diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..0d57a91d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +Dockerfile +Dockerfile.* +docker-compose.yaml diff --git a/.github/workflows/docker-build-deprecated.yaml b/.github/workflows/docker-build-deprecated.yaml index 42ef986f..02943482 100644 --- a/.github/workflows/docker-build-deprecated.yaml +++ b/.github/workflows/docker-build-deprecated.yaml @@ -45,4 +45,4 @@ jobs: labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - file: Dockerfile.deprecated + file: Dockerfile diff --git a/.github/workflows/interchaintest.yaml b/.github/workflows/interchaintest.yaml index 9d9fe688..cbb03ab2 100644 --- a/.github/workflows/interchaintest.yaml +++ b/.github/workflows/interchaintest.yaml @@ -90,20 +90,6 @@ jobs: - name: Load current image run: docker load --input archway_local - - name: Get last release tag - id: lastrelease - uses: WyriHaximus/github-action-get-previous-tag@v1 - with: - prefix: 'v' - - - name: Download ${{ steps.lastrelease.outputs.tag }} image - uses: actions/download-artifact@v3 - with: - name: action_image_artifact_archway_${{ steps.lastrelease.outputs.tag }} - - - name: Load ${{ steps.lastrelease.outputs.tag }} image - run: docker load --input archway_${{ steps.lastrelease.outputs.tag }} - - name: Run chain upgrade test run: | cd interchaintest @@ -140,7 +126,7 @@ jobs: - name: Run chain conformance test run: | cd interchaintest - go test -v -race -run TestGaiaConformance + go test -v -race -run TestGaiaConformance cwica_tests: name: Interchain transactions test @@ -173,4 +159,4 @@ jobs: - name: Run interchain transactions test run: | cd interchaintest - go test -v -race -run TestCWICA \ No newline at end of file + go test -v -race -run TestCWICA \ No newline at end of file diff --git a/.gitignore b/.gitignore index a49ca25c..9291d763 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ build/ dist/ data/ + +.envrc diff --git a/Dockerfile b/Dockerfile index 45462334..7eb81d4d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,54 @@ -FROM scratch +FROM golang:1.23.1-alpine3.19 AS builder -COPY ./archwayd /usr/bin/archwayd +WORKDIR /code -WORKDIR /root/.archway +RUN apk add \ + make \ + # used by make + git \ + # to install GCC + build-base + +# ARG arch=x86_64 +# ARG libwasmvm_sha=0421ad81247a46bbad6899c49d5081a5a080621ab9432e710152d85ba66c94bc +ARG arch=aarch64 +ARG libwasmvm_sha=9429e9ab18f0b2519d9e3344b13fbb3ea339b7f1deedfaa2abc71522d190eaef +ARG libwasmvm_version=v1.5.5 + +# used to to link wasm +# ADD https://github.com/CosmWasm/wasmvm/releases/download/${libwasmvm_version}/libwasmvm_muslc.${arch}.a /lib/libwasmvm_muslc.a +RUN wget -O /lib/libwasmvm_muslc.a https://github.com/CosmWasm/wasmvm/releases/download/${libwasmvm_version}/libwasmvm_muslc.${arch}.a +RUN sha256sum /lib/libwasmvm_muslc.a > /lib/libwasmvm_checksum +RUN if ! grep -q "${libwasmvm_sha} " /lib/libwasmvm_checksum ; then \ + echo "Expected libwasmvm signature: ${libwasmvm_sha}" && \ + echo "Actual libwasmvm signature: $(cat /lib/libwasmvm_checksum)" && \ + exit 1; fi + +ARG GOPROXY="" +ENV GOPROXY=${GOPROXY} + +COPY \ + go.sum \ + go.mod \ + ./ +RUN \ + # --mount=type=cache,target=/root/.cache/go \ + GOPROXY=${GOPROXY} \ + go mod download + +COPY . . +# wasm keeper is not implemented for builds without CGO - https://github.com/CosmWasm/wasmd/blob/88cba83a664ead2e99074cc841422809df85a3b4/x/wasm/keeper/keeper_no_cgo.go#L35 +# thus we use cgo implementation and have to build with cgo enabled + +RUN \ + # --mount=type=cache,target=/root/.cache/go-build \ + # --mount=type=cache,target=/go/pkg \ + CGO_ENABLED=1 LEDGER_ENABLED=false BUILD_TAGS=muslc LINK_STATICALLY=true make build + +# -------------------------------------------------------- +FROM alpine:3.17 + +COPY --from=builder /code/build/archwayd /usr/bin/archwayd # rest server EXPOSE 1317 diff --git a/Dockerfile.deprecated b/Dockerfile.deprecated deleted file mode 100644 index d70415d7..00000000 --- a/Dockerfile.deprecated +++ /dev/null @@ -1,53 +0,0 @@ -FROM golang:1.21.10-alpine3.19 AS go-builder -# arch can be either x86_64 for amd64 or aarch64 for arm -ARG arch=x86_64 -ARG libwasmvm_version=v1.5.2 -ARG libwasmvm_aarch64_sha=e78b224c15964817a3b75a40e59882b4d0e06fd055b39514d61646689cef8c6e -ARG libwasmvm_amd64_sha=e660a38efb2930b34ee6f6b0bb12730adccb040b6ab701b8f82f34453a426ae7 - -# this comes from standard alpine nightly file -# https://github.com/rust-lang/docker-rust-nightly/blob/master/alpine3.12/Dockerfile -# with some changes to support our toolchain, etc -RUN set -eux; apk add --no-cache ca-certificates build-base; - -RUN apk add git -# NOTE: add these to run with LEDGER_ENABLED=true -# RUN apk add libusb-dev linux-headers - -WORKDIR /code -COPY . /code/ - -# See https://github.com/CosmWasm/wasmvm/releases -ADD https://github.com/CosmWasm/wasmvm/releases/download/$libwasmvm_version/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a -ADD https://github.com/CosmWasm/wasmvm/releases/download/$libwasmvm_version/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a -RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep $libwasmvm_aarch64_sha -RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep $libwasmvm_amd64_sha - -# Copy the library you want to the final location that will be found by the linker flag `-lwasmvm_muslc` -RUN cp /lib/libwasmvm_muslc.${arch}.a /lib/libwasmvm_muslc.a - -# force it to use static lib (from above) not standard libgo_cosmwasm.so file -RUN LEDGER_ENABLED=false BUILD_TAGS=muslc LINK_STATICALLY=true make build -RUN echo "Ensuring binary is statically linked ..." \ - && (file /code/build/archwayd | grep "statically linked") - -# -------------------------------------------------------- -FROM alpine:3.17 - -COPY --from=go-builder /code/build/archwayd /usr/bin/archwayd - -WORKDIR /root/.archway - -# safety check to ensure deps are correct -RUN archwayd ensure-binary - -# rest server -EXPOSE 1317 -# comet p2p -EXPOSE 26656 -# comet rpc -EXPOSE 26657 - -ENTRYPOINT [ "/usr/bin/archwayd" ] - -CMD [ "help" ] diff --git a/Dockerfile.dev b/Dockerfile.dev index f783c61a..fdf217d1 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,8 +1,6 @@ -FROM alpine:3.18 +FROM alpine:3.17 -COPY ./archwayd /usr/bin/archwayd - -WORKDIR /root/.archway +COPY ./build/archwayd /usr/bin/archwayd # Install dev packages RUN apk add --no-cache bash jq diff --git a/Makefile b/Makefile index d1a5158b..5bb80b4e 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ ifeq ($(WITH_CLEVELDB),yes) ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb endif ifeq ($(LINK_STATICALLY),true) - ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static" + ldflags += -linkmode=external -extldflags "-static" endif ldflags += $(LDFLAGS) ldflags := $(strip $(ldflags)) diff --git a/app/app.go b/app/app.go index 3418126e..eee6c103 100644 --- a/app/app.go +++ b/app/app.go @@ -127,6 +127,7 @@ import ( ibccm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/spf13/cast" + "github.com/archway-network/archway/app/appconst" "github.com/archway-network/archway/app/keepers" "github.com/archway-network/archway/x/cwfees" "github.com/archway-network/archway/x/genmsg" @@ -154,43 +155,19 @@ import ( cwicakeeper "github.com/archway-network/archway/x/cwica/keeper" cwicatypes "github.com/archway-network/archway/x/cwica/types" + oracle "github.com/archway-network/archway/x/oracle" + oraclekeeper "github.com/archway-network/archway/x/oracle/keeper" + oracletypes "github.com/archway-network/archway/x/oracle/types" + extendedGov "github.com/archway-network/archway/x/gov" "github.com/CosmWasm/wasmd/x/wasm" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" archwayappparams "github.com/archway-network/archway/app/params" archway "github.com/archway-network/archway/types" ) -const appName = "Archway" - -// We pull these out so we can set them with LDFLAGS in the Makefile -var ( - NodeDir = ".archway" - Bech32Prefix = "archway" -) - -// These constants are derived from the above variables. -// These are the ones we will want to use in the code, based on -// any overrides above -var ( - // DefaultNodeHome default home directories for archwayd - DefaultNodeHome = os.ExpandEnv("$HOME/") + NodeDir - - // Bech32PrefixAccAddr defines the Bech32 prefix of an account's address - Bech32PrefixAccAddr = Bech32Prefix - // Bech32PrefixAccPub defines the Bech32 prefix of an account's public key - Bech32PrefixAccPub = Bech32Prefix + sdk.PrefixPublic - // Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address - Bech32PrefixValAddr = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixOperator - // Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key - Bech32PrefixValPub = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixOperator + sdk.PrefixPublic - // Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address - Bech32PrefixConsAddr = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixConsensus - // Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key - Bech32PrefixConsPub = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixConsensus + sdk.PrefixPublic -) - var ( // ModuleBasics defines the module BasicManager is in charge of setting up basic, // non-dependant module elements, such as codec registration @@ -229,6 +206,7 @@ var ( cwfees.AppModule{}, cwica.AppModuleBasic{}, cwerrors.AppModuleBasic{}, + oracle.AppModuleBasic{}, ) // module account permissions @@ -247,6 +225,7 @@ var ( wasmdTypes.ModuleName: {authtypes.Burner}, rewardsTypes.TreasuryCollector: {authtypes.Burner}, callbackTypes.ModuleName: nil, + oracletypes.ModuleName: nil, } ) @@ -255,6 +234,15 @@ var ( _ servertypes.Application = (*ArchwayApp)(nil) ) +func SetPrefixes() { + cfg := sdk.GetConfig() + cfg.SetBech32PrefixForAccount(appconst.Bech32PrefixAccAddr, appconst.Bech32PrefixAccPub) + cfg.SetBech32PrefixForValidator(appconst.Bech32PrefixValAddr, appconst.Bech32PrefixValPub) + cfg.SetBech32PrefixForConsensusNode(appconst.Bech32PrefixConsAddr, appconst.Bech32PrefixConsPub) + cfg.SetAddressVerifier(wasmtypes.VerifyAddressLen()) + cfg.Seal() +} + func init() { // sets the default power reduction in order to ensure that on high precision numbers, which is a default for archway // the network does not get stalled due to an integer overflow in some edge cases. @@ -317,7 +305,7 @@ func NewArchwayApp( std.RegisterLegacyAminoCodec(legacyAmino) std.RegisterInterfaces(interfaceRegistry) - bApp := baseapp.NewBaseApp(appName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) + bApp := baseapp.NewBaseApp(appconst.AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) @@ -335,6 +323,7 @@ func NewArchwayApp( icacontrollertypes.StoreKey, icahosttypes.StoreKey, ibcfeetypes.StoreKey, crisistypes.StoreKey, group.StoreKey, nftkeeper.StoreKey, cwicatypes.StoreKey, trackingTypes.StoreKey, rewardsTypes.StoreKey, callbackTypes.StoreKey, cwfees.ModuleName, cwerrorsTypes.StoreKey, + oracletypes.StoreKey, ) tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey, cwerrorsTypes.TStoreKey) memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -672,8 +661,19 @@ func NewArchwayApp( logger, ) + app.Keepers.OracleKeeper = oraclekeeper.NewKeeper( + appCodec, + keys[oracletypes.StoreKey], + app.Keepers.AccountKeeper, + app.Keepers.BankKeeper, + app.Keepers.DistrKeeper, + app.Keepers.StakingKeeper, + app.Keepers.SlashingKeeper, + distrtypes.ModuleName, + ) + app.Keepers.IBCHooksKeeper = ibchookskeeper.NewKeeper(keys[ibchookstypes.StoreKey]) - ics20WasmHooks := ibchooks.NewWasmHooks(&app.Keepers.IBCHooksKeeper, nil, Bech32Prefix) + ics20WasmHooks := ibchooks.NewWasmHooks(&app.Keepers.IBCHooksKeeper, nil, appconst.Bech32Prefix) hooksIcs4Wrapper := ibchooks.NewICS4Middleware(app.Keepers.IBCKeeper.ChannelKeeper, ics20WasmHooks) var transferStack porttypes.IBCModule @@ -759,6 +759,7 @@ func NewArchwayApp( cwica.NewAppModule(appCodec, app.Keepers.CWICAKeeper, app.Keepers.AccountKeeper), cwerrors.NewAppModule(app.appCodec, app.Keepers.CWErrorsKeeper, app.Keepers.WASMKeeper), crisis.NewAppModule(&app.Keepers.CrisisKeeper, skipGenesisInvariants, app.getSubspace(crisistypes.ModuleName)), // always be last to make sure that it checks for all invariants and not only part of them + oracle.NewAppModule(appCodec, app.Keepers.OracleKeeper, app.Keepers.AccountKeeper, app.Keepers.BankKeeper), ) // BasicModuleManager defines the module BasicManager is in charge of setting up basic, @@ -801,6 +802,7 @@ func NewArchwayApp( paramstypes.ModuleName, vestingtypes.ModuleName, consensusparamtypes.ModuleName, + oracletypes.ModuleName, // additional non simd modules ibcexported.ModuleName, ibctransfertypes.ModuleName, @@ -836,6 +838,7 @@ func NewArchwayApp( upgradetypes.ModuleName, vestingtypes.ModuleName, consensusparamtypes.ModuleName, + oracletypes.ModuleName, // wasm ibchookstypes.ModuleName, wasmdTypes.ModuleName, @@ -876,6 +879,7 @@ func NewArchwayApp( upgradetypes.ModuleName, vestingtypes.ModuleName, consensusparamtypes.ModuleName, + oracletypes.ModuleName, // additional non simd modules ibcexported.ModuleName, ibctransfertypes.ModuleName, @@ -1219,5 +1223,17 @@ func getAcceptedStargateQueries() wasmdKeeper.AcceptedStargateQueries { "/archway.cwerrors.v1.Query/Errors": &cwerrorsTypes.QueryErrorsRequest{}, "/archway.callback.v1.Query/EstimateCallbackFees": &callbackTypes.QueryEstimateCallbackFeesRequest{}, "/archway.callback.v1.Query/Params": &callbackTypes.QueryParamsRequest{}, + "/archway.oracle.v1.Query/ExchangeRate": new(oracletypes.QueryExchangeRateResponse), + "/archway.oracle.v1.Query/ExchangeRateTwap": new(oracletypes.QueryExchangeRateResponse), + "/archway.oracle.v1.Query/ExchangeRates": new(oracletypes.QueryExchangeRatesResponse), + "/archway.oracle.v1.Query/Actives": new(oracletypes.QueryActivesResponse), + "/archway.oracle.v1.Query/VoteTargets": new(oracletypes.QueryVoteTargetsResponse), + "/archway.oracle.v1.Query/FeederDelegation": new(oracletypes.QueryFeederDelegationResponse), + "/archway.oracle.v1.Query/MissCounter": new(oracletypes.QueryMissCounterResponse), + "/archway.oracle.v1.Query/AggregatePrevote": new(oracletypes.QueryAggregatePrevoteResponse), + "/archway.oracle.v1.Query/AggregatePrevotes": new(oracletypes.QueryAggregatePrevotesResponse), + "/archway.oracle.v1.Query/AggregateVote": new(oracletypes.QueryAggregateVoteResponse), + "/archway.oracle.v1.Query/AggregateVotes": new(oracletypes.QueryAggregateVotesResponse), + "/archway.oracle.v1.Query/Params": new(oracletypes.QueryParamsResponse), } } diff --git a/app/app_test.go b/app/app_test.go index fe7eabc7..9390c1f3 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -9,6 +9,8 @@ import ( tmdb "github.com/cosmos/cosmos-db" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + "github.com/archway-network/archway/app/appconst" ) // import ( @@ -87,7 +89,7 @@ var emptyWasmOpts []wasmkeeper.Option = nil // ensure that blocked addresses are properly set in bank keeper func TestBlockedAddrs(t *testing.T) { db := tmdb.NewMemDB() - gapp := NewArchwayApp(log.NewTestLogger(t), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, MakeEncodingConfig(), EmptyBaseAppOptions{}, emptyWasmOpts) + gapp := NewArchwayApp(log.NewTestLogger(t), db, nil, true, map[int64]bool{}, appconst.DefaultNodeHome, 0, MakeEncodingConfig(), EmptyBaseAppOptions{}, emptyWasmOpts) for acc := range BlockedAddresses() { var addr sdk.AccAddress diff --git a/app/appconst/appconst.go b/app/appconst/appconst.go new file mode 100644 index 00000000..6ddb2261 --- /dev/null +++ b/app/appconst/appconst.go @@ -0,0 +1,36 @@ +package appconst + +import ( + "os" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const AppName = "Archway" + +// We pull these out so we can set them with LDFLAGS in the Makefile +var ( + NodeDir = ".archway" + Bech32Prefix = "archway" +) + +// These constants are derived from the above variables. +// These are the ones we will want to use in the code, based on +// any overrides above +var ( + // DefaultNodeHome default home directories for archwayd + DefaultNodeHome = os.ExpandEnv("$HOME/") + NodeDir + + // Bech32PrefixAccAddr defines the Bech32 prefix of an account's address + Bech32PrefixAccAddr = Bech32Prefix + // Bech32PrefixAccPub defines the Bech32 prefix of an account's public key + Bech32PrefixAccPub = Bech32Prefix + sdk.PrefixPublic + // Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address + Bech32PrefixValAddr = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixOperator + // Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key + Bech32PrefixValPub = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixOperator + sdk.PrefixPublic + // Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address + Bech32PrefixConsAddr = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixConsensus + // Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key + Bech32PrefixConsPub = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixConsensus + sdk.PrefixPublic +) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 02b8de2f..0e479bcf 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -32,6 +32,7 @@ import ( callbackKeeper "github.com/archway-network/archway/x/callback/keeper" cwerrorsKeeper "github.com/archway-network/archway/x/cwerrors/keeper" cwicaKeeper "github.com/archway-network/archway/x/cwica/keeper" + oracleKeeper "github.com/archway-network/archway/x/oracle/keeper" rewardsKeeper "github.com/archway-network/archway/x/rewards/keeper" trackingKeeper "github.com/archway-network/archway/x/tracking/keeper" ) @@ -69,4 +70,5 @@ type ArchwayKeepers struct { CallbackKeeper callbackKeeper.Keeper CWErrorsKeeper cwerrorsKeeper.Keeper CWICAKeeper cwicaKeeper.Keeper + OracleKeeper oracleKeeper.Keeper } diff --git a/app/swagger.go b/app/swagger.go index 7214e2a2..fe6b53d7 100644 --- a/app/swagger.go +++ b/app/swagger.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/server/api" + "github.com/archway-network/archway/app/appconst" "github.com/archway-network/archway/docs" "github.com/archway-network/archway/pkg/openapiconsole" ) @@ -13,6 +14,6 @@ import ( func RegisterSwaggerAPI(apiSvr *api.Server) error { // register app's OpenAPI routes. apiSvr.Router.Handle("/static/swagger.min.json", http.FileServer(http.FS(docs.Docs))) - apiSvr.Router.HandleFunc("/", openapiconsole.Handler(appName+" Swagger UI", "/static/swagger.min.json")) + apiSvr.Router.HandleFunc("/", openapiconsole.Handler(appconst.AppName+" Swagger UI", "/static/swagger.min.json")) return nil } diff --git a/cmd/archwayd/main.go b/cmd/archwayd/main.go index 37e1a5a8..022fa184 100644 --- a/cmd/archwayd/main.go +++ b/cmd/archwayd/main.go @@ -10,7 +10,7 @@ import ( svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - "github.com/archway-network/archway/app" + "github.com/archway-network/archway/app/appconst" ) const ArchwayASCII = ` @@ -29,7 +29,7 @@ func main() { rootCmd.AddCommand(ensureLibWasmVM()) - if err := svrcmd.Execute(rootCmd, "ARCHWAY", app.DefaultNodeHome); err != nil { + if err := svrcmd.Execute(rootCmd, "ARCHWAY", appconst.DefaultNodeHome); err != nil { _, _ = fmt.Fprintln(rootCmd.OutOrStderr(), err) os.Exit(1) } diff --git a/cmd/archwayd/root.go b/cmd/archwayd/root.go index ea4feca6..c98bc3ae 100644 --- a/cmd/archwayd/root.go +++ b/cmd/archwayd/root.go @@ -17,7 +17,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -32,21 +31,16 @@ import ( "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/archway-network/archway/app" + "github.com/archway-network/archway/app/appconst" "github.com/archway-network/archway/app/params" ) // NewRootCmd creates a new root command for archwayd. It is called once in the // main function. func NewRootCmd() (*cobra.Command, params.EncodingConfig) { - cfg := sdk.GetConfig() - cfg.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub) - cfg.SetBech32PrefixForValidator(app.Bech32PrefixValAddr, app.Bech32PrefixValPub) - cfg.SetBech32PrefixForConsensusNode(app.Bech32PrefixConsAddr, app.Bech32PrefixConsPub) - cfg.SetAddressVerifier(wasmtypes.VerifyAddressLen()) - cfg.Seal() + app.SetPrefixes() encodingConfig := app.MakeEncodingConfig() tempApp := app.NewArchwayApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, nil, tempDir(), 0, encodingConfig, simtestutil.NewAppOptionsWithFlagHome(tempDir()), []wasmkeeper.Option{}) @@ -58,7 +52,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { WithLegacyAmino(encodingConfig.Amino). WithInput(os.Stdin). WithAccountRetriever(authtypes.AccountRetriever{}). - WithHomeDir(app.DefaultNodeHome). + WithHomeDir(appconst.DefaultNodeHome). WithViper("") rootCmd := &cobra.Command{ @@ -121,7 +115,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { rootCmd.AddCommand( - genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome), + genutilcli.InitCmd(app.ModuleBasics, appconst.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), // testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), debug.Cmd(), @@ -131,7 +125,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { ac := appCreator{ encCfg: encodingConfig, } - server.AddCommands(rootCmd, app.DefaultNodeHome, ac.newApp, ac.appExport, addModuleInitFlags) + server.AddCommands(rootCmd, appconst.DefaultNodeHome, ac.newApp, ac.appExport, addModuleInitFlags) // add keybase, auxiliary RPC, query, and tx child commands rootCmd.AddCommand( @@ -199,7 +193,7 @@ func txCommand() *cobra.Command { } func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { - cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, app.ModuleBasics, app.DefaultNodeHome) + cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, app.ModuleBasics, appconst.DefaultNodeHome) for _, sub_cmd := range cmds { cmd.AddCommand(sub_cmd) diff --git a/e2e/ibchooks/ibchooks_test.go b/e2e/ibchooks/ibchooks_test.go index a28cb296..e01bfb04 100644 --- a/e2e/ibchooks/ibchooks_test.go +++ b/e2e/ibchooks/ibchooks_test.go @@ -7,12 +7,13 @@ import ( "testing" wasmKeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - "github.com/archway-network/archway/app" ibc_hooks "github.com/cosmos/ibc-apps/modules/ibc-hooks/v8" ibchookskeeper "github.com/cosmos/ibc-apps/modules/ibc-hooks/v8/keeper" "github.com/cosmos/ibc-apps/modules/ibc-hooks/v8/tests/unit/mocks" "github.com/stretchr/testify/suite" + "github.com/archway-network/archway/app" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" diff --git a/e2e/ibchooks/setup.go b/e2e/ibchooks/setup.go index 207641dc..550faaea 100644 --- a/e2e/ibchooks/setup.go +++ b/e2e/ibchooks/setup.go @@ -9,7 +9,6 @@ import ( "cosmossdk.io/log" sdkmath "cosmossdk.io/math" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - "github.com/archway-network/archway/app" abci "github.com/cometbft/cometbft/abci/types" cmttypes "github.com/cometbft/cometbft/types" dbm "github.com/cosmos/cosmos-db" @@ -28,6 +27,9 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/ibc-go/v8/testing/mock" "github.com/stretchr/testify/require" + + "github.com/archway-network/archway/app" + "github.com/archway-network/archway/app/appconst" ) type App = app.ArchwayApp @@ -108,7 +110,7 @@ func SetupWithGenesisValSet( // initSetup initializes a new SimApp. A Nop logger is set in SimApp. func setup(t *testing.T, chainID string, withGenesis bool, invCheckPeriod uint) (*app.ArchwayApp, map[string]json.RawMessage) { appOptions := make(simtestutil.AppOptionsMap) - appOptions[flags.FlagHome] = app.DefaultNodeHome + appOptions[flags.FlagHome] = appconst.DefaultNodeHome appOptions[server.FlagInvCheckPeriod] = invCheckPeriod archApp := app.NewArchwayApp( @@ -116,7 +118,7 @@ func setup(t *testing.T, chainID string, withGenesis bool, invCheckPeriod uint) dbm.NewMemDB(), nil, true, map[int64]bool{}, - app.DefaultNodeHome, + appconst.DefaultNodeHome, 1, app.MakeEncodingConfig(), app.EmptyBaseAppOptions{}, @@ -173,7 +175,6 @@ func GenesisStateWithValSet( } validators = append(validators, validator) delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress().String(), sdk.ValAddress(val.Address).String(), sdkmath.LegacyOneDec())) - } // set validators and delegations diff --git a/e2e/testing/chain.go b/e2e/testing/chain.go index d7e2ee8b..462668ca 100644 --- a/e2e/testing/chain.go +++ b/e2e/testing/chain.go @@ -38,6 +38,7 @@ import ( "github.com/stretchr/testify/require" "github.com/archway-network/archway/app" + "github.com/archway-network/archway/app/appconst" ) var TestAccountAddr = sdk.AccAddress("test") @@ -99,8 +100,9 @@ func NewTestChain(t *testing.T, chainIdx int, opts ...interface{}) *TestChain { logger, dbm.NewMemDB(), nil, - true, map[int64]bool{}, - app.DefaultNodeHome, + true, + map[int64]bool{}, + appconst.DefaultNodeHome, 1, encCfg, app.EmptyBaseAppOptions{}, diff --git a/e2e/testing/client.go b/e2e/testing/client.go index e7b2e9d6..788f7552 100644 --- a/e2e/testing/client.go +++ b/e2e/testing/client.go @@ -8,6 +8,16 @@ import ( proto "github.com/cosmos/gogoproto/proto" "google.golang.org/grpc" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/types/module" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" + + "github.com/spf13/viper" + "github.com/stretchr/testify/require" + "github.com/archway-network/archway/app" ) @@ -30,7 +40,7 @@ func (c grpcClient) Invoke(ctx context.Context, method string, args, reply inter } if resp.Code != abci.CodeTypeOK { - return fmt.Errorf(resp.Log) + return fmt.Errorf("%s", resp.Log) } c.app.AppCodec().MustUnmarshal(resp.Value, reply.(proto.Message)) @@ -45,3 +55,26 @@ func (c grpcClient) NewStream(ctx context.Context, desc *grpc.StreamDesc, method func (chain *TestChain) Client() grpc.ClientConnInterface { return grpcClient{app: chain.app} } + +// SetupClientCtx configures the client and server contexts and returns the +// resultant 'context.Context'. This is useful for executing CLI commands. +func (chain *TestChain) SetupClientCtx() context.Context { + home := chain.t.TempDir() + logger := chain.app.Logger() + cfg, err := genutiltest.CreateDefaultCometConfig(home) + require.NoError(chain.t, err) + + appCodec := moduletestutil.MakeTestEncodingConfig().Codec + testModuleBasicManager := module.NewBasicManager(genutil.AppModuleBasic{}) + err = genutiltest.ExecInitCmd( + testModuleBasicManager, home, appCodec) + require.NoError(chain.t, err) + + serverCtx := server.NewContext(viper.New(), cfg, logger) + clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home) + + ctx := context.Background() + ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) + ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) + return ctx +} diff --git a/go.mod b/go.mod index 79d4c744..9f75950b 100644 --- a/go.mod +++ b/go.mod @@ -33,18 +33,22 @@ require ( github.com/dvsekhvalnov/jose2go v1.6.0 github.com/gogo/protobuf v1.3.2 github.com/golang/protobuf v1.5.4 + github.com/google/gofuzz v1.2.0 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.20.1 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa github.com/spf13/cast v1.6.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 google.golang.org/grpc v1.64.1 google.golang.org/protobuf v1.34.2 + gopkg.in/yaml.v2 v2.4.0 ) require ( @@ -113,7 +117,6 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect @@ -163,7 +166,6 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // 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_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect @@ -177,7 +179,6 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/viper v1.19.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect @@ -205,7 +206,6 @@ require ( google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // 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.7 // indirect diff --git a/interchaintest/cwica_test.go b/interchaintest/cwica_test.go index d2b19234..6a95785c 100644 --- a/interchaintest/cwica_test.go +++ b/interchaintest/cwica_test.go @@ -34,7 +34,7 @@ func TestCWICA(t *testing.T) { junoChainSpec := &interchaintest.ChainSpec{ Name: "juno", ChainName: "juno", - Version: "v20.0.0", + Version: "v25.0.0", NumValidators: &numOfVals, ChainConfig: ibc.ChainConfig{ GasAdjustment: 2, @@ -62,20 +62,28 @@ func TestCWICA(t *testing.T) { ibc.CosmosRly, zaptest.NewLogger(t), relayer.StartupFlags("-b", "100", "-p", "events"), + // relayer.ImagePull(false), + relayer.DockerImage(&ibc.DockerImage{ + Repository: "ghcr.io/cosmos/relayer", + Version: "justin-CoC", // sha256:a7f03cc955c1bd8d1436bee29eaf5c1e44298e17d1dfb3fecb1be912f206819b + }), ) client, network := interchaintest.DockerSetup(t) relayer := relayerFactory.Build(t, client, network) // Create the IBC network with the chains and relayer + ibcChannelOpts := ibc.DefaultChannelOpts() + ibcChannelOpts.Order = ibc.Ordered ic := interchaintest.NewInterchain(). AddChain(archwayChain). AddChain(counterpartyChain). AddRelayer(relayer, relayerName). AddLink(interchaintest.InterchainLink{ - Chain1: archwayChain, - Chain2: counterpartyChain, - Relayer: relayer, - Path: path, + Chain1: archwayChain, + Chain2: counterpartyChain, + Relayer: relayer, + Path: path, + CreateChannelOpts: ibcChannelOpts, }) ir := cosmos.DefaultEncoding().InterfaceRegistry rep := testreporter.NewNopReporter() @@ -257,6 +265,7 @@ func TestCWICA(t *testing.T) { require.NoError(t, err) for _, channel := range channels { if channel.Counterparty.PortID == "icahost" { + // TODO: ORDER_UNORDERED channels are not closed on msg timeout require.Equal(t, "STATE_CLOSED", channel.State) } } diff --git a/interchaintest/go.mod b/interchaintest/go.mod index e7852834..40bfe965 100644 --- a/interchaintest/go.mod +++ b/interchaintest/go.mod @@ -1,49 +1,48 @@ module github.com/archway-network/archway/interchaintest -go 1.22.2 +go 1.22.5 -toolchain go1.22.3 +toolchain go1.23.1 replace ( github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0 - // github.com/strangelove-ventures/interchaintest/v7 => github.com/archway-network/interchaintest/v7 v7.0.0-20231003055643-aeec9350d067 - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + // github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + github.com/gogo/protobuf v1.3.3 => github.com/gogo/protobuf v1.3.2 github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) require ( cosmossdk.io/math v1.3.0 - cosmossdk.io/x/upgrade v0.1.2 - github.com/cosmos/cosmos-sdk v0.50.6 - github.com/cosmos/ibc-go/v8 v8.2.1 + cosmossdk.io/x/upgrade v0.1.4 + github.com/cosmos/cosmos-sdk v0.50.10 + github.com/cosmos/ibc-go/v8 v8.4.0 github.com/docker/docker v24.0.9+incompatible - github.com/strangelove-ventures/interchaintest/v8 v8.4.0 + github.com/strangelove-ventures/interchaintest/v8 v8.7.1 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - 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 v0.112.1 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/iam v1.1.6 // indirect - cloud.google.com/go/storage v1.37.0 // indirect - cosmossdk.io/api v0.7.4 // indirect + cloud.google.com/go/storage v1.38.0 // indirect + cosmossdk.io/api v0.7.5 // 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/core v0.11.1 // indirect + cosmossdk.io/depinject v1.0.0 // indirect cosmossdk.io/errors v1.0.1 // indirect - cosmossdk.io/log v1.3.1 // indirect - cosmossdk.io/store v1.1.0 // indirect + cosmossdk.io/log v1.4.1 // indirect + cosmossdk.io/store v1.1.1 // indirect cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/feegrant v0.1.0 // indirect - cosmossdk.io/x/tx v0.13.2 // indirect + cosmossdk.io/x/tx v0.13.5 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect - github.com/BurntSushi/toml v1.3.2 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/ChainSafe/go-schnorrkel/1 v0.0.0-00010101000000-000000000000 // indirect github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 // indirect @@ -51,7 +50,8 @@ require ( github.com/DataDog/zstd v1.5.5 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect github.com/StirlingMarketingGroup/go-namecase v1.0.0 // indirect github.com/avast/retry-go/v4 v4.5.1 // indirect github.com/aws/aws-sdk-go v1.44.224 // indirect @@ -59,48 +59,52 @@ 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/bits-and-blooms/bitset v1.10.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect - github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/cockroachdb/errors v1.11.1 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v1.1.0 // indirect + github.com/cockroachdb/pebble v1.1.1 // 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.7 // indirect - github.com/cometbft/cometbft-db v0.10.0 // indirect + github.com/cometbft/cometbft v0.38.12 // indirect + github.com/cometbft/cometbft-db v0.14.0 // 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/cosmos-db v1.0.2 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.4.12 // indirect - github.com/cosmos/iavl v1.1.2 // indirect - github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect - github.com/cosmos/ics23/go v0.10.0 // indirect - github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74 // indirect + github.com/cosmos/gogoproto v1.7.0 // indirect + github.com/cosmos/iavl v1.2.0 // indirect + github.com/cosmos/ibc-go/modules/capability v1.0.1 // indirect + github.com/cosmos/ics23/go v0.11.0 // indirect + github.com/cosmos/interchain-security/v5 v5.1.1 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // 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 v1.8.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/base58 v1.0.4 // indirect github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v2 v2.2007.4 // indirect + github.com/dgraph-io/badger/v4 v4.2.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect - github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-connections v0.5.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.1 // indirect - github.com/ethereum/go-ethereum v1.14.0 // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-ethereum v1.14.8 // 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.27.0 // indirect @@ -109,24 +113,26 @@ 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/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect - github.com/golang/glog v1.2.0 // indirect + github.com/golang/glog v1.2.1 // 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.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect + github.com/google/flatbuffers v1.12.1 // 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.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/googleapis/gax-go/v2 v2.12.3 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect @@ -139,13 +145,13 @@ require ( github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect - github.com/holiman/uint256 v1.2.4 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 // indirect @@ -154,7 +160,7 @@ require ( github.com/ipfs/go-cid v0.4.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -169,10 +175,11 @@ require ( github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect - github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2 // indirect + github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20240603204351-26b456ae3afe // 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/mr-tron/base58 v1.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -182,6 +189,7 @@ require ( github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect @@ -193,73 +201,80 @@ require ( github.com/pierrec/xxHash v0.1.5 // 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.19.0 // indirect + github.com/prometheus/client_golang v1.20.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.52.2 // indirect - github.com/prometheus/procfs v0.13.0 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // 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 + github.com/rs/cors v1.11.1 // indirect + github.com/rs/zerolog v1.33.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 + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 // indirect + github.com/spf13/viper v1.19.0 // 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/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.7.0 // indirect + github.com/tidwall/gjson v1.17.1 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/tyler-smith/go-bip32 v1.0.0 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect - go.etcd.io/bbolt v1.3.8 // indirect + go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/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.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.22.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sync v0.7.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/mod v0.19.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.20.0 // indirect - google.golang.org/api v0.162.0 // indirect - google.golang.org/appengine v1.6.8 // indirect + golang.org/x/tools v0.23.0 // indirect + google.golang.org/api v0.171.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect - google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect - modernc.org/libc v1.49.3 // indirect + modernc.org/libc v1.55.3 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect - modernc.org/sqlite v1.29.9 // indirect + modernc.org/sqlite v1.31.1 // indirect modernc.org/strutil v1.2.0 // indirect modernc.org/token v1.1.0 // indirect nhooyr.io/websocket v1.8.7 // 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/interchaintest/go.sum b/interchaintest/go.sum index c1aa2798..807d247e 100644 --- a/interchaintest/go.sum +++ b/interchaintest/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.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= -cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= 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,10 +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.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/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= @@ -171,8 +169,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.37.0 h1:WI8CsaFO8Q9KjPVtsZ5Cmi0dXV25zMoX0FklT7c3Jm4= -cloud.google.com/go/storage v1.37.0/go.mod h1:i34TiT2IhiNDmcj65PqwCjcoUX7Z5pLzS8DEmoiFq1k= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= 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,34 +182,34 @@ 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.4 h1:sPo8wKwCty1lht8kgL3J7YL1voJywP3YWuA5JKkBz30= -cosmossdk.io/api v0.7.4/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.7.5 h1:eMPTReoNmGUm8DeiQL9DyM8sYDjEhWzL1+nLbI9DqtQ= +cosmossdk.io/api v0.7.5/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= 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= -cosmossdk.io/core v0.11.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= -cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= -cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/core v0.11.1 h1:h9WfBey7NAiFfIcUhDVNS503I2P2HdZLebJlUIs8LPA= +cosmossdk.io/core v0.11.1/go.mod h1:OJzxcdC+RPrgGF8NJZR2uoQr56tc7gfBKhiKeDO7hH0= +cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= +cosmossdk.io/depinject v1.0.0/go.mod h1:zxK/h3HgHoA/eJVtiSsoaRaRA2D5U4cJ5thIG4ssbB8= 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.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= -cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= +cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk= -cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng= +cosmossdk.io/store v1.1.1 h1:NA3PioJtWDVU7cHHeyvdva5J/ggyLDkyH0hGHl2804Y= +cosmossdk.io/store v1.1.1/go.mod h1:8DwVTz83/2PSI366FERGbWSH7hL6sB7HbYp8bqksNwM= 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/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= -cosmossdk.io/x/tx v0.13.2 h1:Kh90UH30bhnnUdJH+CmWLyaH8IKdY6BBGY3EkdOk82o= -cosmossdk.io/x/tx v0.13.2/go.mod h1:yhPokDCfXVIuAtyp49IFlWB5YAXUgD7Zek+ZHwsHzvU= -cosmossdk.io/x/upgrade v0.1.2 h1:O2FGb0mVSXl7P6BQm9uV3hRVKom1zBLDGhd4G8jysJg= -cosmossdk.io/x/upgrade v0.1.2/go.mod h1:P+e4/ZNd8km7lTAX5hC2pXz/042YDcB7gzKTHuY53nc= +cosmossdk.io/x/tx v0.13.5 h1:FdnU+MdmFWn1pTsbfU0OCf2u6mJ8cqc1H4OMG418MLw= +cosmossdk.io/x/tx v0.13.5/go.mod h1:V6DImnwJMTq5qFjeGWpXNiT/fjgE4HtmclRmTqRVM3w= +cosmossdk.io/x/upgrade v0.1.4 h1:/BWJim24QHoXde8Bc64/2BSEB6W4eTydq0X/2f8+g38= +cosmossdk.io/x/upgrade v0.1.4/go.mod h1:9v0Aj+fs97O+Ztw+tG3/tp5JSlrmT7IcFhAebQHmOPo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -222,8 +220,8 @@ github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTB github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= @@ -240,11 +238,10 @@ github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUq github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 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= @@ -252,6 +249,8 @@ github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDO github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/StirlingMarketingGroup/go-namecase v1.0.0 h1:2CzaNtCzc4iNHirR+5ru9OzGg8rQp860gqLBFqRI02Y= github.com/StirlingMarketingGroup/go-namecase v1.0.0/go.mod h1:ZsoSKcafcAzuBx+sndbxHu/RjDcDTrEdT4UvhniHfio= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= 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= @@ -266,7 +265,6 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= @@ -290,10 +288,10 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2 github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= -github.com/btcsuite/btcd/btcutil v1.1.3/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= +github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= @@ -307,7 +305,6 @@ 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/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= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -337,32 +334,34 @@ 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= github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o= github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= -github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= 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 v1.1.0 h1:pcFh8CdCIt2kmEpK0OIatq67Ln9uGDYY3d5XnE0LJG4= -github.com/cockroachdb/pebble v1.1.0/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= +github.com/cockroachdb/pebble v1.1.1 h1:XnKU22oiCLy2Xn8vp1re67cXg4SAasg/WDt1NtcRFaw= +github.com/cockroachdb/pebble v1.1.1/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= 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.7 h1:ULhIOJ9+LgSy6nLekhq9ae3juX3NnQUMMPyVdhZV6Hk= -github.com/cometbft/cometbft v0.38.7/go.mod h1:HIyf811dFMI73IE0F7RrnY/Fr+d1+HuJAgtkEpQjCMY= -github.com/cometbft/cometbft-db v0.10.0 h1:VMBQh88zXn64jXVvj39tlu/IgsGR84T7ImjS523DCiU= -github.com/cometbft/cometbft-db v0.10.0/go.mod h1:7RR7NRv99j7keWJ5IkE9iZibUTKYdtepXTp7Ra0FxKk= +github.com/cometbft/cometbft v0.38.12 h1:OWsLZN2KcSSFe8bet9xCn07VwhBnavPea3VyPnNq1bg= +github.com/cometbft/cometbft v0.38.12/go.mod h1:GPHp3/pehPqgX1930HmK1BpBLZPxB75v/dZg8Viwy+o= +github.com/cometbft/cometbft-db v0.14.0 h1:dKnK/tQL8BwciH6SgFEuZxwKupMokR4NlwYfJWy7C48= +github.com/cometbft/cometbft-db v0.14.0/go.mod h1:JOXKwjrxS/MW5qJ1xuVpELa8HGBVgHpgI+t8j0L0JEo= +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= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -373,31 +372,35 @@ github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAK github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= -github.com/cosmos/cosmos-sdk v0.50.6 h1:efR3MsvMHX5sxS3be+hOobGk87IzlZbSpsI2x/Vw3hk= -github.com/cosmos/cosmos-sdk v0.50.6/go.mod h1:lVkRY6cdMJ0fG3gp8y4hFrsKZqF4z7y0M2UXFb9Yt40= +github.com/cosmos/cosmos-sdk v0.50.10 h1:zXfeu/z653tWZARr/jESzAEiCUYjgJwwG4ytnYWMoDM= +github.com/cosmos/cosmos-sdk v0.50.10/go.mod h1:6Eesrx3ZE7vxBZWpK++30H+Uc7Q4ahQWCL7JKU/LEdU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= 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.12 h1:vB6Lbe/rtnYGjQuFxkPiPYiCybqFT8QvLipDZP8JpFE= -github.com/cosmos/gogoproto v1.4.12/go.mod h1:LnZob1bXRdUoqMMtwYlcR3wjiElmlC+FkjaZRv1/eLY= -github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= -github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= -github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= -github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= -github.com/cosmos/ibc-go/v8 v8.2.1 h1:MTsnZZjxvGD4Fv5pYyx5UkELafSX0rlPt6IfsE2BpTQ= -github.com/cosmos/ibc-go/v8 v8.2.1/go.mod h1:wj3qx75iC/XNnsMqbPDCIGs0G6Y3E/lo3bdqCyoCy+8= -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/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74 h1:6atU/xizTL10q6EprP7oRuvfgUP2F6puvutnVoE+FRc= -github.com/cosmos/interchain-security/v5 v5.0.0-alpha1.0.20240424193412-7cd900ad2a74/go.mod h1:h/RkwOppo5AJj+1pkQyfjqU1MPdpohD/S6oEeAXpGZY= +github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= +github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= +github.com/cosmos/iavl v1.2.0 h1:kVxTmjTh4k0Dh1VNL046v6BXqKziqMDzxo93oh3kOfM= +github.com/cosmos/iavl v1.2.0/go.mod h1:HidWWLVAtODJqFD6Hbne2Y0q3SdxByJepHUOeoH4LiI= +github.com/cosmos/ibc-go/modules/capability v1.0.1 h1:ibwhrpJ3SftEEZRxCRkH0fQZ9svjthrX2+oXdZvzgGI= +github.com/cosmos/ibc-go/modules/capability v1.0.1/go.mod h1:rquyOV262nGJplkumH+/LeYs04P3eV8oB7ZM4Ygqk4E= +github.com/cosmos/ibc-go/v8 v8.4.0 h1:K2PfX0AZ+1XKZytHGEMuSjQXG/MZshPb83RSTQt2+cE= +github.com/cosmos/ibc-go/v8 v8.4.0/go.mod h1:zh6x1osR0hNvEcFrC/lhGD08sMfQmr9wHVvZ/mRWMCs= +github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= +github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= +github.com/cosmos/interchain-security/v5 v5.1.1 h1:xmRRMeE4xoc+JAZUh0XzXFYWaGBtzFFj5SETuOgnEnY= +github.com/cosmos/interchain-security/v5 v5.1.1/go.mod h1:vmeTcTxFCl1eV0o6xpl/IRT7Basz0szVVGzbppnInMg= 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/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/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= @@ -408,8 +411,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -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/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/base58 v1.0.4 h1:QJC6B0E0rXOPA8U/kw2rP+qiRJsUaE2Er+pYb3siUeA= github.com/decred/base58 v1.0.4/go.mod h1:jJswKPEdvpFpvf7dsDvFZyLT22xZ9lWqEByX38oGd9E= github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU= @@ -423,9 +426,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etly github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= -github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/badger/v4 v4.2.0 h1:kJrlajbXXL9DFTNuhhu9yCx7JJa4qpYWxtE8BzuWsEs= +github.com/dgraph-io/badger/v4 v4.2.0/go.mod h1:qfCqhPoWDFJRx1gp5QwwyGo8xk1lbHUxvK9nK0OGAak= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -463,14 +465,16 @@ 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/ethereum/go-ethereum v1.14.0 h1:xRWC5NlB6g1x7vNy4HDBLuqVNbtLrc7v8S6+Uxim1LU= -github.com/ethereum/go-ethereum v1.14.0/go.mod h1:1STrq471D0BQbCX9He0hUj4bHxX2k6mt5nOQJhDNOJ8= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.8 h1:NgOWvXS+lauK+zFukEvi85UmmsS/OkV0N23UZ1VTIig= +github.com/ethereum/go-ethereum v1.14.8/go.mod h1:TJhyuDq0JDppAkFXgqjwpdlQApywnu/m10kFPxh8vvs= +github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4= +github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0/go.mod h1:D9AJLVXSyZQXJQVk8oh1EwjISE+sJTn2duYIZC0dy3w= 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.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= @@ -484,6 +488,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/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/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= @@ -515,6 +521,7 @@ 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= @@ -542,13 +549,23 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG 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= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.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= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -594,6 +611,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -644,6 +663,7 @@ github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwg 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= @@ -663,8 +683,8 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -676,8 +696,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= @@ -696,6 +716,8 @@ github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIv 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= @@ -724,8 +746,9 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -743,14 +766,20 @@ 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/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +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.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/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= github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= 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= @@ -765,6 +794,8 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +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/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -788,14 +819,15 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +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/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/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.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= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -808,6 +840,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +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= @@ -822,7 +858,6 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= github.com/linxGnu/grocksdb v1.8.14/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= 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= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= @@ -842,6 +877,8 @@ 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.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= @@ -851,8 +888,8 @@ github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2 h1:G/cVeTAbB9S/6FSWWqpFV0v49hiuHLbJPu9hTZ0UR2A= -github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2/go.mod h1:Q5BxOd9FxJqYp4vCiLGVdetecPcWTmUQIu0bRigYosU= +github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20240603204351-26b456ae3afe h1:0fcCSfvBgbagEsEMkZuxgA3Ex7IN9i1Hon0fwgMLpQw= +github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20240603204351-26b456ae3afe/go.mod h1:Q5BxOd9FxJqYp4vCiLGVdetecPcWTmUQIu0bRigYosU= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -866,6 +903,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/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -895,6 +937,8 @@ github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7B github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -919,6 +963,8 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -957,7 +1003,6 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= 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 v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= @@ -988,8 +1033,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.20.1 h1:IMJXHOD6eARkQpxo8KkhgEVFlBNm+nkrFUyGlIu7Na8= +github.com/prometheus/client_golang v1.20.1/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1004,23 +1049,23 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 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.52.2 h1:LW8Vk7BccEdONfrJBDffQGRtpSzi5CQaRZGtboOO2ck= -github.com/prometheus/common v0.52.2/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= -github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= 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/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= -github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 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= @@ -1028,13 +1073,14 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f 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/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/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/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= @@ -1052,8 +1098,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1063,26 +1109,22 @@ github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIK github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= -github.com/strangelove-ventures/interchaintest/v8 v8.4.0 h1:UHLmJfmkFXuJHfSE8qmOuEy4FWZWuRw4G6XZHm9hC6w= -github.com/strangelove-ventures/interchaintest/v8 v8.4.0/go.mod h1:nfPgRi1yjnzi+qF+0Fs9qN9kkS1Fk0oqgpKvqg5a200= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +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/strangelove-ventures/interchaintest/v8 v8.7.1 h1:xzd6YgMQEVpn2v3Qun2bYWTjMZBefMlDIaSF0khyf9o= +github.com/strangelove-ventures/interchaintest/v8 v8.7.1/go.mod h1:6tu+kukThX4u27lZq+W0iJ+pwtkVcG3E2QOveyRoXuQ= 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= @@ -1108,12 +1150,20 @@ 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.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= 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/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 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= @@ -1126,7 +1176,6 @@ github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2n 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= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1134,9 +1183,13 @@ github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 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/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/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= @@ -1148,8 +1201,8 @@ github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWp github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= 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/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 h1:qxen9oVGzDdIRP6ejyAJc760RwW4SnVDiTYTzwnXuxo= +go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5/go.mod h1:eW0HG9/oHQhvRCvb1/pIXW4cOvtDqeQK+XSi3TnwaXY= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1162,18 +1215,18 @@ 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/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= +go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp 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= @@ -1198,7 +1251,6 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1208,8 +1260,8 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPh 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.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/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= @@ -1249,8 +1301,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.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.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= @@ -1310,8 +1362,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.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/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= @@ -1337,8 +1389,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.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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= @@ -1353,8 +1405,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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1363,7 +1415,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1373,10 +1424,10 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -1451,14 +1502,16 @@ 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.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.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.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.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= 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= @@ -1468,18 +1521,19 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1539,8 +1593,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.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= 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= @@ -1600,8 +1654,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.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= -google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= 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= @@ -1610,8 +1664,6 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1634,7 +1686,6 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1721,10 +1772,10 @@ google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= 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-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 h1:SbSDUWW1PAO24TNpLdeheoYPd7kllICcLU52x6eD4kQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= 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= @@ -1766,8 +1817,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.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= 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= @@ -1784,8 +1835,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.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1800,6 +1851,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.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1834,18 +1887,18 @@ launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbc launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk= -modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA= -modernc.org/ccgo/v4 v4.16.0/go.mod h1:dkNyWIjFrVIZ68DTo36vHK+6/ShBn4ysU61So6PIqCI= +modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= +modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= +modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.49.3 h1:j2MRCRdwJI2ls/sGbeSk0t2bypOG/uvPZUsGQFDulqg= -modernc.org/libc v1.49.3/go.mod h1:yMZuGkn7pXbKfoT/M35gFJOAEdSKdxL0q64sF7KqCDo= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -1854,8 +1907,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.29.9 h1:9RhNMklxJs+1596GNuAX+O/6040bvOwacTxuFcRuQow= -modernc.org/sqlite v1.29.9/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA= +modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= +modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= @@ -1868,6 +1921,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/proto/archway/callback/v1/callback.proto b/proto/archway/callback/v1/callback.proto index 513b6fed..ec37b5f4 100644 --- a/proto/archway/callback/v1/callback.proto +++ b/proto/archway/callback/v1/callback.proto @@ -10,42 +10,63 @@ option go_package = "github.com/archway-network/archway/x/callback/types"; // Callback defines the callback structure. message Callback { - // contract_address is the address of the contract which is requesting the callback (bech32 encoded). - string contract_address = 1; - // job_id is an identifier the callback requestor can pass in to identify the callback when it happens. - uint64 job_id = 2; - // callback_height is the height at which the callback is executed. - int64 callback_height = 3; - // fee_split is the breakdown of the fees paid by the contract to reserve the callback - CallbackFeesFeeSplit fee_split = 4; - // reserved_by is the address which reserved the callback (bech32 encoded). - string reserved_by = 5; - // callback_gas_limit is the maximum gas that can be consumed by this callback. - uint64 max_gas_limit = 6; + // contract_address is the address of the contract which is requesting the + // callback (bech32 encoded). + string contract_address = 1; + // job_id is an identifier the callback requestor can pass in to identify the + // callback when it happens. + uint64 job_id = 2; + // callback_height is the height at which the callback is executed. + int64 callback_height = 3; + // fee_split is the breakdown of the fees paid by the contract to reserve the + // callback + CallbackFeesFeeSplit fee_split = 4; + // reserved_by is the address which reserved the callback (bech32 encoded). + string reserved_by = 5; + // callback_gas_limit is the maximum gas that can be consumed by this + // callback. + uint64 max_gas_limit = 6; } -// CallbackFeesFeeSplit is the breakdown of all the fees that need to be paid by the contract to reserve a callback +// CallbackFeesFeeSplit is the breakdown of all the fees that need to be paid by +// the contract to reserve a callback message CallbackFeesFeeSplit { - // transaction_fees is the transaction fees for the callback based on its gas consumption - cosmos.base.v1beta1.Coin transaction_fees = 1; - // block_reservation_fees is the block reservation fees portion of the callback reservation fees - cosmos.base.v1beta1.Coin block_reservation_fees = 2; - // future_reservation_fees is the future reservation fees portion of the callback reservation fees - cosmos.base.v1beta1.Coin future_reservation_fees = 3; - // surplus_fees is any extra fees passed in for the registration of the callback - cosmos.base.v1beta1.Coin surplus_fees = 4; - } + // transaction_fees is the transaction fees for the callback based on its gas + // consumption + cosmos.base.v1beta1.Coin transaction_fees = 1; + // block_reservation_fees is the block reservation fees portion of the + // callback reservation fees + cosmos.base.v1beta1.Coin block_reservation_fees = 2; + // future_reservation_fees is the future reservation fees portion of the + // callback reservation fees + cosmos.base.v1beta1.Coin future_reservation_fees = 3; + // surplus_fees is any extra fees passed in for the registration of the + // callback + cosmos.base.v1beta1.Coin surplus_fees = 4; +} // Params defines the module parameters. message Params { - // callback_gas_limit is the maximum gas that can be consumed by a callback. - uint64 callback_gas_limit = 1; - // max_block_reservation_limit is the maximum number of callbacks which can be registered in a given block. - uint64 max_block_reservation_limit = 2; - // max_future_reservation_limit is the maximum number of blocks in the future that a contract can request a callback in. - uint64 max_future_reservation_limit = 3; - // block_reservation_fee_multiplier is used to calculate a part of the reservation fees which will need to be paid when requesting the callback. - string block_reservation_fee_multiplier = 4 [(cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", (gogoproto.nullable) = false]; - // future_reservation_fee_multiplier is used to calculate a part of the reservation fees which will need to be paid while requesting the callback. - string future_reservation_fee_multiplier = 5 [(cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", (gogoproto.nullable) = false]; -} \ No newline at end of file + // callback_gas_limit is the maximum gas that can be consumed by a callback. + uint64 callback_gas_limit = 1; + // max_block_reservation_limit is the maximum number of callbacks which can be + // registered in a given block. + uint64 max_block_reservation_limit = 2; + // max_future_reservation_limit is the maximum number of blocks in the future + // that a contract can request a callback in. + uint64 max_future_reservation_limit = 3; + // block_reservation_fee_multiplier is used to calculate a part of the + // reservation fees which will need to be paid when requesting the callback. + string block_reservation_fee_multiplier = 4 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + // future_reservation_fee_multiplier is used to calculate a part of the + // reservation fees which will need to be paid while requesting the callback. + string future_reservation_fee_multiplier = 5 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; +} diff --git a/proto/archway/callback/v1/errors.proto b/proto/archway/callback/v1/errors.proto index 0139a782..ab7dafe1 100644 --- a/proto/archway/callback/v1/errors.proto +++ b/proto/archway/callback/v1/errors.proto @@ -9,8 +9,10 @@ option go_package = "github.com/archway-network/archway/x/callback/types"; enum ModuleErrors { // ERR_UNKNOWN is the default error code ERR_UNKNOWN = 0; - // ERR_OUT_OF_GAS is the error code when the contract callback exceeds the gas limit allowed by the module + // ERR_OUT_OF_GAS is the error code when the contract callback exceeds the gas + // limit allowed by the module ERR_OUT_OF_GAS = 1; - // ERR_CONTRACT_EXECUTION_FAILED is the error code when the contract callback execution fails + // ERR_CONTRACT_EXECUTION_FAILED is the error code when the contract callback + // execution fails ERR_CONTRACT_EXECUTION_FAILED = 2; } \ No newline at end of file diff --git a/proto/archway/callback/v1/events.proto b/proto/archway/callback/v1/events.proto index 669175bc..cc519077 100644 --- a/proto/archway/callback/v1/events.proto +++ b/proto/archway/callback/v1/events.proto @@ -10,54 +10,62 @@ import "cosmos_proto/cosmos.proto"; // CallbackRegisteredEvent is emitted when a callback is registered. message CallbackRegisteredEvent { - // contract_address is the address of the contract for which callback is being registered (bech32 encoded). - string contract_address = 1; - // job_id is an identifier of the callback. - uint64 job_id = 2; - // callback_height is the height at which the callback is executed. - int64 callback_height = 3; - // fee_split is the breakdown of the fees paid by the contract to reserve the callback - CallbackFeesFeeSplit fee_split = 4; - // reserved_by is the address which reserved the callback (bech32 encoded). - string reserved_by = 5; + // contract_address is the address of the contract for which callback is being + // registered (bech32 encoded). + string contract_address = 1; + // job_id is an identifier of the callback. + uint64 job_id = 2; + // callback_height is the height at which the callback is executed. + int64 callback_height = 3; + // fee_split is the breakdown of the fees paid by the contract to reserve the + // callback + CallbackFeesFeeSplit fee_split = 4; + // reserved_by is the address which reserved the callback (bech32 encoded). + string reserved_by = 5; } // CallbackCancelledEvent is emitted when a callback is cancelled. message CallbackCancelledEvent { - // cancelled_by is the address of the contract whose callback is being cancelled (bech32 encoded) - string cancelled_by = 1; - // contract_address is the address of the contract (bech32 encoded) - string contract_address = 2; - // job_id is an identifier the callback requestor had passed during registration of the callback - uint64 job_id = 3; - // callback_height is the height at which the callback requestor had registered the callback - int64 callback_height = 4; - // refund_amount is the amount of fees which was refunded on cancellation - cosmos.base.v1beta1.Coin refund_amount = 5 [ (gogoproto.nullable) = false ]; + // cancelled_by is the address of the contract whose callback is being + // cancelled (bech32 encoded) + string cancelled_by = 1; + // contract_address is the address of the contract (bech32 encoded) + string contract_address = 2; + // job_id is an identifier the callback requestor had passed during + // registration of the callback + uint64 job_id = 3; + // callback_height is the height at which the callback requestor had + // registered the callback + int64 callback_height = 4; + // refund_amount is the amount of fees which was refunded on cancellation + cosmos.base.v1beta1.Coin refund_amount = 5 [ (gogoproto.nullable) = false ]; } -// CallbackExecutedSuccessEvent is emitted when a callback is executed successfully. +// CallbackExecutedSuccessEvent is emitted when a callback is executed +// successfully. message CallbackExecutedSuccessEvent { - // contract_address is the address of the contract for which callback is being executed (bech32 encoded). - string contract_address = 1; - // job_id is an identifier of the callback. - uint64 job_id = 2; - // sudo_msg is the input passed by the module to the contract - string sudo_msg = 3; - // gas_used is the amount of gas consumed during the callback execution - uint64 gas_used = 4; + // contract_address is the address of the contract for which callback is being + // executed (bech32 encoded). + string contract_address = 1; + // job_id is an identifier of the callback. + uint64 job_id = 2; + // sudo_msg is the input passed by the module to the contract + string sudo_msg = 3; + // gas_used is the amount of gas consumed during the callback execution + uint64 gas_used = 4; } // CallbackExecutedFailedEvent is emitted when a callback execution fails. message CallbackExecutedFailedEvent { - // contract_address is the address of the contract for which callback is being executed (bech32 encoded). - string contract_address = 1; - // job_id is an identifier of the callback. - uint64 job_id = 2; - // sudo_msg is the input passed by the module to the contract - string sudo_msg = 3; - // gas_used is the amount of gas consumed during the callback execution - uint64 gas_used = 4; - // error is the error returned during the callback execution - string error = 5; + // contract_address is the address of the contract for which callback is being + // executed (bech32 encoded). + string contract_address = 1; + // job_id is an identifier of the callback. + uint64 job_id = 2; + // sudo_msg is the input passed by the module to the contract + string sudo_msg = 3; + // gas_used is the amount of gas consumed during the callback execution + uint64 gas_used = 4; + // error is the error returned during the callback execution + string error = 5; } diff --git a/proto/archway/callback/v1/genesis.proto b/proto/archway/callback/v1/genesis.proto index d81c594a..f25eb949 100644 --- a/proto/archway/callback/v1/genesis.proto +++ b/proto/archway/callback/v1/genesis.proto @@ -10,7 +10,7 @@ import "archway/callback/v1/callback.proto"; // GenesisState defines the initial state of the callback module. message GenesisState { // params defines all the module parameters. - Params params = 1 [ (gogoproto.nullable) = false ]; + Params params = 1 [ (gogoproto.nullable) = false ]; // callbacks defines all the callbacks which are yet to be executed repeated Callback callbacks = 2; } diff --git a/proto/archway/callback/v1/query.proto b/proto/archway/callback/v1/query.proto index 3714deca..db481396 100644 --- a/proto/archway/callback/v1/query.proto +++ b/proto/archway/callback/v1/query.proto @@ -10,18 +10,21 @@ import "archway/callback/v1/callback.proto"; // Query service for the callback module. service Query { - // Params returns module parameters - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/archway/callback/v1/params"; - } - // EstimateCallbackFees returns the total amount of callback fees a contract needs to pay to register the callback - rpc EstimateCallbackFees(QueryEstimateCallbackFeesRequest) returns (QueryEstimateCallbackFeesResponse) { - option (google.api.http).get = "/archway/callback/v1/estimate_callback_fees"; - } - // Callbacks returns all the callbacks registered at a given height - rpc Callbacks(QueryCallbacksRequest) returns (QueryCallbacksResponse) { - option (google.api.http).get = "/archway/callback/v1/callbacks"; - } + // Params returns module parameters + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/archway/callback/v1/params"; + } + // EstimateCallbackFees returns the total amount of callback fees a contract + // needs to pay to register the callback + rpc EstimateCallbackFees(QueryEstimateCallbackFeesRequest) + returns (QueryEstimateCallbackFeesResponse) { + option (google.api.http).get = + "/archway/callback/v1/estimate_callback_fees"; + } + // Callbacks returns all the callbacks registered at a given height + rpc Callbacks(QueryCallbacksRequest) returns (QueryCallbacksResponse) { + option (google.api.http).get = "/archway/callback/v1/callbacks"; + } } // QueryParamsRequest is the request for Query.Params. @@ -33,28 +36,31 @@ message QueryParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } -// QueryEstimateCallbackFeesRequest is the request for Query.EstimateCallbackFees. -message QueryEstimateCallbackFeesRequest{ +// QueryEstimateCallbackFeesRequest is the request for +// Query.EstimateCallbackFees. +message QueryEstimateCallbackFeesRequest { // block_height is the height at which to estimate the callback fees int64 block_height = 1; } -// QueryEstimateCallbackFeesResponse is the response for Query.EstimateCallbackFees. -message QueryEstimateCallbackFeesResponse{ - // total_fees is the total fees that needs to be paid by the contract to reserve a callback +// QueryEstimateCallbackFeesResponse is the response for +// Query.EstimateCallbackFees. +message QueryEstimateCallbackFeesResponse { + // total_fees is the total fees that needs to be paid by the contract to + // reserve a callback cosmos.base.v1beta1.Coin total_fees = 1; // fee_split is the breakdown of the total_fees CallbackFeesFeeSplit fee_split = 2; } // QueryCallbacksRequest is the request for Query.Callbacks. -message QueryCallbacksRequest{ +message QueryCallbacksRequest { // block_height is the height at which to query the callbacks int64 block_height = 1; } // QueryCallbacksResponse is the response for Query.Callbacks. -message QueryCallbacksResponse{ +message QueryCallbacksResponse { // callbacks is the list of callbacks registered at the given height repeated Callback callbacks = 1; } \ No newline at end of file diff --git a/proto/archway/callback/v1/tx.proto b/proto/archway/callback/v1/tx.proto index 1903458f..f9935334 100644 --- a/proto/archway/callback/v1/tx.proto +++ b/proto/archway/callback/v1/tx.proto @@ -15,7 +15,8 @@ service Msg { // module parameters. The authority is defined in the keeper. rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); - // RequestCallback defines a message for registering a callback at a specific height by a given contract + // RequestCallback defines a message for registering a callback at a specific + // height by a given contract rpc RequestCallback(MsgRequestCallback) returns (MsgRequestCallbackResponse); // CancelCallback defines a message for cancelling an existing callback @@ -24,53 +25,64 @@ service Msg { // MsgUpdateParams is the Msg/UpdateParams request type. message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "authority"; - // authority is the address that controls the module (defaults to x/gov unless overwritten). - string authority = 1; - // params defines the x/callback parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "params,omitempty"]; + option (cosmos.msg.v1.signer) = "authority"; + // authority is the address that controls the module (defaults to x/gov unless + // overwritten). + string authority = 1; + // params defines the x/callback parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "params,omitempty" + ]; } - -// MsgUpdateParamsResponse defines the response structure for executing a MsgUpdateParams message. + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. message MsgUpdateParamsResponse {} // MsgRequestCallback is the Msg/RequestCallback request type. message MsgRequestCallback { - option (cosmos.msg.v1.signer) = "sender"; - // sender is the address who is requesting the callback (bech32 encoded) - string sender = 1; - // contract_address is the address of the contract which is requesting the callback (bech32 encoded) - string contract_address = 2; - // job_id is an identifier the callback requestor can pass in to identify the callback when it happens - uint64 job_id = 3; - // callback_height is the height at which the callback is executed. - int64 callback_height = 4; - // fees is the amount of fees being paid to register the contract - cosmos.base.v1beta1.Coin fees = 5 [ (gogoproto.nullable) = false ]; + option (cosmos.msg.v1.signer) = "sender"; + // sender is the address who is requesting the callback (bech32 encoded) + string sender = 1; + // contract_address is the address of the contract which is requesting the + // callback (bech32 encoded) + string contract_address = 2; + // job_id is an identifier the callback requestor can pass in to identify the + // callback when it happens + uint64 job_id = 3; + // callback_height is the height at which the callback is executed. + int64 callback_height = 4; + // fees is the amount of fees being paid to register the contract + cosmos.base.v1beta1.Coin fees = 5 [ (gogoproto.nullable) = false ]; } - -// MsgRequestCallbackResponse defines the response structure for executing a MsgRequestCallback message. +// MsgRequestCallbackResponse defines the response structure for executing a +// MsgRequestCallback message. message MsgRequestCallbackResponse {} // MsgCancelCallback is the Msg/CancelCallback request type. -message MsgCancelCallback{ +message MsgCancelCallback { option (cosmos.msg.v1.signer) = "sender"; - // sender is the address of the contract which is cancelling the callback (bech32 encoded) + // sender is the address of the contract which is cancelling the callback + // (bech32 encoded) string sender = 1; // contract_address is the address of the contract (bech32 encoded) string contract_address = 2; - // job_id is an identifier the callback requestor had passed during registration of the callback + // job_id is an identifier the callback requestor had passed during + // registration of the callback uint64 job_id = 3; - // callback_height is the height at which the callback requestor had registered the callback + // callback_height is the height at which the callback requestor had + // registered the callback int64 callback_height = 4; } - -// MsgCancelCallbackResponse defines the response structure for executing a MsgCancelCallback message. +// MsgCancelCallbackResponse defines the response structure for executing a +// MsgCancelCallback message. message MsgCancelCallbackResponse { - // refund is the amount of fees being refunded due to the cancellation of the callback + // refund is the amount of fees being refunded due to the cancellation of the + // callback cosmos.base.v1beta1.Coin refund = 1 [ (gogoproto.nullable) = false ]; -} \ No newline at end of file +} \ No newline at end of file diff --git a/proto/archway/cwerrors/v1/cwerrors.proto b/proto/archway/cwerrors/v1/cwerrors.proto index ded53eab..3d580373 100644 --- a/proto/archway/cwerrors/v1/cwerrors.proto +++ b/proto/archway/cwerrors/v1/cwerrors.proto @@ -24,6 +24,7 @@ message SudoError { enum ModuleErrors { // ERR_UNKNOWN is the default error code ERR_UNKNOWN = 0; - // ERR_CALLBACK_EXECUTION_FAILED is the error code for when the error callback fails + // ERR_CALLBACK_EXECUTION_FAILED is the error code for when the error callback + // fails ERR_CALLBACK_EXECUTION_FAILED = 1; } \ No newline at end of file diff --git a/proto/archway/cwfees/v1/cwfees.proto b/proto/archway/cwfees/v1/cwfees.proto index 3bf230cd..0b104012 100644 --- a/proto/archway/cwfees/v1/cwfees.proto +++ b/proto/archway/cwfees/v1/cwfees.proto @@ -5,15 +5,18 @@ import "google/protobuf/any.proto"; import "cosmos/msg/v1/msg.proto"; - option go_package = "github.com/archway-network/archway/x/cwfees/types"; service Msg { option (cosmos.msg.v1.service) = true; - // RegisterAsGranter allows a cosmwasm contract to register itself as a fee granter. - rpc RegisterAsGranter(MsgRegisterAsGranter) returns (MsgRegisterAsGranterResponse); - // UnregisterAsGranter allows a cosmwasm contract to unregister itself as a fee granter. - rpc UnregisterAsGranter(MsgUnregisterAsGranter) returns (MsgUnregisterAsGranterResponse); + // RegisterAsGranter allows a cosmwasm contract to register itself as a fee + // granter. + rpc RegisterAsGranter(MsgRegisterAsGranter) + returns (MsgRegisterAsGranterResponse); + // UnregisterAsGranter allows a cosmwasm contract to unregister itself as a + // fee granter. + rpc UnregisterAsGranter(MsgUnregisterAsGranter) + returns (MsgUnregisterAsGranterResponse); } // MsgRegisterAsGranter allows a contract to register itself as a fee granter. @@ -25,7 +28,8 @@ message MsgRegisterAsGranter { // MsgRegisterAsGranterResponse defines the response of RegisterAsGranter. message MsgRegisterAsGranterResponse {} -// MsgUnregisterAsGranter can be used by a cosmwasm contract to unregister itself as a fee granter. +// MsgUnregisterAsGranter can be used by a cosmwasm contract to unregister +// itself as a fee granter. message MsgUnregisterAsGranter { option (cosmos.msg.v1.signer) = "granting_contract"; string granting_contract = 1; @@ -35,8 +39,10 @@ message MsgUnregisterAsGranter { message MsgUnregisterAsGranterResponse {} service Query { - // IsGrantingContract can be used to check if a contract is a granting contract. - rpc IsGrantingContract(IsGrantingContractRequest) returns (IsGrantingContractResponse); + // IsGrantingContract can be used to check if a contract is a granting + // contract. + rpc IsGrantingContract(IsGrantingContractRequest) + returns (IsGrantingContractResponse); } // IsGrantingContract is the request type of IsGrantingContract RPC. @@ -53,6 +59,4 @@ message IsGrantingContractResponse { } // GenesisState represents the genesis state of the cwfeesant module. -message GenesisState { - repeated string granting_contracts = 1; -} +message GenesisState { repeated string granting_contracts = 1; } diff --git a/proto/archway/genmsg/v1/genmsg.proto b/proto/archway/genmsg/v1/genmsg.proto index 93f2de4c..2dc193ed 100644 --- a/proto/archway/genmsg/v1/genmsg.proto +++ b/proto/archway/genmsg/v1/genmsg.proto @@ -3,10 +3,8 @@ package archway.genmsg.v1; import "google/protobuf/any.proto"; - option go_package = "github.com/archway-network/archway/x/genmsg/types"; -// GenesisState represents the messages to be processed during genesis by the genmsg module. -message GenesisState { - repeated google.protobuf.Any messages = 1; -} +// GenesisState represents the messages to be processed during genesis by the +// genmsg module. +message GenesisState { repeated google.protobuf.Any messages = 1; } diff --git a/proto/archway/oracle/v1/event.proto b/proto/archway/oracle/v1/event.proto new file mode 100644 index 00000000..8ae02a79 --- /dev/null +++ b/proto/archway/oracle/v1/event.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; + +package archway.oracle.v1; + +import "archway/oracle/v1/oracle.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/archway-network/archway/x/oracle/types"; + +// Emitted when a price is posted +message EventPriceUpdate { + string pair = 1; + string price = 2 [ + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + int64 timestamp_ms = 3; +} + +// Emitted when a valoper delegates oracle voting rights to a feeder address. +message EventDelegateFeederConsent { + // Validator is the Bech32 address that is delegating voting rights. + string validator = 1; + + // Feeder is the delegate or representative that will be able to send + // vote and prevote transaction messages. + string feeder = 2; +} + +// Emitted by MsgAggregateExchangeVote when an aggregate vote is added to state +message EventAggregateVote { + // Validator is the Bech32 address to which the vote will be credited. + string validator = 1; + + // Feeder is the delegate or representative that will send vote and prevote + // transaction messages on behalf of the voting validator. + string feeder = 2; + + repeated archway.oracle.v1.ExchangeRateTuple prices = 3 [ + (gogoproto.castrepeated) = "ExchangeRateTuples", + (gogoproto.nullable) = false + ]; +} + +// Emitted by MsgAggregateExchangePrevote when an aggregate prevote is added +// to state +message EventAggregatePrevote { + // Validator is the Bech32 address to which the vote will be credited. + string validator = 1; + + // Feeder is the delegate or representative that will send vote and prevote + // transaction messages on behalf of the voting validator. + string feeder = 2; +} + +message EventValidatorPerformance { + // Validator is the Bech32 address to which the vote will be credited. + string validator = 1; + + // Tendermint consensus voting power + int64 voting_power = 2; + + // RewardWeight: Weight of rewards the validator should receive in units of + // consensus power. + int64 reward_weight = 3; + + // Number of valid votes for which the validator will be rewarded + int64 win_count = 4; + + // Number of abstained votes for which there will be no reward or punishment + int64 abstain_count = 5; + + // Number of invalid/punishable votes + int64 miss_count = 6; +} \ No newline at end of file diff --git a/proto/archway/oracle/v1/genesis.proto b/proto/archway/oracle/v1/genesis.proto new file mode 100644 index 00000000..32a5be4f --- /dev/null +++ b/proto/archway/oracle/v1/genesis.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; +package archway.oracle.v1; + +import "gogoproto/gogo.proto"; +import "archway/oracle/v1/oracle.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/archway-network/archway/x/oracle/types"; + +// GenesisState defines the oracle module's genesis state. +message GenesisState { + archway.oracle.v1.Params params = 1 [ (gogoproto.nullable) = false ]; + repeated archway.oracle.v1.FeederDelegation feeder_delegations = 2 + [ (gogoproto.nullable) = false ]; + repeated archway.oracle.v1.ExchangeRateTuple exchange_rates = 3 [ + (gogoproto.castrepeated) = "ExchangeRateTuples", + (gogoproto.nullable) = false + ]; + repeated archway.oracle.v1.MissCounter miss_counters = 4 + [ (gogoproto.nullable) = false ]; + repeated archway.oracle.v1.AggregateExchangeRatePrevote + aggregate_exchange_rate_prevotes = 5 [ (gogoproto.nullable) = false ]; + repeated archway.oracle.v1.AggregateExchangeRateVote + aggregate_exchange_rate_votes = 6 [ (gogoproto.nullable) = false ]; + repeated string pairs = 7 [ + (gogoproto.customtype) = + "github.com/archway-network/archway/x/oracle/asset.Pair", + (gogoproto.nullable) = false + ]; + repeated archway.oracle.v1.Rewards rewards = 8 + [ (gogoproto.nullable) = false ]; +} + +// FeederDelegation is the address for where oracle feeder authority are +// delegated to. By default this struct is only used at genesis to feed in +// default feeder addresses. +message FeederDelegation { + string feeder_address = 1; + string validator_address = 2; +} + +// MissCounter defines an miss counter and validator address pair used in +// oracle module's genesis state +message MissCounter { + string validator_address = 1; + uint64 miss_counter = 2; +} diff --git a/proto/archway/oracle/v1/oracle.proto b/proto/archway/oracle/v1/oracle.proto new file mode 100644 index 00000000..5dd4cd14 --- /dev/null +++ b/proto/archway/oracle/v1/oracle.proto @@ -0,0 +1,161 @@ +syntax = "proto3"; +package archway.oracle.v1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/archway-network/archway/x/oracle/types"; + +// Params defines the module parameters for the x/oracle module. +message Params { + option (gogoproto.equal) = true; + + // VotePeriod defines the number of blocks during which voting takes place. + uint64 vote_period = 1 [ (gogoproto.moretags) = "yaml:\"vote_period\"" ]; + + // VoteThreshold specifies the minimum proportion of votes that must be + // received for a ballot to pass. + string vote_threshold = 2 [ + (gogoproto.moretags) = "yaml:\"vote_threshold\"", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + // RewardBand defines a maxium divergence that a price vote can have from the + // weighted median in the ballot. If a vote lies within the valid range + // defined by: + // μ := weightedMedian, + // validRange := μ ± (μ * rewardBand / 2), + // then rewards are added to the validator performance. + // Note that if the reward band is smaller than 1 standard + // deviation, the band is taken to be 1 standard deviation.a price + string reward_band = 3 [ + (gogoproto.moretags) = "yaml:\"reward_band\"", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + // The set of whitelisted markets, or asset pairs, for the module. + // Ex. '["unibi:uusd","ubtc:uusd"]' + repeated string whitelist = 4 [ + (gogoproto.moretags) = "yaml:\"whitelist\"", + (gogoproto.customtype) = + "github.com/archway-network/archway/x/oracle/asset.Pair" + ]; + // SlashFraction returns the proportion of an oracle's stake that gets + // slashed in the event of slashing. `SlashFraction` specifies the exact + // penalty for failing a voting period. + string slash_fraction = 5 [ + (gogoproto.moretags) = "yaml:\"slash_fraction\"", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + // SlashWindow returns the number of voting periods that specify a + // "slash window". After each slash window, all oracles that have missed more + // than the penalty threshold are slashed. Missing the penalty threshold is + // synonymous with submitting fewer valid votes than `MinValidPerWindow`. + uint64 slash_window = 6 [ (gogoproto.moretags) = "yaml:\"slash_window\"" ]; + string min_valid_per_window = 7 [ + (gogoproto.moretags) = "yaml:\"min_valid_per_window\"", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + + // Amount of time to look back for TWAP calculations. + // Ex: "900.000000069s" corresponds to 900 seconds and 69 nanoseconds in JSON. + google.protobuf.Duration twap_lookback_window = 8 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "twap_lookback_window,omitempty", + (gogoproto.moretags) = "yaml:\"twap_lookback_window\"" + ]; + + // The minimum number of voters (i.e. oracle validators) per pair for it to be + // considered a passing ballot. Recommended at least 4. + uint64 min_voters = 9 [ (gogoproto.moretags) = "yaml:\"min_voters\"" ]; + + // The validator fee ratio that is given to validators every epoch. + string validator_fee_ratio = 10 [ + (gogoproto.moretags) = "yaml:\"validator_fee_ratio\"", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + + uint64 expiration_blocks = 11 + [ (gogoproto.moretags) = "yaml:\"expiration_blocks\"" ]; +} + +// Struct for aggregate prevoting on the ExchangeRateVote. +// The purpose of aggregate prevote is to hide vote exchange rates with hash +// which is formatted as hex string in +// SHA256("{salt}:({pair},{exchange_rate})|...|({pair},{exchange_rate}):{voter}") +message AggregateExchangeRatePrevote { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string hash = 1 [ (gogoproto.moretags) = "yaml:\"hash\"" ]; + string voter = 2 [ (gogoproto.moretags) = "yaml:\"voter\"" ]; + uint64 submit_block = 3 [ (gogoproto.moretags) = "yaml:\"submit_block\"" ]; +} + +// MsgAggregateExchangeRateVote - struct for voting on +// the exchange rates different assets. +message AggregateExchangeRateVote { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + repeated ExchangeRateTuple exchange_rate_tuples = 1 [ + (gogoproto.moretags) = "yaml:\"exchange_rate_tuples\"", + (gogoproto.castrepeated) = "ExchangeRateTuples", + (gogoproto.nullable) = false + ]; + + string voter = 2 [ (gogoproto.moretags) = "yaml:\"voter\"" ]; +} + +// ExchangeRateTuple - struct to store interpreted exchange rates data to store +message ExchangeRateTuple { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string pair = 1 [ + (gogoproto.moretags) = "yaml:\"pair\"", + (gogoproto.customtype) = + "github.com/archway-network/archway/x/oracle/asset.Pair", + (gogoproto.nullable) = false + ]; + + string exchange_rate = 2 [ + (gogoproto.moretags) = "yaml:\"exchange_rate\"", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; +} + +message DatedPrice { + string exchange_rate = 1 [ + (gogoproto.moretags) = "yaml:\"exchange_rate\"", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + + // creation_height defines the block height when price record was created + int64 creation_height = 2 + [ (gogoproto.moretags) = "yaml:\"creation_height\"" ]; + + // creation_time_unix_ms defines the block time in milliseconds since unix epoch, + // when price record was created + uint64 creation_time_unix_ms = 3 + [ (gogoproto.moretags) = "yaml:\"creation_time_unix_ms\"" ]; +} + +// Rewards defines a credit object towards validators +// which provide prices faithfully for different pairs. +message Rewards { + // id uniquely identifies the rewards instance of the pair + uint64 id = 1; + // vote_periods defines the vote periods left in which rewards will be + // distributed. + uint64 vote_periods = 2; + // Coins defines the amount of coins to distribute in a single vote period. + repeated cosmos.base.v1beta1.Coin coins = 3 [ (gogoproto.nullable) = false ]; +} diff --git a/proto/archway/oracle/v1/query.proto b/proto/archway/oracle/v1/query.proto new file mode 100644 index 00000000..b2c0ac65 --- /dev/null +++ b/proto/archway/oracle/v1/query.proto @@ -0,0 +1,264 @@ +syntax = "proto3"; +package archway.oracle.v1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "archway/oracle/v1/oracle.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/archway-network/archway/x/oracle/types"; + +// Query defines the gRPC querier service. +service Query { + // ExchangeRate returns exchange rate of a pair + rpc ExchangeRate(QueryExchangeRateRequest) + returns (QueryExchangeRateResponse) { + option (google.api.http).get = "/archway/oracle/v1beta1/exchange_rate"; + } + + // ExchangeRateTwap returns twap exchange rate of a pair + rpc ExchangeRateTwap(QueryExchangeRateRequest) + returns (QueryExchangeRateResponse) { + option (google.api.http).get = "/archway/oracle/v1beta1/exchange_rate_twap"; + } + + // ExchangeRates returns exchange rates of all pairs + rpc ExchangeRates(QueryExchangeRatesRequest) + returns (QueryExchangeRatesResponse) { + option (google.api.http).get = + "/archway/oracle/v1beta1/pairs/exchange_rates"; + } + + // Actives returns all active pairs + rpc Actives(QueryActivesRequest) returns (QueryActivesResponse) { + option (google.api.http).get = "/archway/oracle/v1beta1/pairs/actives"; + } + + // VoteTargets returns all vote target for pairs + rpc VoteTargets(QueryVoteTargetsRequest) returns (QueryVoteTargetsResponse) { + option (google.api.http).get = "/archway/oracle/v1beta1/pairs/vote_targets"; + } + + // FeederDelegation returns feeder delegation of a validator + rpc FeederDelegation(QueryFeederDelegationRequest) + returns (QueryFeederDelegationResponse) { + option (google.api.http).get = + "/archway/oracle/v1beta1/validators/{validator_addr}/feeder"; + } + + // MissCounter returns oracle miss counter of a validator + rpc MissCounter(QueryMissCounterRequest) returns (QueryMissCounterResponse) { + option (google.api.http).get = + "/archway/oracle/v1beta1/validators/{validator_addr}/miss"; + } + + // AggregatePrevote returns an aggregate prevote of a validator + rpc AggregatePrevote(QueryAggregatePrevoteRequest) + returns (QueryAggregatePrevoteResponse) { + option (google.api.http).get = + "/archway/oracle/v1beta1/validators/{validator_addr}/aggregate_prevote"; + } + + // AggregatePrevotes returns aggregate prevotes of all validators + rpc AggregatePrevotes(QueryAggregatePrevotesRequest) + returns (QueryAggregatePrevotesResponse) { + option (google.api.http).get = + "/archway/oracle/v1beta1/validators/aggregate_prevotes"; + } + + // AggregateVote returns an aggregate vote of a validator + rpc AggregateVote(QueryAggregateVoteRequest) + returns (QueryAggregateVoteResponse) { + option (google.api.http).get = + "/archway/oracle/v1beta1/valdiators/{validator_addr}/aggregate_vote"; + } + + // AggregateVotes returns aggregate votes of all validators + rpc AggregateVotes(QueryAggregateVotesRequest) + returns (QueryAggregateVotesResponse) { + option (google.api.http).get = + "/archway/oracle/v1beta1/validators/aggregate_votes"; + } + + // Params queries all parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/archway/oracle/v1beta1/params"; + } +} + +// QueryExchangeRateRequest is the request type for the Query/ExchangeRate RPC +// method. +message QueryExchangeRateRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // pair defines the pair to query for. + string pair = 1 [ + (gogoproto.customtype) = + "github.com/archway-network/archway/x/oracle/asset.Pair", + (gogoproto.nullable) = false + ]; +} + +// QueryExchangeRateResponse is response type for the +// Query/ExchangeRate RPC method. +message QueryExchangeRateResponse { + // exchange_rate defines the exchange rate of assets voted by validators + string exchange_rate = 1 [ + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; +} + +// QueryExchangeRatesRequest is the request type for the Query/ExchangeRates RPC +// method. +message QueryExchangeRatesRequest {} + +// QueryExchangeRatesResponse is response type for the +// Query/ExchangeRates RPC method. +message QueryExchangeRatesResponse { + // exchange_rates defines a list of the exchange rate for all whitelisted + // pairs. + repeated archway.oracle.v1.ExchangeRateTuple exchange_rates = 1 [ + (gogoproto.castrepeated) = "ExchangeRateTuples", + (gogoproto.nullable) = false + ]; +} + +// QueryActivesRequest is the request type for the Query/Actives RPC method. +message QueryActivesRequest {} + +// QueryActivesResponse is response type for the +// Query/Actives RPC method. +message QueryActivesResponse { + // actives defines a list of the pair which oracle prices agreed upon. + repeated string actives = 1 [ + (gogoproto.customtype) = + "github.com/archway-network/archway/x/oracle/asset.Pair", + (gogoproto.nullable) = false + ]; +} + +// QueryVoteTargetsRequest is the request type for the Query/VoteTargets RPC +// method. +message QueryVoteTargetsRequest {} + +// QueryVoteTargetsResponse is response type for the +// Query/VoteTargets RPC method. +message QueryVoteTargetsResponse { + // vote_targets defines a list of the pairs in which everyone + // should vote in the current vote period. + repeated string vote_targets = 1 [ + (gogoproto.customtype) = + "github.com/archway-network/archway/x/oracle/asset.Pair", + (gogoproto.nullable) = false + ]; +} + +// QueryFeederDelegationRequest is the request type for the +// Query/FeederDelegation RPC method. +message QueryFeederDelegationRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator defines the validator address to query for. + string validator_addr = 1; +} + +// QueryFeederDelegationResponse is response type for the +// Query/FeederDelegation RPC method. +message QueryFeederDelegationResponse { + // feeder_addr defines the feeder delegation of a validator + string feeder_addr = 1; +} + +// QueryMissCounterRequest is the request type for the Query/MissCounter RPC +// method. +message QueryMissCounterRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator defines the validator address to query for. + string validator_addr = 1; +} + +// QueryMissCounterResponse is response type for the +// Query/MissCounter RPC method. +message QueryMissCounterResponse { + // miss_counter defines the oracle miss counter of a validator + uint64 miss_counter = 1; +} + +// QueryAggregatePrevoteRequest is the request type for the +// Query/AggregatePrevote RPC method. +message QueryAggregatePrevoteRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator defines the validator address to query for. + string validator_addr = 1; +} + +// QueryAggregatePrevoteResponse is response type for the +// Query/AggregatePrevote RPC method. +message QueryAggregatePrevoteResponse { + // aggregate_prevote defines oracle aggregate prevote submitted by a validator + // in the current vote period + archway.oracle.v1.AggregateExchangeRatePrevote aggregate_prevote = 1 + [ (gogoproto.nullable) = false ]; + ; +} + +// QueryAggregatePrevotesRequest is the request type for the +// Query/AggregatePrevotes RPC method. +message QueryAggregatePrevotesRequest {} + +// QueryAggregatePrevotesResponse is response type for the +// Query/AggregatePrevotes RPC method. +message QueryAggregatePrevotesResponse { + // aggregate_prevotes defines all oracle aggregate prevotes submitted in the + // current vote period + repeated archway.oracle.v1.AggregateExchangeRatePrevote aggregate_prevotes = 1 + [ (gogoproto.nullable) = false ]; +} + +// QueryAggregateVoteRequest is the request type for the Query/AggregateVote RPC +// method. +message QueryAggregateVoteRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator defines the validator address to query for. + string validator_addr = 1; +} + +// QueryAggregateVoteResponse is response type for the +// Query/AggregateVote RPC method. +message QueryAggregateVoteResponse { + // aggregate_vote defines oracle aggregate vote submitted by a validator in + // the current vote period + archway.oracle.v1.AggregateExchangeRateVote aggregate_vote = 1 + [ (gogoproto.nullable) = false ]; +} + +// QueryAggregateVotesRequest is the request type for the Query/AggregateVotes +// RPC method. +message QueryAggregateVotesRequest {} + +// QueryAggregateVotesResponse is response type for the +// Query/AggregateVotes RPC method. +message QueryAggregateVotesResponse { + // aggregate_votes defines all oracle aggregate votes submitted in the current + // vote period + repeated archway.oracle.v1.AggregateExchangeRateVote aggregate_votes = 1 + [ (gogoproto.nullable) = false ]; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + archway.oracle.v1.Params params = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/proto/archway/oracle/v1/state.proto b/proto/archway/oracle/v1/state.proto new file mode 100644 index 00000000..055e0164 --- /dev/null +++ b/proto/archway/oracle/v1/state.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package archway.oracle.v1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "archway/oracle/v1/oracle.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/archway-network/archway/x/oracle/types"; + +// a snapshot of the prices at a given point in time +message PriceSnapshot { + string pair = 1 [ + (gogoproto.moretags) = "yaml:\"pair\"", + (gogoproto.customtype) = + "github.com/archway-network/archway/x/oracle/asset.Pair", + (gogoproto.nullable) = false + ]; + + string price = 2 [ + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + + // milliseconds since unix epoch + int64 timestamp_ms = 3; +} \ No newline at end of file diff --git a/proto/archway/oracle/v1/tx.proto b/proto/archway/oracle/v1/tx.proto new file mode 100644 index 00000000..94e03dd6 --- /dev/null +++ b/proto/archway/oracle/v1/tx.proto @@ -0,0 +1,94 @@ +syntax = "proto3"; +package archway.oracle.v1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "archway/oracle/v1/oracle.proto"; +import "cosmos/msg/v1/msg.proto"; + +option go_package = "github.com/archway-network/archway/x/oracle/types"; + +// Msg defines the oracle Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // AggregateExchangeRatePrevote defines a method for submitting + // aggregate exchange rate prevote + rpc AggregateExchangeRatePrevote(MsgAggregateExchangeRatePrevote) + returns (MsgAggregateExchangeRatePrevoteResponse) { + option (google.api.http).post = "/archway/oracle/prevote"; + } + + // AggregateExchangeRateVote defines a method for submitting + // aggregate exchange rate vote + rpc AggregateExchangeRateVote(MsgAggregateExchangeRateVote) + returns (MsgAggregateExchangeRateVoteResponse) { + option (google.api.http).post = "/archway/oracle/vote"; + } + + // DelegateFeedConsent defines a method for delegating oracle voting rights + // to another address known as a price feeder. + // See https://github.com/NibiruChain/pricefeeder. + rpc DelegateFeedConsent(MsgDelegateFeedConsent) + returns (MsgDelegateFeedConsentResponse) { + option (google.api.http).post = "/archway/oracle/feeder-delegate"; + } +} + +// MsgAggregateExchangeRatePrevote represents a message to submit +// aggregate exchange rate prevote. +message MsgAggregateExchangeRatePrevote { + option (cosmos.msg.v1.signer) = "feeder"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string hash = 1 [ (gogoproto.moretags) = "yaml:\"hash\"" ]; + // Feeder is the Bech32 address of the price feeder. A validator may + // specify multiple price feeders by delegating them consent. The validator + // address is also a valid feeder by default. + string feeder = 2 [ (gogoproto.moretags) = "yaml:\"feeder\"" ]; + // Validator is the Bech32 address to which the prevote will be credited. + string validator = 3 [ (gogoproto.moretags) = "yaml:\"validator\"" ]; +} + +// MsgAggregateExchangeRatePrevoteResponse defines the +// Msg/AggregateExchangeRatePrevote response type. +message MsgAggregateExchangeRatePrevoteResponse {} + +// MsgAggregateExchangeRateVote represents a message to submit +// aggregate exchange rate vote. +message MsgAggregateExchangeRateVote { + option (cosmos.msg.v1.signer) = "feeder"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string salt = 1 [ (gogoproto.moretags) = "yaml:\"salt\"" ]; + string exchange_rates = 2 + [ (gogoproto.moretags) = "yaml:\"exchange_rates\"" ]; + // Feeder is the Bech32 address of the price feeder. A validator may + // specify multiple price feeders by delegating them consent. The validator + // address is also a valid feeder by default. + string feeder = 3 [ (gogoproto.moretags) = "yaml:\"feeder\"" ]; + // Validator is the Bech32 address to which the vote will be credited. + string validator = 4 [ (gogoproto.moretags) = "yaml:\"validator\"" ]; +} + +// MsgAggregateExchangeRateVoteResponse defines the +// Msg/AggregateExchangeRateVote response type. +message MsgAggregateExchangeRateVoteResponse {} + +// MsgDelegateFeedConsent represents a message to delegate oracle voting rights +// to another address. +message MsgDelegateFeedConsent { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string operator = 1 [ (gogoproto.moretags) = "yaml:\"operator\"" ]; + string delegate = 2 [ (gogoproto.moretags) = "yaml:\"delegate\"" ]; +} + +// MsgDelegateFeedConsentResponse defines the Msg/DelegateFeedConsent response +// type. +message MsgDelegateFeedConsentResponse {} diff --git a/proto/archway/rewards/v1/tx.proto b/proto/archway/rewards/v1/tx.proto index 982d2669..3c914956 100644 --- a/proto/archway/rewards/v1/tx.proto +++ b/proto/archway/rewards/v1/tx.proto @@ -50,9 +50,7 @@ message MsgWithdrawRewards { option (cosmos.msg.v1.signer) = "rewards_address"; message RecordsLimit { uint64 limit = 1; } - message RecordIDs { - repeated uint64 ids = 1; - } + message RecordIDs { repeated uint64 ids = 1; } // rewards_address is the address to distribute rewards to (bech32 encoded). string rewards_address = 1; @@ -89,20 +87,23 @@ message MsgSetFlatFee { // MsgSetFlatFeeResponse is the response for Msg.SetFlatFee. message MsgSetFlatFeeResponse {} - // MsgUpdateParams is the Msg/UpdateParams request type. // // Since: archway v5 && cosmos-sdk 0.47 message MsgUpdateParams { option (cosmos.msg.v1.signer) = "authority"; - // authority is the address that controls the module (defaults to x/gov unless overwritten). + // authority is the address that controls the module (defaults to x/gov unless + // overwritten). string authority = 1; // params defines the x/rewards parameters to update. // // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "params,omitempty"]; + Params params = 2 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "params,omitempty" + ]; } // MsgUpdateParamsResponse defines the response structure for executing a diff --git a/proto/buf.lock b/proto/buf.lock index d1ea0063..0d13e67d 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -4,8 +4,8 @@ deps: - remote: buf.build owner: cosmos repository: cosmos-proto - commit: 1935555c206d4afb9e94615dfd0fad31 - digest: shake256:c74d91a3ac7ae07d579e90eee33abf9b29664047ac8816500cf22c081fec0d72d62c89ce0bebafc1f6fec7aa5315be72606717740ca95007248425102c365377 + commit: 04467658e59e44bbb22fe568206e1f70 + digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466 - remote: buf.build owner: cosmos repository: cosmos-sdk @@ -14,13 +14,13 @@ deps: - remote: buf.build owner: cosmos repository: gogo-proto - commit: 5e5b9fdd01804356895f8f79a6f1ddc1 - digest: shake256:0b85da49e2e5f9ebc4806eae058e2f56096ff3b1c59d1fb7c190413dd15f45dd456f0b69ced9059341c80795d2b6c943de15b120a9e0308b499e43e4b5fc2952 + commit: 88ef6483f90f478fb938c37dde52ece3 + digest: shake256:89c45df2aa11e0cff97b0d695436713db3d993d76792e9f8dc1ae90e6ab9a9bec55503d48ceedd6b86069ab07d3041b32001b2bfe0227fa725dd515ff381e5ba - remote: buf.build owner: cosmos repository: ibc - commit: fbb44f5ad3194450af479a615fa715d9 - digest: shake256:3fbf41c96089017ebf3b5143f78de0d531f604cb11da1bc98b2104eb6dd295b8a49f5f35c60b8389ba50bfa08959da905109324099e75ece9afd8e4087b14019 + commit: 6b221c7d310545198c1dafe70287d254 + digest: shake256:c5ea4d89af1c47f4d02057892eacdcb863359178079d9599f30d853b374fe9e9bfb3d9ca6720361c3439999a885a4f87fff4cd41c6c26b1f1142d60c386f8323 - remote: buf.build owner: cosmos repository: ics23 @@ -29,5 +29,5 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - commit: 28151c0d0a1641bf938a7672c500e01d - digest: shake256:49215edf8ef57f7863004539deff8834cfb2195113f0b890dd1f67815d9353e28e668019165b9d872395871eeafcbab3ccfdb2b5f11734d3cca95be9e8d139de + commit: c0913f24652a4cfc95f77d97443a5005 + digest: shake256:0ef3248c6235d420fe61f373154adcde6b94e3297f82472b1d8d8c3747240b61b4a10405e2a6f8ac1c98816ac6e690ea7871024aa5ae0e035cd540214667ceed diff --git a/proto/buf.yaml b/proto/buf.yaml index 34639bae..13f1ea4c 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -2,8 +2,9 @@ version: v1 name: buf.build/archway-network/archway deps: - buf.build/cosmos/gogo-proto + - buf.build/cosmos/cosmos-proto - buf.build/cosmos/cosmos-sdk:v0.50.0 - - buf.build/cosmos/ibc:fbb44f5ad3194450af479a615fa715d9 + - buf.build/cosmos/ibc:6b221c7d310545198c1dafe70287d254 - buf.build/googleapis/googleapis - buf.build/cosmos/ics23:b1abd8678aab07165efd453c96796a179eb3131f breaking: diff --git a/scripts/localnet.sh b/scripts/localnet.sh index f144248b..f81585ca 100755 --- a/scripts/localnet.sh +++ b/scripts/localnet.sh @@ -21,17 +21,13 @@ echo_success () { } # Set localnet settings -if [[ -f "build/archwayd" ]] ;then - BINARY=build/archwayd - # Console log text colour - red=`tput setaf 9` - green=`tput setaf 10` - blue=`tput setaf 12` - reset=`tput sgr0` -else - BINARY=archwayd -fi -CHAIN_ID=localnet-1 +BINARY=build/archwayd +# Console log text colour +red=`tput setaf 9` +green=`tput setaf 10` +blue=`tput setaf 12` +reset=`tput sgr0` +CHAIN_ID=archway-localnet-1 CHAIN_DIR=./data VALIDATOR_MNEMONIC="guard cream sadness conduct invite crumble clock pudding hole grit liar hotel maid produce squeeze return argue turtle know drive eight casino maze host" DEVELOPER_MNEMONIC="friend excite rough reopen cover wheel spoon convince island path clean monkey play snow number walnut pull lock shoot hurry dream divide concert discover" @@ -82,24 +78,28 @@ setup_chain () { # reduce deposit period to 20seconds contents="$(jq '.app_state.gov.params.max_deposit_period = "20s"' $genesis)" && echo "${contents}" > $genesis echo_info "Set x/gov proposal max deposit period to 20 seconds" + contents="$(jq '.app_state.oracle.params.min_voters = "1"' $genesis)" && echo "${contents}" > $genesis + echo_info "Set x/oracle min_voters to 1" + $BINARY config set client keyring-backend test --home $CHAIN_DIR/$CHAIN_ID + $BINARY config set client chain-id $CHAIN_ID --home $CHAIN_DIR/$CHAIN_ID # Adding users echo_info "Adding genesis accounts..." echo_info "1. validator" - echo $VALIDATOR_MNEMONIC | $BINARY --home $CHAIN_DIR/$CHAIN_ID keys add validator --recover --keyring-backend test - $BINARY --home $CHAIN_DIR/$CHAIN_ID genesis add-genesis-account $($BINARY --home $CHAIN_DIR/$CHAIN_ID keys show validator --keyring-backend test -a) $GENESIS_COINS + echo $VALIDATOR_MNEMONIC | $BINARY --home $CHAIN_DIR/$CHAIN_ID keys add validator --recover + $BINARY --home $CHAIN_DIR/$CHAIN_ID genesis add-genesis-account $($BINARY --home $CHAIN_DIR/$CHAIN_ID keys show validator -a) $GENESIS_COINS echo_info "2. developer" - echo $DEVELOPER_MNEMONIC | $BINARY --home $CHAIN_DIR/$CHAIN_ID keys add developer --recover --keyring-backend test - $BINARY --home $CHAIN_DIR/$CHAIN_ID genesis add-genesis-account $($BINARY --home $CHAIN_DIR/$CHAIN_ID keys show developer --keyring-backend test -a) $GENESIS_COINS + echo $DEVELOPER_MNEMONIC | $BINARY --home $CHAIN_DIR/$CHAIN_ID keys add developer --recover + $BINARY --home $CHAIN_DIR/$CHAIN_ID genesis add-genesis-account $($BINARY --home $CHAIN_DIR/$CHAIN_ID keys show developer -a) $GENESIS_COINS echo_info "3. user" - echo $USER_MNEMONIC | $BINARY --home $CHAIN_DIR/$CHAIN_ID keys add user --recover --keyring-backend test - $BINARY --home $CHAIN_DIR/$CHAIN_ID genesis add-genesis-account $($BINARY --home $CHAIN_DIR/$CHAIN_ID keys show user --keyring-backend test -a) $GENESIS_COINS + echo $USER_MNEMONIC | $BINARY --home $CHAIN_DIR/$CHAIN_ID keys add user --recover + $BINARY --home $CHAIN_DIR/$CHAIN_ID genesis add-genesis-account $($BINARY --home $CHAIN_DIR/$CHAIN_ID keys show user -a) $GENESIS_COINS # Creating gentx echo_info "Creating gentx for validator..." - $BINARY --home $CHAIN_DIR/$CHAIN_ID genesis gentx validator 100000000000000000000000stake --chain-id $CHAIN_ID --fees 950000000000000000000stake --keyring-backend test + $BINARY --home $CHAIN_DIR/$CHAIN_ID genesis gentx validator 100000000000000000000000stake --chain-id $CHAIN_ID --fees 950000000000000000000stake # Collecting gentx diff --git a/types/codec/codec.go b/types/codec/codec.go new file mode 100644 index 00000000..3726162e --- /dev/null +++ b/types/codec/codec.go @@ -0,0 +1,105 @@ +package codec + +import ( + "fmt" + "time" + + collcodec "cosmossdk.io/collections/codec" + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var ( + DecValueEncoder collcodec.KeyCodec[math.LegacyDec] = decValueEncoder{} + TimeKeyEncoder collcodec.KeyCodec[time.Time] = timeKeyEncoder{} +) + +func HumanizeBytes(bz []byte) string { + return fmt.Sprintf("\nbytesAsHex: %x", bz) +} + +// Collection Codecs + +// math.LegacyDec + +type decValueEncoder struct{} + +func (decValueEncoder) Stringify(value math.LegacyDec) string { + return value.String() +} +func (decValueEncoder) Encode(buffer []byte, value math.LegacyDec) (int, error) { + b, err := value.Marshal() + copy(buffer, b) + return len(b), err +} +func (decValueEncoder) Decode(b []byte) (int, math.LegacyDec, error) { + dec := new(math.LegacyDec) + err := dec.Unmarshal(b) + return len(b), *dec, err +} +func (decValueEncoder) EncodeJSON(value math.LegacyDec) ([]byte, error) { + b, err := value.MarshalJSON() + return b, err +} +func (decValueEncoder) DecodeJSON(b []byte) (math.LegacyDec, error) { + dec := new(math.LegacyDec) + err := dec.UnmarshalJSON(b) + return *dec, err +} +func (dve decValueEncoder) EncodeNonTerminal(buffer []byte, key math.LegacyDec) (int, error) { + return dve.Encode(buffer, key) +} +func (dve decValueEncoder) DecodeNonTerminal(buffer []byte) (int, math.LegacyDec, error) { + return dve.Decode(buffer) +} +func (decValueEncoder) Size(key math.LegacyDec) int { + b, _ := key.Marshal() + return len(b) +} +func (tke decValueEncoder) SizeNonTerminal(key math.LegacyDec) int { + return tke.Size(key) +} +func (d decValueEncoder) KeyType() string { + return "math.LegacyDec" +} + +// std.time.Time + +type timeKeyEncoder struct{} + +func (timeKeyEncoder) Stringify(t time.Time) string { + return t.String() +} +func (timeKeyEncoder) Encode(buffer []byte, t time.Time) (int, error) { + buf := sdk.FormatTimeBytes(t) + copy(buffer, buf) + return len(buf), nil +} +func (timeKeyEncoder) Decode(b []byte) (int, time.Time, error) { + t, err := sdk.ParseTimeBytes(b) + return len(b), t, err +} +func (timeKeyEncoder) EncodeJSON(value time.Time) ([]byte, error) { + return value.MarshalJSON() +} +func (tke timeKeyEncoder) DecodeJSON(b []byte) (time.Time, error) { + t := new(time.Time) + err := t.UnmarshalJSON(b) + return *t, err +} +func (tke timeKeyEncoder) EncodeNonTerminal(buffer []byte, key time.Time) (int, error) { + return tke.Encode(buffer, key) +} +func (tke timeKeyEncoder) DecodeNonTerminal(buffer []byte) (int, time.Time, error) { + return tke.Decode(buffer) +} +func (timeKeyEncoder) Size(key time.Time) int { + return len(sdk.FormatTimeString(key)) +} +func (timeKeyEncoder) KeyType() string { + return "archway.timeKeyEncoder" +} +func (tke timeKeyEncoder) SizeNonTerminal(key time.Time) int { + return tke.Size(key) +} diff --git a/types/codec/codec_test.go b/types/codec/codec_test.go new file mode 100644 index 00000000..fa9e9783 --- /dev/null +++ b/types/codec/codec_test.go @@ -0,0 +1,32 @@ +package codec + +import ( + "testing" + "time" + + collcodec "cosmossdk.io/collections/codec" + "github.com/stretchr/testify/require" +) + +func assertBijective[T any](t *testing.T, encoder collcodec.KeyCodec[T], key T) { + size := encoder.Size(key) + encodedKey := make([]byte, size) + + write, err := encoder.Encode(encodedKey, key) + require.NoError(t, err) + + read, decodedKey, err := encoder.Decode(encodedKey) + require.NoError(t, err) + + require.Equal(t, write, size, "write bytes do not match the size") + require.Equal(t, read, size, "read bytes do not match the size") + require.Equal(t, len(encodedKey), size, "encoded key does not match the size") + require.Equal(t, key, decodedKey, "encoding and decoding produces different keys") +} + +func TestTimeKey(t *testing.T) { + t.Run("bijective", func(t *testing.T) { + key := time.Now() + assertBijective[time.Time](t, TimeKeyEncoder, key.Round(0).UTC()) + }) +} diff --git a/types/errors/error.go b/types/errors/error.go new file mode 100644 index 00000000..9a98628b --- /dev/null +++ b/types/errors/error.go @@ -0,0 +1,197 @@ +package errors + +import ( + "errors" + "fmt" + "runtime/debug" + + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" +) + +// TryCatch is an implementation of the try-catch block from languages like C++ and JS. +// given a 'callback' function, TryCatch defers and recovers from any panics or +// errors, allowing one to safely handle multiple panics in succession. +// +// Typically, you'll write something like: `err := TryCatch(aRiskyFunction)()` +// +// Usage example: +// +// var calmPanic error = TryCatch(func() { +// panic("something crazy") +// })() +// fmt.Println(calmPanic.Error()) // prints "something crazy" +// +// Note that TryCatch doesn't return an error. It returns a function that returns +// an error. Only when you call the output of TryCatch will it "feel" like a +// try-catch block from other languages. +// +// This means that TryCatch can be used to restart go routines that panic as well. +func TryCatch(callback func()) func() error { + return func() (err error) { + defer func() { + if panicInfo := recover(); panicInfo != nil { + err = fmt.Errorf("%v, %s", panicInfo, string(debug.Stack())) + return + } + }() + callback() // calling the decorated function + return err + } +} + +// ToError converts a value to an error type if it: +// (1) is a string, +// (2) has a String() function +// (3) is already an error. +// (4) or is a slice of these cases +// I.e., the types supported are: +// string, []string, error, []error, fmt.Stringer, []fmt.Stringer +// +// The type is inferred from try catch blocks at runtime. +func ToError(v any) (out error, ok bool) { + if v == nil { + return nil, true + } + switch v := v.(type) { + case string: + return errors.New(v), true + case error: + return v, true + case fmt.Stringer: + return errors.New(v.String()), true + case []string: + return toErrorFromSlice(v) + case []error: + return toErrorFromSlice(v) + case []fmt.Stringer: + return toErrorFromSlice(v) + default: + // Cases for duck typing at runtime + + // case: error + if tcErr := TryCatch(func() { + v := v.(error) + out = errors.New(v.Error()) + })(); tcErr == nil { + return out, true + } + + // case: string + if tcErr := TryCatch(func() { + v := v.(string) + out = errors.New(v) + })(); tcErr == nil { + return out, true + } + + // case: fmt.Stringer (object with String method) + if tcErr := TryCatch(func() { + v := v.(fmt.Stringer) + out = errors.New(v.String()) + })(); tcErr == nil { + return out, true + } + + // case: []string + if tcErr := TryCatch(func() { + if maybeOut, okLocal := ToError(v.([]string)); okLocal { + out = maybeOut + } + })(); tcErr == nil { + return out, true + } + + // case: []error + if tcErr := TryCatch(func() { + if maybeOut, okLocal := ToError(v.([]error)); okLocal { + out = maybeOut + } + })(); tcErr == nil { + return out, true + } + + // case: []fmt.Stringer + if tcErr := TryCatch(func() { + if maybeOut, okLocal := ToError(v.([]fmt.Stringer)); okLocal { + out = maybeOut + } + })(); tcErr == nil { + return out, true + } + + return fmt.Errorf("invalid type: %T", v), false + } +} + +func toErrorFromSlice(slice any) (out error, ok bool) { + switch slice := slice.(type) { + case []string: + var errs []error + for _, str := range slice { + if err, okLocal := ToError(str); okLocal { + errs = append(errs, err) + } else { + return err, false + } + } + return CombineErrors(errs...), true + case []error: + return CombineErrors(slice...), true + case []fmt.Stringer: + var errs []error + for _, stringer := range slice { + if err, okLocal := ToError(stringer.String()); okLocal { + errs = append(errs, err) + } else { + return err, false + } + } + return CombineErrors(errs...), true + } + return nil, false +} + +// Combines errors into single error. Error descriptions are ordered the same way +// they're passed to the function. +func CombineErrors(errs ...error) (outErr error) { + for _, e := range errs { + switch { + case e != nil && outErr == nil: + outErr = e + case e != nil && outErr != nil: + outErr = fmt.Errorf("%s: %s", outErr, e) + } + } + return outErr +} + +func CombineErrorsGeneric(errAnySlice any) (out error, ok bool) { + err, ok := ToError(errAnySlice) + if ok { + return err, true + } else { + return err, false + } +} + +func CombineErrorsFromStrings(strs ...string) (err error) { + var errs []error + for _, s := range strs { + err, _ := ToError(s) + errs = append(errs, err) + } + return CombineErrors(errs...) +} + +func ErrNilGrpcMsg() error { + return grpcstatus.Errorf(grpccodes.InvalidArgument, "nil msg") +} + +// ErrNotImplemented: Represents an function error value. +func ErrNotImplemented() error { return fmt.Errorf("fn not implemented yet") } + +// ErrNotImplementedGprc: Represents an unimplemented gRPC method. +func ErrNotImplementedGprc() error { + return grpcstatus.Error(grpccodes.Unimplemented, ErrNotImplemented().Error()) +} diff --git a/types/errors/error_test.go b/types/errors/error_test.go new file mode 100644 index 00000000..eb1565a5 --- /dev/null +++ b/types/errors/error_test.go @@ -0,0 +1,186 @@ +package errors + +import ( + "errors" + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" +) + +func newErrors(strs ...string) []error { + var errs []error + for _, s := range strs { + errs = append(errs, errors.New(s)) + } + return errs +} + +func TestCombineErrors(t *testing.T) { + testCases := []struct { + name string + errs []error + errOut error + }{ + {name: "single nil remains nil", errs: []error{nil}, errOut: nil}, + {name: "multiple nil becomes nil", errs: []error{nil, nil, nil}, errOut: nil}, + {name: "single err unaffected", errs: newErrors("err0"), errOut: errors.New("err0")}, + { + name: "multiple err coalesces - A", + errs: newErrors("err0", "err1"), + errOut: errors.New("err0: err1"), + }, + { + name: "multiple err coalesces - B", + errs: newErrors("err0", "err1", "err2", "foobar"), + errOut: errors.New(strings.Join([]string{"err0", "err1", "err2", "foobar"}, ": ")), + }, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + errOut := CombineErrors(tc.errs...) + assert.EqualValuesf(t, tc.errOut, errOut, + "tc.errOut: %s\nerrOut: %s", tc.errOut, errOut) + }) + } +} + +func TestCombineErrorsGeneric(t *testing.T) { + testCases := []struct { + name string + in any + out error + fail bool + }{ + // cases: error + {name: "type=err | single err unaffected", in: errors.New("err0"), out: errors.New("err0")}, + {name: "type=err | single nil remains nil", in: nil, out: nil}, + + // cases: []error + {name: "type=err | single nil remains nil", in: []error{nil}, out: nil}, + {name: "multiple nil becomes nil", in: []error{nil, nil, nil}, out: nil}, + { + name: "multiple err coalesces - A", + in: newErrors("err0", "err1"), + out: errors.New("err0: err1"), + }, + { + name: "multiple err coalesces - B", + in: newErrors("err0", "err1", "err2", "foobar"), + out: errors.New(strings.Join([]string{"err0", "err1", "err2", "foobar"}, ": ")), + }, + + // cases: string + {name: "type=string | empty string", in: "", out: errors.New("")}, + {name: "type=string | happy string", in: "happy", out: errors.New("happy")}, + + // cases: []string + {name: "type=[]string | empty string", in: []string{""}, out: errors.New("")}, + {name: "type=[]string | empty strings", in: []string{"", ""}, out: errors.New(": ")}, + {name: "type=[]string | mixed", in: []string{"", "abc", ""}, out: errors.New(": abc: ")}, + + // cases: fmt.Stringer + {name: "type=fmt.Stringer |", in: asset.Registry.Pair(denoms.USDC, denoms.NUSD), out: errors.New("uusdc:unusd")}, + + // cases: []fmt.Stringer + { + name: "type=[]fmt.Stringer | happy", + in: []fmt.Stringer{asset.Registry.Pair(denoms.BTC, denoms.NUSD), asset.Registry.Pair(denoms.ETH, denoms.NUSD)}, + out: errors.New("ubtc:unusd: ueth:unusd"), + }, + {name: "type=[]fmt.Stringer | empty", in: []fmt.Stringer{}, out: nil}, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + out, ok := CombineErrorsGeneric(tc.in) + if tc.fail { + assert.Falsef(t, ok, "out: %v", out) + } else { + assert.EqualValuesf(t, tc.out, out, + "tc.errOut: %s\nerrOut: %s", tc.out, out) + assert.True(t, ok) + } + }) + } +} + +func TestToError(t *testing.T) { + testCases := []struct { + Name string + Test func() + }{ + { + Name: "string nonempty", + Test: func() { + description := "an error description" + out, ok := ToError(description) + assert.True(t, ok) + assert.EqualValues(t, out.Error(), description) + }, + }, + { + Name: "error nonempty", + Test: func() { + description := "an error description" + out, ok := ToError(errors.New(description)) + assert.True(t, ok) + assert.EqualValues(t, out.Error(), description) + }, + }, + { + Name: "empty string creates blank error", + Test: func() { + description := "" + out, ok := ToError("") + assert.True(t, ok) + assert.EqualValues(t, out.Error(), description) + }, + }, + { + Name: "fail - bad type", + Test: func() { + descriptionOfBadType := int64(2200) + _, ok := ToError(descriptionOfBadType) + assert.False(t, ok) + }, + }, + { + Name: "nil input returns nil", + Test: func() { + err, ok := ToError(nil) + assert.True(t, ok) + assert.Equal(t, nil, err) + }, + }, + { + Name: "slice of strings", + Test: func() { + err, ok := ToError([]string{"abc", "123"}) + assert.True(t, ok) + assert.Equal(t, errors.New("abc: 123"), err) + }, + }, + { + Name: "slice of error", + Test: func() { + err, ok := ToError(newErrors("abc", "123")) + assert.True(t, ok) + assert.Equal(t, errors.New("abc: 123"), err) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + tc.Test() + }) + } +} diff --git a/types/math/dec.go b/types/math/dec.go new file mode 100644 index 00000000..6961947e --- /dev/null +++ b/types/math/dec.go @@ -0,0 +1,191 @@ +package math + +import ( + "fmt" + "math/big" + "strings" + + "cosmossdk.io/math" + + "github.com/archway-network/archway/types/errors" +) + +const ( + // number of decimal places + PrecisionExponent = 18 + + // bits required to represent the above precision + // Ceiling[Log2[10^Precision - 1]] + DecimalPrecisionBits = 60 + + // decimalTruncateBits is the minimum number of bits removed + // by a truncate operation. It is equal to + // Floor[Log2[10^Precision - 1]]. + decimalTruncateBits = DecimalPrecisionBits - 1 + maxBitLen = 256 + MaxDecBitLen = maxBitLen + decimalTruncateBits +) + +var ( + // precisionInt: 10 ** PrecisionExponent + precisionInt = new(big.Int).Exp(big.NewInt(10), big.NewInt(PrecisionExponent), nil) + // halfPrecisionInt: (10 ** PrecisionExponent) / 2 + halfPrecisionInt = new(big.Int).Quo(precisionInt, big.NewInt(2)) + oneInt = big.NewInt(1) +) + +// MustSqrtDec computes the square root of the input decimal using its +// underlying big.Int. The big.Int.Sqrt method is part of the standard library, +// thoroughly tested, works at seemingly unbound precision (e.g. for numbers as +// large as 10**99. +// - NOTE, MustSqrtDec panics if it is called on a negative number, similar to the +// sdk.NewCoin and SqrtBigInt functions. A panic safe version of MustSqrtDec +// is available in the SqrtDec method. +func MustSqrtDec(dec math.LegacyDec) math.LegacyDec { + sqrtBigInt := MustSqrtBigInt(dec.BigInt()) + precision := math.LegacyNewDecFromBigInt(PRECISION_MULT) + return math.LegacyNewDecFromBigInt(sqrtBigInt).Quo(precision) +} + +// SqrtDec computes the square root of the input decimal using its +// underlying big.Int. SqrtDec is panic-safe and returns an error if the input +// decimal is negative. +// +// The big.Int.Sqrt method is part of the standard library, +// thoroughly tested, works at seemingly unbound precision (e.g. for numbers as +// large as 10**99. +func SqrtDec(dec math.LegacyDec) (math.LegacyDec, error) { + var sqrtDec math.LegacyDec + var panicErr error = errors.TryCatch(func() { + sqrtDec = MustSqrtDec(dec) + })() + return sqrtDec, panicErr +} + +// MustSqrtBigInt returns the square root of the input. +// - NOTE: MustSqrtBigInt panics if it is called on a negative number because it uses +// the `big.Int.Sqrt` from the "math/big" package. +func MustSqrtBigInt(i *big.Int) *big.Int { + sqrtInt := &big.Int{} + return sqrtInt.Sqrt(i) +} + +// SqrtInt is the panic-safe version of MustSqrtBigInt +func SqrtBigInt(i *big.Int) (*big.Int, error) { + sqrtInt := new(big.Int) + var panicErr error = errors.TryCatch(func() { + *sqrtInt = *MustSqrtBigInt(i) + })() + return sqrtInt, panicErr +} + +// BigIntPow10 returns a big int that is a power of 10, e.g. BigIngPow10(3) +// returns 1000. This function is useful for creating large numbers outside the +// range of an int64 or 18 decimal precision. +func BigIntPow10(power int64) *big.Int { + bigInt, _ := new(big.Int).SetString("1"+strings.Repeat("0", int(power)), 10) + return bigInt +} + +// ———————————————————————————————————————————————— +// Logic needed from private code in the Cosmos-SDK +// See https://github.com/cosmos/cosmos-sdk/blob/v0.45.12/types/decimal.go +// + +const ( + PRECISION = 18 +) + +var ( + PRECISION_MULT = calcPrecisionMultiplier(0) + PRECISION_SQRT = int64(PRECISION / 2) + tenInt = big.NewInt(10) +) + +// calcPrecisionMultiplier computes a multiplier needed to maintain a target +// precision defined by 10 ** (PRECISION_SQRT - prec). +// The maximum available precision is PRECISION_SQRT (9). +func calcPrecisionMultiplier(prec int64) *big.Int { + if prec > PRECISION_SQRT { + panic(fmt.Sprintf("too much precision, maximum %v, provided %v", PRECISION_SQRT, prec)) + } + zerosToAdd := PRECISION_SQRT - prec + multiplier := new(big.Int).Exp(tenInt, big.NewInt(zerosToAdd), nil) + return multiplier +} + +// ____ +// __| |__ "chop 'em +// ` \ round!" +// ___|| ~ _ -bankers +// | | __ +// | | | __|__|__ +// |_____: / | $$$ | +// |________| + +// ChopPrecisionAndRound: Remove a Precision amount of rightmost digits and +// perform bankers rounding on the remainder (gaussian rounding) on the digits +// which have been removed. +// +// Mutates the input. Use the non-mutative version if that is undesired +func ChopPrecisionAndRound(d *big.Int) *big.Int { + // remove the negative and add it back when returning + if d.Sign() == -1 { + // make d positive, compute chopped value, and then un-mutate d + d = d.Neg(d) + d = ChopPrecisionAndRound(d) + d = d.Neg(d) + return d + } + + // Divide out the 'precisionInt', which truncates to a quotient and remainder. + quo, rem := d, big.NewInt(0) + quo, rem = quo.QuoRem(d, precisionInt, rem) + + return BankersRound(quo, rem, halfPrecisionInt) +} + +// BankersRound: Banker's rounding is a method commonly used in banking and +// accounting to reduce roudning bias when processing large volumes of rounded +// numbers. +// +// 1. If the remainder < half precision, round down +// 2. If the remainder > half precision, round up +// 3. If remainder == half precision, round to the nearest even number +// +// The name comes from the idea that it provides egalitarian rounding that +// doesn't consistently favor one party over another (e.g. always rounding up). +// With this method, rounding errors tend to cancel out rather than +// accumulating in one direction. +func BankersRound(quo, rem, halfPrecision *big.Int) *big.Int { + // Zero remainder after dividing precision means => no rounding is needed. + if rem.Sign() == 0 { + return quo + } + + // Nonzero remainder after dividing precision means => do banker's rounding + switch rem.Cmp(halfPrecision) { + case -1: + return quo + case 1: + return quo.Add(quo, oneInt) + default: + // default case: bankers rounding must take place + // always round to an even number + if quo.Bit(0) == 0 { + return quo + } + return quo.Add(quo, oneInt) + } +} + +// Clamp return the value if it is within the clampValue, otherwise return the clampValue. +// e.g. Clamp(1.5, 1) = 1, Clamp(-1.5, 1) = -1, Clamp(0.5, 1) = 0.5 +func Clamp(value math.LegacyDec, clampValue math.LegacyDec) math.LegacyDec { + if value.GT(clampValue) { + return clampValue + } else if value.LT(clampValue.Neg()) { + return clampValue.Neg() + } + return value +} diff --git a/types/math/dec_test.go b/types/math/dec_test.go new file mode 100644 index 00000000..3a676beb --- /dev/null +++ b/types/math/dec_test.go @@ -0,0 +1,166 @@ +package math + +import ( + "fmt" + "math/big" + "testing" + + "cosmossdk.io/math" + + "github.com/stretchr/testify/assert" + + "github.com/archway-network/archway/types/errors" +) + +func TestSqrtBigInt(t *testing.T) { + testCases := []struct { + bigInt *big.Int + sqrtBigInt *big.Int + }{ + {bigInt: big.NewInt(1), sqrtBigInt: big.NewInt(1)}, + {bigInt: big.NewInt(4), sqrtBigInt: big.NewInt(2)}, + {bigInt: big.NewInt(250_000), sqrtBigInt: big.NewInt(500)}, + {bigInt: big.NewInt(4_819_136_400), sqrtBigInt: big.NewInt(69_420)}, + { + bigInt: new(big.Int).Mul(big.NewInt(4_819_136_400), BigIntPow10(32)), + sqrtBigInt: new(big.Int).Mul(big.NewInt(69_420), BigIntPow10(16)), + }, + { + bigInt: new(big.Int).Mul(big.NewInt(9), BigIntPow10(100)), + sqrtBigInt: new(big.Int).Mul(big.NewInt(3), BigIntPow10(50)), + }, + } + + for _, testCase := range testCases { + tc := testCase + t.Run(fmt.Sprintf(`bigInt: %s, sqrtBigInt: %s`, tc.bigInt, tc.sqrtBigInt), func(t *testing.T) { + sqrtInt, err := SqrtBigInt(tc.bigInt) + assert.NoError(t, err) + assert.Equal(t, tc.sqrtBigInt.String(), sqrtInt.String()) + }) + } +} + +func TestSqrtDec(t *testing.T) { + testCases := []struct { + dec math.LegacyDec + sqrtDec math.LegacyDec + }{ + // -------------------------------------------------------------------- + // Cases: 1 or higher + {dec: math.LegacyOneDec(), sqrtDec: math.LegacyOneDec()}, + {dec: math.LegacyNewDec(4), sqrtDec: math.LegacyNewDec(2)}, + {dec: math.LegacyNewDec(250_000), sqrtDec: math.LegacyNewDec(500)}, + {dec: math.LegacyNewDec(4_819_136_400), sqrtDec: math.LegacyNewDec(69_420)}, + + // -------------------------------------------------------------------- + // Cases: Between 0 and 1 + {dec: math.LegacyMustNewDecFromStr("0.81"), sqrtDec: math.LegacyMustNewDecFromStr("0.9")}, + {dec: math.LegacyMustNewDecFromStr("0.25"), sqrtDec: math.LegacyMustNewDecFromStr("0.5")}, + // ↓ dec 1e-12, sqrtDec: 1e-6 + {dec: math.LegacyMustNewDecFromStr("0.000000000001"), sqrtDec: math.LegacyMustNewDecFromStr("0.000001")}, + + // -------------------------------------------------------------------- + // The math/big library panics if you call sqrt() on a negative number. + } + + t.Run("negative sqrt should panic", func(t *testing.T) { + panicString := errors.TryCatch(func() { + MustSqrtDec(math.LegacyNewDec(-9)) + })().Error() + + assert.Contains(t, panicString, "square root of negative number") + }) + + for _, testCase := range testCases { + tc := testCase + t.Run(fmt.Sprintf(`dec: %s, sqrtDec: %s`, tc.dec, tc.sqrtDec), func(t *testing.T) { + sqrtDec, err := SqrtDec(tc.dec) + assert.NoError(t, err) + assert.Equal(t, tc.sqrtDec.String(), sqrtDec.String()) + }) + } +} + +func TestBankersRound(t *testing.T) { + quo := big.NewInt(56789) + halfPrecision := big.NewInt(50000) + + testCases := []struct { + name string + quo *big.Int + rem *big.Int + rounded *big.Int + }{ + { + name: "Remainder < half precision => round down", + rem: big.NewInt(49_999), + rounded: quo, + }, + { + name: "Remainder > half precision => round up", + rem: big.NewInt(50_001), + rounded: big.NewInt(56_790), // = quo + 1 + }, + { + name: "Remainder = half precision, quotient is odd => round up", + rem: halfPrecision, + rounded: big.NewInt(56_742), + quo: big.NewInt(56_741), + }, + { + name: "Remainder = half precision, quotient is even => no change", + rem: halfPrecision, + rounded: quo, + }, + { + name: "Remainder = 0 => no change", + rem: big.NewInt(0), + rounded: quo, + }, + } + + for _, tc := range testCases { + tcQuo := quo + if tc.quo != nil { + tcQuo = tc.quo + } + rounded := BankersRound(tcQuo, tc.rem, halfPrecision) + assert.EqualValues(t, tc.rounded, rounded) + } +} + +func TestClamp(t *testing.T) { + tests := []struct { + value math.LegacyDec + clampValue math.LegacyDec + expected math.LegacyDec + description string + }{ + { + value: math.LegacyNewDec(15), + clampValue: math.LegacyNewDec(1), + expected: math.LegacyNewDec(1), + description: "Clamping 15 to 1", + }, + { + value: math.LegacyNewDec(-15), + clampValue: math.LegacyNewDec(1), + expected: math.LegacyNewDec(-1), + description: "Clamping -15 to 1", + }, + { + value: math.LegacyMustNewDecFromStr("0.5"), + clampValue: math.LegacyNewDec(1), + expected: math.LegacyMustNewDecFromStr("0.5"), + description: "Clamping 0.5 to 1", + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + result := Clamp(tt.value, tt.clampValue) + assert.Equal(t, tt.expected, result) + }) + } +} diff --git a/types/set/set.go b/types/set/set.go new file mode 100644 index 00000000..6b05a905 --- /dev/null +++ b/types/set/set.go @@ -0,0 +1,36 @@ +package set + +type Set[T comparable] map[T]struct{} + +func (set Set[T]) Add(s T) { + set[s] = struct{}{} +} + +func (set Set[T]) Remove(s T) { + delete(set, s) +} + +func (set Set[T]) Has(s T) bool { + _, ok := set[s] + return ok +} + +func (set Set[T]) Len() int { + return len(set.ToSlice()) +} + +func (set Set[T]) ToSlice() []T { + var slice []T + for s := range set { + slice = append(slice, s) + } + return slice +} + +func New[T comparable](strs ...T) Set[T] { + set := Set[T]{} + for _, s := range strs { + set.Add(s) + } + return set +} diff --git a/types/set/set_test.go b/types/set/set_test.go new file mode 100644 index 00000000..f2665b98 --- /dev/null +++ b/types/set/set_test.go @@ -0,0 +1,58 @@ +package set + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +var elementSlice = []string{"fire", "earth", "water", "air"} + +func TestAdd(t *testing.T) { + elements := New(elementSlice...) + + assert.False(t, elements.Has("lava")) + assert.False(t, elements.Has("mud")) + + elements.Add("lava") + elements.Add("mud") + assert.True(t, elements.Has("lava")) + assert.True(t, elements.Has("mud")) + + assert.Equal(t, 6, elements.Len()) + + // Add blank string + elements.Add("") + assert.True(t, elements.Has("")) + assert.Equal(t, 7, elements.Len()) +} + +func TestRemove(t *testing.T) { + elements := New(elementSlice...) + elem := "water" + assert.True(t, elements.Has(elem)) + + elements.Remove(elem) + assert.False(t, elements.Has(elem)) +} + +func TestHas(t *testing.T) { + elements := New(elementSlice...) + + assert.True(t, elements.Has("fire")) + assert.True(t, elements.Has("water")) + assert.True(t, elements.Has("air")) + assert.True(t, elements.Has("earth")) + assert.False(t, elements.Has("")) + assert.False(t, elements.Has("foo")) + assert.False(t, elements.Has("bar")) +} + +func TestLen(t *testing.T) { + elements := New(elementSlice...) + assert.Equal(t, elements.Len(), 4) + + elements.Remove("fire") + elements.Remove("water") + assert.Equal(t, elements.Len(), 2) +} diff --git a/x/callback/types/callback.pb.go b/x/callback/types/callback.pb.go index 38f8ceee..1c1a6fa7 100644 --- a/x/callback/types/callback.pb.go +++ b/x/callback/types/callback.pb.go @@ -29,17 +29,21 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Callback defines the callback structure. type Callback struct { - // contract_address is the address of the contract which is requesting the callback (bech32 encoded). + // contract_address is the address of the contract which is requesting the + // callback (bech32 encoded). ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - // job_id is an identifier the callback requestor can pass in to identify the callback when it happens. + // job_id is an identifier the callback requestor can pass in to identify the + // callback when it happens. JobId uint64 `protobuf:"varint,2,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` // callback_height is the height at which the callback is executed. CallbackHeight int64 `protobuf:"varint,3,opt,name=callback_height,json=callbackHeight,proto3" json:"callback_height,omitempty"` - // fee_split is the breakdown of the fees paid by the contract to reserve the callback + // fee_split is the breakdown of the fees paid by the contract to reserve the + // callback FeeSplit *CallbackFeesFeeSplit `protobuf:"bytes,4,opt,name=fee_split,json=feeSplit,proto3" json:"fee_split,omitempty"` // reserved_by is the address which reserved the callback (bech32 encoded). ReservedBy string `protobuf:"bytes,5,opt,name=reserved_by,json=reservedBy,proto3" json:"reserved_by,omitempty"` - // callback_gas_limit is the maximum gas that can be consumed by this callback. + // callback_gas_limit is the maximum gas that can be consumed by this + // callback. MaxGasLimit uint64 `protobuf:"varint,6,opt,name=max_gas_limit,json=maxGasLimit,proto3" json:"max_gas_limit,omitempty"` } @@ -118,15 +122,20 @@ func (m *Callback) GetMaxGasLimit() uint64 { return 0 } -// CallbackFeesFeeSplit is the breakdown of all the fees that need to be paid by the contract to reserve a callback +// CallbackFeesFeeSplit is the breakdown of all the fees that need to be paid by +// the contract to reserve a callback type CallbackFeesFeeSplit struct { - // transaction_fees is the transaction fees for the callback based on its gas consumption + // transaction_fees is the transaction fees for the callback based on its gas + // consumption TransactionFees *types.Coin `protobuf:"bytes,1,opt,name=transaction_fees,json=transactionFees,proto3" json:"transaction_fees,omitempty"` - // block_reservation_fees is the block reservation fees portion of the callback reservation fees + // block_reservation_fees is the block reservation fees portion of the + // callback reservation fees BlockReservationFees *types.Coin `protobuf:"bytes,2,opt,name=block_reservation_fees,json=blockReservationFees,proto3" json:"block_reservation_fees,omitempty"` - // future_reservation_fees is the future reservation fees portion of the callback reservation fees + // future_reservation_fees is the future reservation fees portion of the + // callback reservation fees FutureReservationFees *types.Coin `protobuf:"bytes,3,opt,name=future_reservation_fees,json=futureReservationFees,proto3" json:"future_reservation_fees,omitempty"` - // surplus_fees is any extra fees passed in for the registration of the callback + // surplus_fees is any extra fees passed in for the registration of the + // callback SurplusFees *types.Coin `protobuf:"bytes,4,opt,name=surplus_fees,json=surplusFees,proto3" json:"surplus_fees,omitempty"` } @@ -195,13 +204,17 @@ func (m *CallbackFeesFeeSplit) GetSurplusFees() *types.Coin { type Params struct { // callback_gas_limit is the maximum gas that can be consumed by a callback. CallbackGasLimit uint64 `protobuf:"varint,1,opt,name=callback_gas_limit,json=callbackGasLimit,proto3" json:"callback_gas_limit,omitempty"` - // max_block_reservation_limit is the maximum number of callbacks which can be registered in a given block. + // max_block_reservation_limit is the maximum number of callbacks which can be + // registered in a given block. MaxBlockReservationLimit uint64 `protobuf:"varint,2,opt,name=max_block_reservation_limit,json=maxBlockReservationLimit,proto3" json:"max_block_reservation_limit,omitempty"` - // max_future_reservation_limit is the maximum number of blocks in the future that a contract can request a callback in. + // max_future_reservation_limit is the maximum number of blocks in the future + // that a contract can request a callback in. MaxFutureReservationLimit uint64 `protobuf:"varint,3,opt,name=max_future_reservation_limit,json=maxFutureReservationLimit,proto3" json:"max_future_reservation_limit,omitempty"` - // block_reservation_fee_multiplier is used to calculate a part of the reservation fees which will need to be paid when requesting the callback. + // block_reservation_fee_multiplier is used to calculate a part of the + // reservation fees which will need to be paid when requesting the callback. BlockReservationFeeMultiplier cosmossdk_io_math.LegacyDec `protobuf:"bytes,4,opt,name=block_reservation_fee_multiplier,json=blockReservationFeeMultiplier,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"block_reservation_fee_multiplier"` - // future_reservation_fee_multiplier is used to calculate a part of the reservation fees which will need to be paid while requesting the callback. + // future_reservation_fee_multiplier is used to calculate a part of the + // reservation fees which will need to be paid while requesting the callback. FutureReservationFeeMultiplier cosmossdk_io_math.LegacyDec `protobuf:"bytes,5,opt,name=future_reservation_fee_multiplier,json=futureReservationFeeMultiplier,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"future_reservation_fee_multiplier"` } diff --git a/x/callback/types/errors.pb.go b/x/callback/types/errors.pb.go index 460b6385..92baa1e2 100644 --- a/x/callback/types/errors.pb.go +++ b/x/callback/types/errors.pb.go @@ -27,9 +27,11 @@ type ModuleErrors int32 const ( // ERR_UNKNOWN is the default error code ModuleErrors_ERR_UNKNOWN ModuleErrors = 0 - // ERR_OUT_OF_GAS is the error code when the contract callback exceeds the gas limit allowed by the module + // ERR_OUT_OF_GAS is the error code when the contract callback exceeds the gas + // limit allowed by the module ModuleErrors_ERR_OUT_OF_GAS ModuleErrors = 1 - // ERR_CONTRACT_EXECUTION_FAILED is the error code when the contract callback execution fails + // ERR_CONTRACT_EXECUTION_FAILED is the error code when the contract callback + // execution fails ModuleErrors_ERR_CONTRACT_EXECUTION_FAILED ModuleErrors = 2 ) diff --git a/x/callback/types/events.pb.go b/x/callback/types/events.pb.go index 5dd882b2..1424fdb1 100644 --- a/x/callback/types/events.pb.go +++ b/x/callback/types/events.pb.go @@ -27,13 +27,15 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // CallbackRegisteredEvent is emitted when a callback is registered. type CallbackRegisteredEvent struct { - // contract_address is the address of the contract for which callback is being registered (bech32 encoded). + // contract_address is the address of the contract for which callback is being + // registered (bech32 encoded). ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` // job_id is an identifier of the callback. JobId uint64 `protobuf:"varint,2,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` // callback_height is the height at which the callback is executed. CallbackHeight int64 `protobuf:"varint,3,opt,name=callback_height,json=callbackHeight,proto3" json:"callback_height,omitempty"` - // fee_split is the breakdown of the fees paid by the contract to reserve the callback + // fee_split is the breakdown of the fees paid by the contract to reserve the + // callback FeeSplit *CallbackFeesFeeSplit `protobuf:"bytes,4,opt,name=fee_split,json=feeSplit,proto3" json:"fee_split,omitempty"` // reserved_by is the address which reserved the callback (bech32 encoded). ReservedBy string `protobuf:"bytes,5,opt,name=reserved_by,json=reservedBy,proto3" json:"reserved_by,omitempty"` @@ -109,13 +111,16 @@ func (m *CallbackRegisteredEvent) GetReservedBy() string { // CallbackCancelledEvent is emitted when a callback is cancelled. type CallbackCancelledEvent struct { - // cancelled_by is the address of the contract whose callback is being cancelled (bech32 encoded) + // cancelled_by is the address of the contract whose callback is being + // cancelled (bech32 encoded) CancelledBy string `protobuf:"bytes,1,opt,name=cancelled_by,json=cancelledBy,proto3" json:"cancelled_by,omitempty"` // contract_address is the address of the contract (bech32 encoded) ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - // job_id is an identifier the callback requestor had passed during registration of the callback + // job_id is an identifier the callback requestor had passed during + // registration of the callback JobId uint64 `protobuf:"varint,3,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` - // callback_height is the height at which the callback requestor had registered the callback + // callback_height is the height at which the callback requestor had + // registered the callback CallbackHeight int64 `protobuf:"varint,4,opt,name=callback_height,json=callbackHeight,proto3" json:"callback_height,omitempty"` // refund_amount is the amount of fees which was refunded on cancellation RefundAmount types.Coin `protobuf:"bytes,5,opt,name=refund_amount,json=refundAmount,proto3" json:"refund_amount"` @@ -189,9 +194,11 @@ func (m *CallbackCancelledEvent) GetRefundAmount() types.Coin { return types.Coin{} } -// CallbackExecutedSuccessEvent is emitted when a callback is executed successfully. +// CallbackExecutedSuccessEvent is emitted when a callback is executed +// successfully. type CallbackExecutedSuccessEvent struct { - // contract_address is the address of the contract for which callback is being executed (bech32 encoded). + // contract_address is the address of the contract for which callback is being + // executed (bech32 encoded). ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` // job_id is an identifier of the callback. JobId uint64 `protobuf:"varint,2,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` @@ -264,7 +271,8 @@ func (m *CallbackExecutedSuccessEvent) GetGasUsed() uint64 { // CallbackExecutedFailedEvent is emitted when a callback execution fails. type CallbackExecutedFailedEvent struct { - // contract_address is the address of the contract for which callback is being executed (bech32 encoded). + // contract_address is the address of the contract for which callback is being + // executed (bech32 encoded). ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` // job_id is an identifier of the callback. JobId uint64 `protobuf:"varint,2,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` diff --git a/x/callback/types/query.pb.go b/x/callback/types/query.pb.go index 252d1979..c8b53e91 100644 --- a/x/callback/types/query.pb.go +++ b/x/callback/types/query.pb.go @@ -113,7 +113,8 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } -// QueryEstimateCallbackFeesRequest is the request for Query.EstimateCallbackFees. +// QueryEstimateCallbackFeesRequest is the request for +// Query.EstimateCallbackFees. type QueryEstimateCallbackFeesRequest struct { // block_height is the height at which to estimate the callback fees BlockHeight int64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` @@ -159,9 +160,11 @@ func (m *QueryEstimateCallbackFeesRequest) GetBlockHeight() int64 { return 0 } -// QueryEstimateCallbackFeesResponse is the response for Query.EstimateCallbackFees. +// QueryEstimateCallbackFeesResponse is the response for +// Query.EstimateCallbackFees. type QueryEstimateCallbackFeesResponse struct { - // total_fees is the total fees that needs to be paid by the contract to reserve a callback + // total_fees is the total fees that needs to be paid by the contract to + // reserve a callback TotalFees *types.Coin `protobuf:"bytes,1,opt,name=total_fees,json=totalFees,proto3" json:"total_fees,omitempty"` // fee_split is the breakdown of the total_fees FeeSplit *CallbackFeesFeeSplit `protobuf:"bytes,2,opt,name=fee_split,json=feeSplit,proto3" json:"fee_split,omitempty"` @@ -369,7 +372,8 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // Params returns module parameters Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) - // EstimateCallbackFees returns the total amount of callback fees a contract needs to pay to register the callback + // EstimateCallbackFees returns the total amount of callback fees a contract + // needs to pay to register the callback EstimateCallbackFees(ctx context.Context, in *QueryEstimateCallbackFeesRequest, opts ...grpc.CallOption) (*QueryEstimateCallbackFeesResponse, error) // Callbacks returns all the callbacks registered at a given height Callbacks(ctx context.Context, in *QueryCallbacksRequest, opts ...grpc.CallOption) (*QueryCallbacksResponse, error) @@ -414,7 +418,8 @@ func (c *queryClient) Callbacks(ctx context.Context, in *QueryCallbacksRequest, type QueryServer interface { // Params returns module parameters Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) - // EstimateCallbackFees returns the total amount of callback fees a contract needs to pay to register the callback + // EstimateCallbackFees returns the total amount of callback fees a contract + // needs to pay to register the callback EstimateCallbackFees(context.Context, *QueryEstimateCallbackFeesRequest) (*QueryEstimateCallbackFeesResponse, error) // Callbacks returns all the callbacks registered at a given height Callbacks(context.Context, *QueryCallbacksRequest) (*QueryCallbacksResponse, error) diff --git a/x/callback/types/tx.pb.go b/x/callback/types/tx.pb.go index 9594bb84..f14e66da 100644 --- a/x/callback/types/tx.pb.go +++ b/x/callback/types/tx.pb.go @@ -32,7 +32,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgUpdateParams is the Msg/UpdateParams request type. type MsgUpdateParams struct { - // authority is the address that controls the module (defaults to x/gov unless overwritten). + // authority is the address that controls the module (defaults to x/gov unless + // overwritten). Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` // params defines the x/callback parameters to update. // @@ -87,7 +88,8 @@ func (m *MsgUpdateParams) GetParams() Params { return Params{} } -// MsgUpdateParamsResponse defines the response structure for executing a MsgUpdateParams message. +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. type MsgUpdateParamsResponse struct { } @@ -128,9 +130,11 @@ var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo type MsgRequestCallback struct { // sender is the address who is requesting the callback (bech32 encoded) Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` - // contract_address is the address of the contract which is requesting the callback (bech32 encoded) + // contract_address is the address of the contract which is requesting the + // callback (bech32 encoded) ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - // job_id is an identifier the callback requestor can pass in to identify the callback when it happens + // job_id is an identifier the callback requestor can pass in to identify the + // callback when it happens JobId uint64 `protobuf:"varint,3,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` // callback_height is the height at which the callback is executed. CallbackHeight int64 `protobuf:"varint,4,opt,name=callback_height,json=callbackHeight,proto3" json:"callback_height,omitempty"` @@ -206,7 +210,8 @@ func (m *MsgRequestCallback) GetFees() types.Coin { return types.Coin{} } -// MsgRequestCallbackResponse defines the response structure for executing a MsgRequestCallback message. +// MsgRequestCallbackResponse defines the response structure for executing a +// MsgRequestCallback message. type MsgRequestCallbackResponse struct { } @@ -245,13 +250,16 @@ var xxx_messageInfo_MsgRequestCallbackResponse proto.InternalMessageInfo // MsgCancelCallback is the Msg/CancelCallback request type. type MsgCancelCallback struct { - // sender is the address of the contract which is cancelling the callback (bech32 encoded) + // sender is the address of the contract which is cancelling the callback + // (bech32 encoded) Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` // contract_address is the address of the contract (bech32 encoded) ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - // job_id is an identifier the callback requestor had passed during registration of the callback + // job_id is an identifier the callback requestor had passed during + // registration of the callback JobId uint64 `protobuf:"varint,3,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` - // callback_height is the height at which the callback requestor had registered the callback + // callback_height is the height at which the callback requestor had + // registered the callback CallbackHeight int64 `protobuf:"varint,4,opt,name=callback_height,json=callbackHeight,proto3" json:"callback_height,omitempty"` } @@ -316,9 +324,11 @@ func (m *MsgCancelCallback) GetCallbackHeight() int64 { return 0 } -// MsgCancelCallbackResponse defines the response structure for executing a MsgCancelCallback message. +// MsgCancelCallbackResponse defines the response structure for executing a +// MsgCancelCallback message. type MsgCancelCallbackResponse struct { - // refund is the amount of fees being refunded due to the cancellation of the callback + // refund is the amount of fees being refunded due to the cancellation of the + // callback Refund types.Coin `protobuf:"bytes,1,opt,name=refund,proto3" json:"refund"` } @@ -427,7 +437,8 @@ type MsgClient interface { // UpdateParams defines a governance operation for updating the x/callback // module parameters. The authority is defined in the keeper. UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) - // RequestCallback defines a message for registering a callback at a specific height by a given contract + // RequestCallback defines a message for registering a callback at a specific + // height by a given contract RequestCallback(ctx context.Context, in *MsgRequestCallback, opts ...grpc.CallOption) (*MsgRequestCallbackResponse, error) // CancelCallback defines a message for cancelling an existing callback CancelCallback(ctx context.Context, in *MsgCancelCallback, opts ...grpc.CallOption) (*MsgCancelCallbackResponse, error) @@ -473,7 +484,8 @@ type MsgServer interface { // UpdateParams defines a governance operation for updating the x/callback // module parameters. The authority is defined in the keeper. UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) - // RequestCallback defines a message for registering a callback at a specific height by a given contract + // RequestCallback defines a message for registering a callback at a specific + // height by a given contract RequestCallback(context.Context, *MsgRequestCallback) (*MsgRequestCallbackResponse, error) // CancelCallback defines a message for cancelling an existing callback CancelCallback(context.Context, *MsgCancelCallback) (*MsgCancelCallbackResponse, error) diff --git a/x/cwerrors/types/cwerrors.pb.go b/x/cwerrors/types/cwerrors.pb.go index 359a6f93..f92691aa 100644 --- a/x/cwerrors/types/cwerrors.pb.go +++ b/x/cwerrors/types/cwerrors.pb.go @@ -29,7 +29,8 @@ type ModuleErrors int32 const ( // ERR_UNKNOWN is the default error code ModuleErrors_ERR_UNKNOWN ModuleErrors = 0 - // ERR_CALLBACK_EXECUTION_FAILED is the error code for when the error callback fails + // ERR_CALLBACK_EXECUTION_FAILED is the error code for when the error callback + // fails ModuleErrors_ERR_CALLBACK_EXECUTION_FAILED ModuleErrors = 1 ) diff --git a/x/cwfees/types/cwfees.pb.go b/x/cwfees/types/cwfees.pb.go index c6dcb0dc..0ba745d8 100644 --- a/x/cwfees/types/cwfees.pb.go +++ b/x/cwfees/types/cwfees.pb.go @@ -111,7 +111,8 @@ func (m *MsgRegisterAsGranterResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgRegisterAsGranterResponse proto.InternalMessageInfo -// MsgUnregisterAsGranter can be used by a cosmwasm contract to unregister itself as a fee granter. +// MsgUnregisterAsGranter can be used by a cosmwasm contract to unregister +// itself as a fee granter. type MsgUnregisterAsGranter struct { GrantingContract string `protobuf:"bytes,1,opt,name=granting_contract,json=grantingContract,proto3" json:"granting_contract,omitempty"` } @@ -387,9 +388,11 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { - // RegisterAsGranter allows a cosmwasm contract to register itself as a fee granter. + // RegisterAsGranter allows a cosmwasm contract to register itself as a fee + // granter. RegisterAsGranter(ctx context.Context, in *MsgRegisterAsGranter, opts ...grpc.CallOption) (*MsgRegisterAsGranterResponse, error) - // UnregisterAsGranter allows a cosmwasm contract to unregister itself as a fee granter. + // UnregisterAsGranter allows a cosmwasm contract to unregister itself as a + // fee granter. UnregisterAsGranter(ctx context.Context, in *MsgUnregisterAsGranter, opts ...grpc.CallOption) (*MsgUnregisterAsGranterResponse, error) } @@ -421,9 +424,11 @@ func (c *msgClient) UnregisterAsGranter(ctx context.Context, in *MsgUnregisterAs // MsgServer is the server API for Msg service. type MsgServer interface { - // RegisterAsGranter allows a cosmwasm contract to register itself as a fee granter. + // RegisterAsGranter allows a cosmwasm contract to register itself as a fee + // granter. RegisterAsGranter(context.Context, *MsgRegisterAsGranter) (*MsgRegisterAsGranterResponse, error) - // UnregisterAsGranter allows a cosmwasm contract to unregister itself as a fee granter. + // UnregisterAsGranter allows a cosmwasm contract to unregister itself as a + // fee granter. UnregisterAsGranter(context.Context, *MsgUnregisterAsGranter) (*MsgUnregisterAsGranterResponse, error) } @@ -499,7 +504,8 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { - // IsGrantingContract can be used to check if a contract is a granting contract. + // IsGrantingContract can be used to check if a contract is a granting + // contract. IsGrantingContract(ctx context.Context, in *IsGrantingContractRequest, opts ...grpc.CallOption) (*IsGrantingContractResponse, error) } @@ -522,7 +528,8 @@ func (c *queryClient) IsGrantingContract(ctx context.Context, in *IsGrantingCont // QueryServer is the server API for Query service. type QueryServer interface { - // IsGrantingContract can be used to check if a contract is a granting contract. + // IsGrantingContract can be used to check if a contract is a granting + // contract. IsGrantingContract(context.Context, *IsGrantingContractRequest) (*IsGrantingContractResponse, error) } diff --git a/x/genmsg/types/genmsg.pb.go b/x/genmsg/types/genmsg.pb.go index 7e94afa3..2319bfce 100644 --- a/x/genmsg/types/genmsg.pb.go +++ b/x/genmsg/types/genmsg.pb.go @@ -23,7 +23,8 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// GenesisState represents the messages to be processed during genesis by the genmsg module. +// GenesisState represents the messages to be processed during genesis by the +// genmsg module. type GenesisState struct { Messages []*types.Any `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` } diff --git a/x/oracle/README.md b/x/oracle/README.md new file mode 100644 index 00000000..b92898cd --- /dev/null +++ b/x/oracle/README.md @@ -0,0 +1,330 @@ +# Oracle + +The Oracle module provides the Nibiru blockchain with an up-to-date and accurate price feed of exchange rates of trading pairs. + +As price information is extrinsic to the blockchain, the Nibiru network relies on validators to periodically vote on the current exchange rates, with the protocol tallying up the results once per `VotePeriod` and updating the on-chain exchange rate as the weighted median of the ballot. + +> Since the Oracle service is powered by validators, you may find it interesting to look at the [Staking](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec/README.md) module, which covers the logic for staking and validators. + +## Contents +- [Oracle](#oracle) + - [Concepts](#concepts) + - [Voting Procedure](#voting-procedure) + - [Reward Band](#reward-band) + - [Slashing](#slashing) + - [Abstaining from Voting](#abstaining-from-voting) + - [Messages](#messages) + - [Module Parameters](#module-parameters) + - [State](#state) + - [ExchangeRate](#exchangerate) + - [FeederDelegation](#feederdelegation) + - [MissCounter](#misscounter) + - [AggregateExchangeRatePrevote](#aggregateexchangerateprevote) + - [AggregateExchangeRateVote](#aggregateexchangeratevote) + - [End Block](#end-block) + - [Tally Exchange Rate Votes](#tally-exchange-rate-votes) + - [Messages](#messages-1) + - [MsgAggregateExchangeRatePrevote](#msgaggregateexchangerateprevote) + - [MsgAggregateExchangeRateVote](#msgaggregateexchangeratevote) + - [MsgDelegateFeedConsent](#msgdelegatefeedconsent) + - [Events](#events) + - [EndBlocker](#endblocker) + - [Events for MsgExchangeRatePrevote](#events-for-msgexchangerateprevote) + - [Events for MsgExchangeRateVote](#events-for-msgexchangeratevote) + - [Events for MsgDelegateFeedConsent](#events-for-msgdelegatefeedconsent) + - [Events for MsgAggregateExchangeRatePrevote](#events-for-msgaggregateexchangerateprevote) + - [Events for MsgAggregateExchangeRateVote](#events-for-msgaggregateexchangeratevote) + +--- + +## Concepts + +See [docs.nibiru.fi/ecosystem/oracle](https://docs.nibiru.fi/ecosystem/oracle/). + +### Voting Procedure + +During each `VotePeriod`, the Oracle module obtains consensus on the exchange rate of pairs specified in `Whitelist` by requiring all members of the validator set to submit a vote for exchange rates before the end of the interval. + +Validators must first pre-commit to a exchange rate, then in the subsequent `VotePeriod` submit and reveal their exchange rate alongside a proof that they had pre-commited at that price. This scheme forces the voter to commit to a submission before knowing the votes of others and thereby reduces centralization and free-rider risk in the Oracle. + +* Prevote and Vote + + Let `P_t` be the current time interval of duration defined by `VotePeriod` (currently set to 30 seconds) during which validators must submit two messages: + + * A `MsgAggregateExchangeRatePrevote`, containing the SHA256 hash of the exchange rates of pairs. A prevote must be submitted for all pairs. + * A `MsgAggregateExchangeRateVote`, containing the salt used to create the hash for the aggregate prevote submitted in the previous interval `P_t-1`. + +* Vote Tally + + At the end of `P_t`, the submitted votes are tallied. + + The submitted salt of each vote is used to verify consistency with the prevote submitted by the validator in `P_t-1`. If the validator has not submitted a prevote, or the SHA256 resulting from the salt does not match the hash from the prevote, the vote is dropped. + + For each pair, if the total voting power of submitted votes exceeds 50%, the weighted median of the votes is recorded on-chain as the effective exchange rate for the following `VotePeriod` `P_t+1`. + + Exchange rates receiving fewer than `VoteThreshold` total voting power have their exchange rates deleted from the store, and no exchange rate will exist for the next VotePeriod `P_t+1`. + +* Ballot Rewards + + After the votes are tallied, the winners of the ballots are determined with `tally()`. + + Voters that have managed to vote within a narrow band around the weighted median, are rewarded with a portion of the collected seigniorage. See `k.RewardBallotWinners()` for more details. + +### Reward Band + +Let `M` be the weighted median, `𝜎` be the standard deviation of the votes in the ballot, and be the RewardBand parameter. The band around the median is set to be `𝜀 = max(𝜎, R/2)`. All valid (i.e. bonded and non-jailed) validators that submitted an exchange rate vote in the interval `[M - 𝜀, M + 𝜀]` should be included in the set of winners, weighted by their relative vote power. + +### Slashing + +> Be sure to read this section carefully as it concerns potential loss of funds. + +A `VotePeriod` during which either of the following events occur is considered a "miss": + +* The validator fails to submits a vote for an exchange rate against **each and every** pair specified in `Whitelist`. + +* The validator fails to vote within the `reward band` around the weighted median for one or more pairs. + +During every `SlashWindow`, participating validators must maintain a valid vote rate of at least `MinValidPerWindow` (5%), lest they get their stake slashed (currently set to 0.01%). The slashed validator is automatically temporarily "jailed" by the protocol (to protect the funds of delegators), and the operator is expected to fix the discrepancy promptly to resume validator participation. + +### Abstaining from Voting + +A validator may abstain from voting by submitting a non-positive integer for the `ExchangeRate` field in `MsgAggregateExchangeRateVote`. Doing so will absolve them of any penalties for missing `VotePeriod`s, but also disqualify them from receiving Oracle seigniorage rewards for faithful reporting. + +### Messages + +> The control flow for vote-tallying, exchange rate updates, ballot rewards and slashing happens at the end of every `VotePeriod`, and is found at the [end-block ABCI](#end-block) function rather than inside message handlers. + +--- + +## Module Parameters + +The oracle module contains the following parameters: + +| Module Param (type) | Description | +| ------------------------- | ----------- | +| `VotePeriod` (uint64) | Defines the number of blocks during which voting takes place. Ex. "5". | +| `VoteThreshold` (Dec) | VoteThreshold specifies the minimum proportion of votes that must be received for a ballot to pass. Ex. "0.5" | +| `RewardBand` (Dec) | Defines a maxium divergence that a price vote can have from the weighted median in the ballot. If a vote lies within the valid range defined by: `μ := weightedMedian`, `validRange := μ ± (μ * rewardBand / 2)`, then rewards are added to the validator performance. Note that if the reward band is smaller than 1 standard deviation, the band is taken to be 1 standard deviation.a price. Ex. "0.02" | +| `Whitelist` (set[String]) | The set of whitelisted markets, or asset pairs, for the module. Ex. '["unibi:uusd","ubtc:uusd"]' | +| `SlashFraction` (Dec) | The proportion of an oracle's stake that gets slashed in the event of slashing. `SlashFraction` specifies the exact penalty for failing a voting period. | +| `SlashWindow` (uint64) | The number of voting periods that specify a "slash window". After each slash window, all oracles that have missed more than the penalty threshold are slashed. Missing the penalty threshold is synonymous with submitting fewer valid votes than `MinValidPerWindow`. | +| `MinValidPerWindow` (Dec) | The oracle slashing threshold. Ex. "0.05". | +| `TwapLookbackWindow` (Duration) | Lookback window for time-weighted average price (TWAP) calculations. + +--- + +## State + +### ExchangeRate + +An `sdk.Dec` that stores the current exchange rate against a given pair. + +You can get the active list of pairs (exchange rates with votes past `VoteThreshold`) with `k.GetActivePairs()`. + +- ExchangeRate: `0x03 -> amino(sdk.Dec)` + +### FeederDelegation + +An `sdk.AccAddress` (`nibi-` account) address of `operator`'s delegated price feeder. + +- FeederDelegation: `0x04 -> amino(sdk.AccAddress)` + +### MissCounter + +An `int64` representing the number of `VotePeriods` that validator `operator` missed during the current `SlashWindow`. + +- MissCounter: `0x05 -> amino(int64)` + +### AggregateExchangeRatePrevote + +`AggregateExchangeRatePrevote` containing validator voter's aggregated prevote for all pairs for the current `VotePeriod`. + +- AggregateExchangeRatePrevote: `0x06 -> amino(AggregateExchangeRatePrevote)` + +```go +// AggregateVoteHash is hash value to hide vote exchange rates +// which is formatted as hex string in SHA256("{salt}:({pair},{exchange_rate})|...|({pair},{exchange_rate}):{voter}") +type AggregateVoteHash []byte + +type AggregateExchangeRatePrevote struct { + Hash AggregateVoteHash // Vote hex hash to protect centralize data source problem + Voter sdk.ValAddress // Voter val address + SubmitBlock int64 +} +``` + +### AggregateExchangeRateVote + +`AggregateExchangeRateVote` containing validator voter's aggregate vote for all pairs for the current `VotePeriod`. + +- AggregateExchangeRateVote: `0x07 -> amino(AggregateExchangeRateVote)` + +```go +type ExchangeRateTuple struct { + Pair string `json:"pair"` + ExchangeRate sdk.Dec `json:"exchange_rate"` +} + +type ExchangeRateTuples []ExchangeRateTuple + +type AggregateExchangeRateVote struct { + ExchangeRateTuples ExchangeRateTuples // ExchangeRates of pairs + Voter sdk.ValAddress // voter val address of validator +} +``` + +--- + +## End Block + +### Tally Exchange Rate Votes + +At the end of every block, the `Oracle` module checks whether it's the last block of the `VotePeriod`. If it is, it runs the [Voting Procedure](#Voting_Procedure): + +1. All current active exchange rates are purged from the store + +2. Received votes are organized into ballots by pair. Abstained votes, as well as votes by inactive or jailed validators are ignored + +3. Pairs not meeting the following requirements will be dropped: + + - Must appear in the permitted pairs in `Whitelist` + - Ballot for pair must have at least `VoteThreshold` total vote power + +4. For each remaining `pair` with a passing ballot: + + - Tally up votes and find the weighted median exchange rate and winners with `tally()` + - Iterate through winners of the ballot and add their weight to their running total + - Set the exchange rate on the blockchain for that pair with `k.SetExchangeRate()` + - Emit an `exchange_rate_update` event + +5. Count up the validators who [missed](#Slashing) the Oracle vote and increase the appropriate miss counters + +6. If at the end of a `SlashWindow`, penalize validators who have missed more than the penalty threshold (submitted fewer valid votes than `MinValidPerWindow`) + +7. Distribute rewards to ballot winners with `k.RewardBallotWinners()` + +8. Clear all prevotes (except ones for the next `VotePeriod`) and votes from the store + +--- + +## Messages + +### MsgAggregateExchangeRatePrevote + +`Hash` is a hex string generated by the leading 20 bytes of the SHA256 hash (hex string) of a string of the format `{salt}:({pair},{exchange_rate})|...|({pair},{exchange_rate}):{voter}`, the metadata of the actual `MsgAggregateExchangeRateVote` to follow in the next `VotePeriod`. You can use the `GetAggregateVoteHash()` function to help encode this hash. Note that since in the subsequent `MsgAggregateExchangeRateVote`, the salt will have to be revealed, the salt used must be regenerated for each prevote submission. + +```go +// MsgAggregateExchangeRatePrevote - struct for aggregate prevoting on the ExchangeRateVote. +// The purpose of aggregate prevote is to hide vote exchange rates with hash +// which is formatted as hex string in SHA256("{salt}:({pair},{exchange_rate})|...|({pair},{exchange_rate}):{voter}") +type MsgAggregateExchangeRatePrevote struct { + Hash AggregateVoteHash + Feeder sdk.AccAddress + Validator sdk.ValAddress +} +``` + +`Feeder` (`nibi-` address) is used if the validator wishes to delegate oracle vote signing to a separate key (who "feeds" the price in lieu of the operator) to de-risk exposing their validator signing key. + +`Validator` is the validator address (`nibivaloper-` address) of the original validator. + +### MsgAggregateExchangeRateVote + +The `MsgAggregateExchangeRateVote` contains the actual exchange rates vote. The `Salt` parameter must match the salt used to create the prevote, otherwise the voter cannot be rewarded. + +```go +// MsgAggregateExchangeRateVote - struct for voting on the exchange rates of pairs. +type MsgAggregateExchangeRateVote struct { + Salt string + ExchangeRates string + Feeder sdk.AccAddress + Validator sdk.ValAddress +} +``` + +### MsgDelegateFeedConsent + +Validators may also elect to delegate voting rights to another key to prevent the block signing key from being kept online. To do so, they must submit a `MsgDelegateFeedConsent`, delegating their oracle voting rights to a `Delegate` that sign `MsgAggregateExchangeRatePrevote` and `MsgAggregateExchangeRateVote` on behalf of the validator. + +> Delegate validators will likely require you to deposit some funds (in NIBI) which they can use to pay fees, sent in a separate MsgSend. This agreement is made off-chain and not enforced by the Nibiru protocol. + +The `Operator` field contains the operator address of the validator (prefixed `nibivaloper-`). The `Delegate` field is the account address (prefixed `nibi-`) of the delegate account that will be submitting exchange rate related votes and prevotes on behalf of the `Operator`. + +```go +// MsgDelegateFeedConsent - struct for delegating oracle voting rights to another address. +type MsgDelegateFeedConsent struct { + Operator sdk.ValAddress + Delegate sdk.AccAddress +} +``` + +--- + +## Events + +The oracle module emits the following events: + +### EndBlocker + +| Type | Attribute Key | Attribute Value | +|----------------------|---------------|-----------------| +| exchange_rate_update | pair | {pair} | +| exchange_rate_update | exchange_rate | {exchangeRate} | + + +### Events for MsgExchangeRatePrevote + +| Type | Attribute Key | Attribute Value | +|---------|---------------|---------------------| +| prevote | pair | {pair} | +| prevote | voter | {validatorAddress} | +| prevote | feeder | {feederAddress} | +| message | module | oracle | +| message | action | exchangerateprevote | +| message | sender | {senderAddress} | + +### Events for MsgExchangeRateVote + +| Type | Attribute Key | Attribute Value | +|---------|---------------|--------------------| +| vote | pair | {pair} | +| vote | voter | {validatorAddress} | +| vote | exchange_rate | {exchangeRate} | +| vote | feeder | {feederAddress} | +| message | module | oracle | +| message | action | exchangeratevote | +| message | sender | {senderAddress} | + +### Events for MsgDelegateFeedConsent + + +| Type | Attribute Key | Attribute Value | +|---------------|---------------|--------------------| +| feed_delegate | operator | {validatorAddress} | +| feed_delegate | feeder | {feederAddress} | +| message | module | oracle | +| message | action | delegatefeeder | +| message | sender | {senderAddress} | + +### Events for MsgAggregateExchangeRatePrevote + +| Type | Attribute Key | Attribute Value | +|-------------------|---------------|------------------------------| +| aggregate_prevote | voter | {validatorAddress} | +| aggregate_prevote | feeder | {feederAddress} | +| message | module | oracle | +| message | action | aggregateexchangerateprevote | +| message | sender | {senderAddress} | + +### Events for MsgAggregateExchangeRateVote + +| Type | Attribute Key | Attribute Value | +|----------------|----------------|---------------------------| +| aggregate_vote | voter | {validatorAddress} | +| aggregate_vote | exchange_rates | {exchangeRates} | +| aggregate_vote | feeder | {feederAddress} | +| message | module | oracle | +| message | action | aggregateexchangeratevote | +| message | sender | {senderAddress} | + +--- diff --git a/x/oracle/abci.go b/x/oracle/abci.go new file mode 100644 index 00000000..3d6545dc --- /dev/null +++ b/x/oracle/abci.go @@ -0,0 +1,33 @@ +package oracle + +import ( + "time" + + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" + + "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// EndBlocker is called at the end of every block +func EndBlocker(ctx sdk.Context, k keeper.Keeper) error { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker) + + params, err := k.Params.Get(ctx) + if err != nil { + return err + } + + if types.IsPeriodLastBlock(ctx, params.VotePeriod) { + k.UpdateExchangeRates(ctx) + } + + // Do slash who did miss voting over threshold and + // reset miss counters of all validators at the last block of slash window + if types.IsPeriodLastBlock(ctx, params.SlashWindow) { + k.SlashAndResetMissCounters(ctx) + } + + return nil +} diff --git a/x/oracle/abci_test.go b/x/oracle/abci_test.go new file mode 100644 index 00000000..0fe43380 --- /dev/null +++ b/x/oracle/abci_test.go @@ -0,0 +1,144 @@ +package oracle_test + +import ( + "testing" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + cmTypes "github.com/cometbft/cometbft/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/x/oracle" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" + oracletypes "github.com/archway-network/archway/x/oracle/types" +) + +// TODO (spekalsg3): duplicated from `package keeper_test` +func MakeAggregatePrevoteAndVote( + t *testing.T, + ctx sdk.Context, + msgServer oracletypes.MsgServer, + height int64, + rates oracletypes.ExchangeRateTuples, + val *cmTypes.Validator, +) { + accAddr := sdk.AccAddress(val.Address) + valAddr := sdk.ValAddress(val.Address) + + salt := "1" + ratesStr, err := rates.ToString() + require.NoError(t, err) + hash := oracletypes.GetAggregateVoteHash(salt, ratesStr, valAddr) + + prevoteMsg := oracletypes.NewMsgAggregateExchangeRatePrevote(hash, accAddr, valAddr) + _, err = msgServer.AggregateExchangeRatePrevote(ctx.WithBlockHeight(height), prevoteMsg) + require.NoError(t, err) + + // chain.GetApp().Keepers.OracleKeeper.VotePeriod(ctx) + voteMsg := oracletypes.NewMsgAggregateExchangeRateVote(salt, ratesStr, accAddr, valAddr) + _, err = msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(height+1), voteMsg) + require.NoError(t, err) +} + +func TestOracleTallyTiming(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(4), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + // all the Addrs vote for the block ... not last period block yet, so tally fails + for _, val := range chain.GetCurrentValSet().Validators { + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.BTC, denoms.USD), ExchangeRate: math.LegacyOneDec()}, + }, val) + } + + params.VotePeriod = 10 // set vote period to 10 for now, for convenience + params.ExpirationBlocks = 100 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + require.Equal(t, 1, int(ctx.BlockHeight())) + + require.NoError(t, oracle.EndBlocker(ctx, keepers.OracleKeeper)) + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, asset.Registry.Pair(denoms.BTC, denoms.USD)) + require.Error(t, err) + + ctx = ctx.WithBlockHeight(int64(params.VotePeriod)) + require.NoError(t, oracle.EndBlocker(ctx, keepers.OracleKeeper)) + + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, asset.Registry.Pair(denoms.BTC, denoms.USD)) + require.NoError(t, err) +} + +// Set prices for 2 pairs, one that is updated and the other which is updated only once. +// Ensure that the updated pair is not deleted and the other pair is deleted after a certain time. +func TestOraclePriceExpiration(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(4), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + pair1 := asset.Registry.Pair(denoms.BTC, denoms.USD) + pair2 := asset.Registry.Pair(denoms.ETH, denoms.USD) + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + // Set prices for both pairs + for _, val := range chain.GetCurrentValSet().Validators { + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: pair1, ExchangeRate: math.LegacyOneDec()}, + {Pair: pair2, ExchangeRate: math.LegacyOneDec()}, + }, val) + } + + params.VotePeriod = 10 + params.ExpirationBlocks = 10 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + // Wait for prices to set + ctx = ctx.WithBlockHeight(int64(params.VotePeriod)) + require.NoError(t, oracle.EndBlocker(ctx, keepers.OracleKeeper)) + + // Check if both prices are set + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, pair1) + require.NoError(t, err) + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, pair2) + require.NoError(t, err) + + // Set prices for pair 1 + voteHeight := int64(params.VotePeriod+params.ExpirationBlocks) - 1 + for _, val := range chain.GetCurrentValSet().Validators { + MakeAggregatePrevoteAndVote(t, ctx, msgServer, voteHeight, types.ExchangeRateTuples{ + {Pair: pair1, ExchangeRate: math.LegacyNewDec(2)}, + }, val) + } + + // Set price + ctx = ctx.WithBlockHeight(voteHeight) + require.NoError(t, oracle.EndBlocker(ctx, keepers.OracleKeeper)) + + // Set the block height to the expiration height + // End blocker should delete the price of pair2 + ctx = ctx.WithBlockHeight(int64(params.ExpirationBlocks + params.VotePeriod)) + require.NoError(t, oracle.EndBlocker(ctx, keepers.OracleKeeper)) + + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, pair1) + require.NoError(t, err) + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, pair2) + require.Error(t, err) +} diff --git a/x/oracle/asset/pair.go b/x/oracle/asset/pair.go new file mode 100644 index 00000000..1c5e167f --- /dev/null +++ b/x/oracle/asset/pair.go @@ -0,0 +1,200 @@ +package asset + +import ( + "encoding/json" + "fmt" + "strings" + + "cosmossdk.io/collections" + collcodec "cosmossdk.io/collections/codec" + sdkerrors "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// paired against USD +var ErrInvalidTokenPair = sdkerrors.Register("asset", 1, "invalid token pair") + +type Pair string + +func NewPair(base string, quote string) Pair { + // validate as denom + ap := fmt.Sprintf("%s%s%s", base, ":", quote) + return Pair(ap) +} + +// TryNewPair New returns a new asset pair instance if the pair is valid. +// The form, "token0:token1", is expected for 'pair'. +// Use this function to return an error instead of panicking. +func TryNewPair(pair string) (Pair, error) { + split := strings.Split(pair, ":") + splitLen := len(split) + if splitLen != 2 { + if splitLen == 1 { + return "", sdkerrors.Wrapf(ErrInvalidTokenPair, + "pair separator missing for pair name, %v", pair) + } else { + return "", sdkerrors.Wrapf(ErrInvalidTokenPair, + "pair name %v must have exactly two assets, not %v", pair, splitLen) + } + } + + if split[0] == "" || split[1] == "" { + return "", sdkerrors.Wrapf(ErrInvalidTokenPair, + "empty token identifiers are not allowed. token0: %v, token1: %v.", + split[0], split[1]) + } + + // validate as denom + Pair := NewPair(split[0], split[1]) + return Pair, Pair.Validate() +} + +// MustNewPair returns a new asset pair. It will panic if 'pair' is invalid. +// The form, "token0:token1", is expected for 'pair'. +func MustNewPair(pair string) Pair { + Pair, err := TryNewPair(pair) + if err != nil { + panic(err) + } + return Pair +} + +/* +String returns the string representation of the asset pair. + +Note that this differs from the output of the proto-generated 'String' method. +*/ +func (pair Pair) String() string { + return string(pair) +} + +func (pair Pair) Inverse() Pair { + return NewPair(pair.QuoteDenom(), pair.BaseDenom()) +} + +func (pair Pair) BaseDenom() string { + split := strings.Split(pair.String(), ":") + return split[0] +} + +func (pair Pair) QuoteDenom() string { + split := strings.Split(pair.String(), ":") + return split[1] +} + +// Validate performs a basic validation of the market params +func (pair Pair) Validate() error { + if len(pair) == 0 { + return ErrInvalidTokenPair.Wrap("pair is empty") + } + + split := strings.Split(pair.String(), ":") + if len(split) != 2 { + return ErrInvalidTokenPair.Wrap(pair.String()) + } + + if err := sdk.ValidateDenom(split[0]); err != nil { + return ErrInvalidTokenPair.Wrapf("invalid base asset: %s", err) + } + if err := sdk.ValidateDenom(split[1]); err != nil { + return ErrInvalidTokenPair.Wrapf("invalid quote asset: %s", err) + } + return nil +} + +func (pair Pair) Equal(other Pair) bool { + return pair.String() == other.String() +} + +var _ sdk.CustomProtobufType = (*Pair)(nil) + +func (pair Pair) Marshal() ([]byte, error) { + return []byte(pair), nil +} + +func (pair *Pair) Unmarshal(data []byte) error { + *pair = Pair(data) + return nil +} + +func (pair Pair) MarshalJSON() ([]byte, error) { + return json.Marshal(pair.String()) +} + +func (pair *Pair) UnmarshalJSON(data []byte) error { + var pairString string + if err := json.Unmarshal(data, &pairString); err != nil { + return err + } + *pair = Pair(pairString) + return nil +} + +func (pair Pair) MarshalTo(data []byte) (n int, err error) { + copy(data, pair) + return pair.Size(), nil +} + +func (pair Pair) Size() int { + return len(pair) +} + +var PairKeyEncoder collcodec.KeyCodec[Pair] = pairKeyEncoder{} + +type pairKeyEncoder struct{} + +func (pairKeyEncoder) Size(key Pair) int { + return key.Size() +} + +func (pairKeyEncoder) KeyType() string { + return "archway.pairKeyEncoder" +} + +func (pairKeyEncoder) Stringify(a Pair) string { + return a.String() +} + +func (pairKeyEncoder) Encode(buf []byte, pair Pair) (int, error) { + i, err := collections.StringKey.Encode(buf, pair.String()) + return i, err +} + +func (pairKeyEncoder) Decode(b []byte) (int, Pair, error) { + i, s, err := collections.StringKey.Decode(b) + return i, MustNewPair(s), err +} +func (pairKeyEncoder) EncodeJSON(value Pair) ([]byte, error) { + return value.MarshalJSON() +} +func (pairKeyEncoder) DecodeJSON(b []byte) (Pair, error) { + newPair := new(Pair) + err := newPair.UnmarshalJSON(b) + return *newPair, err +} +func (pke pairKeyEncoder) EncodeNonTerminal(buffer []byte, key Pair) (int, error) { + return pke.Encode(buffer, key) +} +func (pke pairKeyEncoder) DecodeNonTerminal(buffer []byte) (int, Pair, error) { + return pke.Decode(buffer) +} +func (pairKeyEncoder) SizeNonTerminal(key Pair) int { + return key.Size() +} + +// MustNewPairs constructs a new asset pair set. A panic will occur if one of +// the provided pair names is invalid. +func MustNewPairs(pairStrings ...string) (pairs []Pair) { + for _, pairString := range pairStrings { + pairs = append(pairs, MustNewPair(pairString)) + } + return pairs +} + +func PairsToStrings(pairs []Pair) []string { + pairsStrings := []string{} + for _, pair := range pairs { + pairsStrings = append(pairsStrings, pair.String()) + } + return pairsStrings +} diff --git a/x/oracle/asset/pair_test.go b/x/oracle/asset/pair_test.go new file mode 100644 index 00000000..a4123466 --- /dev/null +++ b/x/oracle/asset/pair_test.go @@ -0,0 +1,180 @@ +package asset_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/archway-network/archway/app" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" +) + +func TestTryNewPair(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + tokenStr string + err error + }{ + { + "only one token", + denoms.NIBI, + asset.ErrInvalidTokenPair, + }, + { + "more than 2 tokens", + fmt.Sprintf("%s:%s:%s", denoms.NIBI, denoms.NUSD, denoms.USDC), + asset.ErrInvalidTokenPair, + }, + { + "different separator", + fmt.Sprintf("%s,%s", denoms.NIBI, denoms.NUSD), + asset.ErrInvalidTokenPair, + }, + { + "correct pair", + fmt.Sprintf("%s:%s", denoms.NIBI, denoms.NUSD), + nil, + }, + { + "empty token identifier", + fmt.Sprintf(":%s", denoms.ETH), + fmt.Errorf("empty token identifiers are not allowed"), + }, + { + "invalid denom 1", + "-invalid1:valid", + fmt.Errorf("invalid denom"), + }, + { + "invalid denom 2", + "valid:-invalid2", + fmt.Errorf("invalid denom"), + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := asset.TryNewPair(tc.tokenStr) + if tc.err != nil { + require.ErrorContains(t, err, tc.err.Error()) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestGetDenoms(t *testing.T) { + pair := asset.MustNewPair("uatom:unibi") + + require.Equal(t, "uatom", pair.BaseDenom()) + require.Equal(t, "unibi", pair.QuoteDenom()) +} + +func TestEquals(t *testing.T) { + pair := asset.MustNewPair("abc:xyz") + matchingOther := asset.MustNewPair("abc:xyz") + mismatchToken1 := asset.MustNewPair("abc:abc") + inversePair := asset.MustNewPair("xyz:abc") + + require.True(t, pair.Equal(matchingOther)) + require.False(t, pair.Equal(inversePair)) + require.False(t, pair.Equal(mismatchToken1)) +} + +func TestMustNewAssetPair(t *testing.T) { + require.Panics(t, func() { + asset.MustNewPair("aaa:bbb:ccc") + }) + + require.NotPanics(t, func() { + asset.MustNewPair("aaa:bbb") + }) +} + +func TestInverse(t *testing.T) { + pair := asset.MustNewPair("abc:xyz") + inverse := pair.Inverse() + require.Equal(t, "xyz", inverse.BaseDenom()) + require.Equal(t, "abc", inverse.QuoteDenom()) +} + +func TestMarshalJSON(t *testing.T) { + cdc := app.MakeEncodingConfig() + + testCases := []struct { + name string + input asset.Pair + strOutput string + }{ + {name: "happy-0", input: asset.Pair("abc:xyz"), strOutput: "\"abc:xyz\""}, + {name: "happy-1", input: asset.Pair("abc:xyz:foo"), strOutput: "\"abc:xyz:foo\""}, + {name: "happy-2", input: asset.Pair("abc"), strOutput: "\"abc\""}, + {name: "empty", input: asset.Pair(""), strOutput: "\"\""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // MarshalJSON with codec.LegacyAmino + jsonBz, err := cdc.Amino.MarshalJSON(tc.input) + require.NoError(t, err) + require.Equal(t, tc.strOutput, string(jsonBz)) + + // MarshalJSON on custom type + jsonBzCustom, err := tc.input.MarshalJSON() + require.NoError(t, err) + require.Equal(t, jsonBzCustom, jsonBz) + + // UnmarshalJSON with codec.LegacyAmino + newPair := new(asset.Pair) + require.NoError(t, cdc.Amino.UnmarshalJSON(jsonBz, newPair)) + require.Equal(t, tc.input, *newPair) + + // UnmarshalJSON on custom type + newNewPair := new(asset.Pair) + *newNewPair = tc.input + require.NoError(t, newNewPair.UnmarshalJSON(jsonBz)) + + // Marshal and Unmarshal (to bytes) test + bz, err := tc.input.Marshal() + require.NoError(t, err) + newNewNewPair := new(asset.Pair) + require.NoError(t, newNewNewPair.Unmarshal(bz)) + require.Equal(t, tc.input, *newNewNewPair) + }) + } +} + +func TestPairsUtils(t *testing.T) { + testCases := []struct { + pairStrs []string + expectPanic bool + }{ + {pairStrs: []string{"eth:usd", "btc:usd", "atom:usd"}, expectPanic: false}, + {pairStrs: []string{"eth:usd", "", "abc"}, expectPanic: true}, + {pairStrs: []string{"eth:usd:ftt", "btc:usd"}, expectPanic: true}, + } + + var panicTestFn func(t require.TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) + + for idx, tc := range testCases { + t.Run(fmt.Sprint(idx), func(t *testing.T) { + if tc.expectPanic { + panicTestFn = require.Panics + } else { + panicTestFn = require.NotPanics + } + panicTestFn(t, func() { + pairs := asset.MustNewPairs(tc.pairStrs...) + newPairStrs := asset.PairsToStrings(pairs) + require.Equal(t, tc.pairStrs, newPairStrs) + }) + }) + } +} diff --git a/x/oracle/asset/registry.go b/x/oracle/asset/registry.go new file mode 100644 index 00000000..2fb50792 --- /dev/null +++ b/x/oracle/asset/registry.go @@ -0,0 +1,80 @@ +package asset + +import ( + "github.com/archway-network/archway/types/set" + "github.com/archway-network/archway/x/oracle/denoms" +) + +type registry map[string]set.Set[string] + +var Registry registry + +func init() { + // map of base asset to supported quote assets + // quote assets are usually stables + Registry = map[string]set.Set[string]{ + denoms.BTC: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.ETH: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.NIBI: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.ATOM: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.OSMO: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.AVAX: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.SOL: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.BNB: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.ADA: set.New(denoms.USDC, denoms.NUSD, denoms.USD, denoms.USDT), + denoms.NUSD: set.New(denoms.USD, denoms.USDC), + denoms.USDC: set.New(denoms.USD, denoms.NUSD), + denoms.USDT: set.New(denoms.USD, denoms.NUSD, denoms.USDC), + } +} + +func (r registry) Pair(base string, quote string) Pair { + for q := range r[base] { + if q == quote { + return NewPair(string(base), string(quote)) + } + } + + return "" +} + +// Returns all supported base denoms +func (r registry) BaseDenoms() set.Set[string] { + baseSet := make(set.Set[string]) + for d := range r { + baseSet.Add(d) + } + return baseSet +} + +// Returns all supported quote denoms +func (r registry) QuoteDenoms() set.Set[string] { + quoteSet := make(set.Set[string]) + for base := range r { + for q := range r[base] { + quoteSet.Add(q) + } + } + return quoteSet +} + +// Checks if the provided denom is a supported base denom +func (r registry) IsSupportedBaseDenom(denom string) bool { + _, ok := r[denom] + return ok +} + +// Checks if the provided denom is a supported quote denom +func (r registry) IsSupportedQuoteDenom(denom string) bool { + return r.QuoteDenoms().Has(denom) +} + +// Checks if the provided denom is a supported denom +func (r registry) IsSupportedDenom(denom string) bool { + return r.IsSupportedBaseDenom(string(denom)) || r.IsSupportedQuoteDenom(string(denom)) +} + +// Checks if the provided base and quote denoms are a supported pair +func (r registry) IsSupportedPair(base string, quote string) bool { + return r.IsSupportedBaseDenom(base) && r.IsSupportedQuoteDenom(quote) +} diff --git a/x/oracle/asset/registry_test.go b/x/oracle/asset/registry_test.go new file mode 100644 index 00000000..25f4d543 --- /dev/null +++ b/x/oracle/asset/registry_test.go @@ -0,0 +1,81 @@ +package asset + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/archway-network/archway/x/oracle/denoms" +) + +func TestIsSupportedPair(t *testing.T) { + for base := range Registry { + for quote := range Registry[base] { + require.Truef(t, Registry.IsSupportedPair(base, quote), "%s:%s should be supported", base, quote) + } + } + + t.Log("test an unsupported pair") + require.False(t, Registry.IsSupportedPair(denoms.ATOM, denoms.OSMO)) +} + +func TestPair(t *testing.T) { + for base := range Registry { + for quote := range Registry[base] { + require.Equal(t, NewPair(base, quote), Registry.Pair(base, quote)) + } + } + + t.Log("test an unsupported pair") + require.Equal(t, Pair(""), Registry.Pair(denoms.ATOM, denoms.OSMO)) + + t.Log("test an unsupported base asset") + require.Equal(t, Pair(""), Registry.Pair("unsuported_denom", denoms.USDC)) + + t.Log("test an unsupported quote asset") + require.Equal(t, Pair(""), Registry.Pair(denoms.ATOM, "unsupported_denom")) +} + +func TestBaseDenoms(t *testing.T) { + for base := range Registry { + require.Contains(t, Registry.BaseDenoms(), base) + } +} + +func TestIsSupportedBaseDenom(t *testing.T) { + for base := range Registry { + require.True(t, Registry.IsSupportedBaseDenom(base)) + } + require.False(t, Registry.IsSupportedBaseDenom("unsupported_denom")) +} + +func TestQuoteDenoms(t *testing.T) { + for base := range Registry { + for quote := range Registry[base] { + require.True(t, Registry.QuoteDenoms().Has(quote)) + } + } +} + +func TestIsSupportedQuoteDenom(t *testing.T) { + for base := range Registry { + for quote := range Registry[base] { + require.True(t, Registry.IsSupportedQuoteDenom(quote)) + } + } + + require.False(t, Registry.IsSupportedQuoteDenom("unsupported_denom")) +} + +func TestIsSupportedDenom(t *testing.T) { + for base := range Registry.BaseDenoms() { + require.True(t, Registry.IsSupportedDenom(base)) + } + + for quote := range Registry.QuoteDenoms() { + require.True(t, Registry.IsSupportedDenom(quote)) + } + + t.Log("test an unsupported denom") + require.False(t, Registry.IsSupportedDenom("unsupported_denom")) +} diff --git a/x/oracle/client/cli/gen_pricefeeder_delegation.go b/x/oracle/client/cli/gen_pricefeeder_delegation.go new file mode 100644 index 00000000..00fcd399 --- /dev/null +++ b/x/oracle/client/cli/gen_pricefeeder_delegation.go @@ -0,0 +1,99 @@ +package cli + +import ( + "encoding/json" + "fmt" + + flag "github.com/spf13/pflag" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/spf13/cobra" + + "github.com/archway-network/archway/x/oracle/types" +) + +const ( + FlagValidator = "validator" + FlagPricefeeder = "pricefeeder" +) + +func AddGenesisPricefeederDelegationCmd(defaultNodeHome string) *cobra.Command { + cmd := &cobra.Command{ + Use: "add-genesis-pricefeeder-delegation", + Short: "Add a pricefeeder delegation to genesis.json.", + Long: `Add a pricefeeder delegation to genesis.json.`, + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + serverCtx := server.GetServerContextFromCmd(cmd) + config := serverCtx.Config + config.SetRoot(clientCtx.HomeDir) + genFile := config.GenesisFile() + + genState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) + if err != nil { + return err + } + + valAddr, err := cmd.Flags().GetString(FlagValidator) + if err != nil { + return err + } + + _, err = sdk.ValAddressFromBech32(valAddr) + if err != nil { + return err + } + + pricefeederAddr, err := cmd.Flags().GetString(FlagPricefeeder) + if err != nil { + return err + } + + _, err = sdk.AccAddressFromBech32(pricefeederAddr) + if err != nil { + return err + } + + oracleGenState := types.GetGenesisStateFromAppState(clientCtx.Codec, genState) + oracleGenState.FeederDelegations = append(oracleGenState.FeederDelegations, types.FeederDelegation{ + FeederAddress: pricefeederAddr, + ValidatorAddress: valAddr, + }) + + oracleGenStateBz, err := clientCtx.Codec.MarshalJSON(oracleGenState) + if err != nil { + return fmt.Errorf("failed to marshal market genesis state: %w", err) + } + + genState[types.ModuleName] = oracleGenStateBz + + appStateJSON, err := json.Marshal(genState) + if err != nil { + return fmt.Errorf("failed to marshal application genesis state: %w", err) + } + + genDoc.AppState = appStateJSON + return genutil.ExportGenesisFile(genDoc, genFile) + }, + } + + cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") + + flagSet := flag.NewFlagSet("flags-add-genesis-pricefeeder-delegation", flag.ContinueOnError) + + flagSet.String(FlagValidator, "", "validator address") + _ = cmd.MarkFlagRequired(FlagValidator) + + flagSet.String(FlagPricefeeder, "", "pricefeeder address") + _ = cmd.MarkFlagRequired(FlagPricefeeder) + + cmd.Flags().AddFlagSet(flagSet) + + return cmd +} diff --git a/x/oracle/client/cli/gen_pricefeeder_delegation_test.go b/x/oracle/client/cli/gen_pricefeeder_delegation_test.go new file mode 100644 index 00000000..b3bf3975 --- /dev/null +++ b/x/oracle/client/cli/gen_pricefeeder_delegation_test.go @@ -0,0 +1,74 @@ +package cli_test + +import ( + "fmt" + "testing" + + "github.com/archway-network/archway/x/oracle/client/cli" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" +) + +func TestAddGenesisPricefeederDelegation(t *testing.T) { + tests := []struct { + name string + validator string + pricefeeder string + + expectErr bool + }{ + { + name: "valid", + validator: "cosmosvaloper1lg6qclqn8fayp7t7rwxha6hgfhawxm5eh4ued7", + pricefeeder: "cosmos18lmsapqp03fnvlf6436khg0d9gzhgrfrkcyr3a", + expectErr: false, + }, + { + name: "invalid pricefeeder", + validator: "cosmosvaloper1lg6qclqn8fayp7t7rwxha6hgfhawxm5eh4ued7", + pricefeeder: "cosmos1foobar", + expectErr: true, + }, + { + name: "empty pricefeeder", + validator: "cosmosvaloper1lg6qclqn8fayp7t7rwxha6hgfhawxm5eh4ued7", + pricefeeder: "", + expectErr: true, + }, + { + name: "invalid validator", + validator: "cosmosvaloper1foobar", + pricefeeder: "cosmos18lmsapqp03fnvlf6436khg0d9gzhgrfrkcyr3a", + expectErr: true, + }, + { + name: "empty validator", + validator: "", + pricefeeder: "cosmos18lmsapqp03fnvlf6436khg0d9gzhgrfrkcyr3a", + expectErr: true, + }, + } + + for i, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + chain := e2eTesting.NewTestChain(t, i) + ctx := chain.SetupClientCtx() + cmd := cli.AddGenesisPricefeederDelegationCmd(t.TempDir()) + cmd.SetArgs([]string{ + fmt.Sprintf("--%s=%s", cli.FlagValidator, tc.validator), + fmt.Sprintf("--%s=%s", cli.FlagPricefeeder, tc.pricefeeder), + fmt.Sprintf("--%s=home", flags.FlagHome), + }) + + if tc.expectErr { + require.Error(t, cmd.ExecuteContext(ctx)) + } else { + require.NoError(t, cmd.ExecuteContext(ctx)) + } + }) + } +} diff --git a/x/oracle/client/cli/query.go b/x/oracle/client/cli/query.go new file mode 100644 index 00000000..fb774125 --- /dev/null +++ b/x/oracle/client/cli/query.go @@ -0,0 +1,370 @@ +package cli + +import ( + "context" + "strings" + + "github.com/spf13/cobra" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd() *cobra.Command { + oracleQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for the oracle module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + oracleQueryCmd.AddCommand( + GetCmdQueryExchangeRates(), + GetCmdQueryActives(), + GetCmdQueryParams(), + GetCmdQueryFeederDelegation(), + GetCmdQueryMissCounter(), + GetCmdQueryAggregatePrevote(), + GetCmdQueryAggregateVote(), + GetCmdQueryVoteTargets(), + ) + + return oracleQueryCmd +} + +// GetCmdQueryExchangeRates implements the query rate command. +func GetCmdQueryExchangeRates() *cobra.Command { + cmd := &cobra.Command{ + Use: "exchange-rates [pair]", + Args: cobra.RangeArgs(0, 1), + Short: "Query the current exchange rate w.r.t a pair", + Long: strings.TrimSpace(` +Query the current exchange rate of a pair. +You can find the current list of active pairs by running + +$ nibid query oracle exchange-rates + +Or, can filter with pair + +$ nibid query oracle exchange-rates nibi:usd +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + if len(args) == 0 { + res, err := queryClient.ExchangeRates(context.Background(), &types.QueryExchangeRatesRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + } + + assetPair, err := asset.TryNewPair(args[0]) + if err != nil { + return err + } + + res, err := queryClient.ExchangeRate( + context.Background(), + &types.QueryExchangeRateRequest{Pair: assetPair}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryActives implements the query actives command. +func GetCmdQueryActives() *cobra.Command { + cmd := &cobra.Command{ + Use: "actives", + Args: cobra.NoArgs, + Short: "Query the active list of pairs recognized by the oracle", + Long: strings.TrimSpace(` +Query the active list of pairs recognized by the oracles. + +$ nibid query oracle actives +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.Actives(context.Background(), &types.QueryActivesRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryParams implements the query params command. +func GetCmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Args: cobra.NoArgs, + Short: "Query the current Oracle params", + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryFeederDelegation implements the query feeder delegation command +func GetCmdQueryFeederDelegation() *cobra.Command { + cmd := &cobra.Command{ + Use: "feeder [validator]", + Args: cobra.ExactArgs(1), + Short: "Query the oracle feeder delegate account", + Long: strings.TrimSpace(` +Query the account the validator's oracle voting right is delegated to. + +$ nibid query oracle feeder nibivaloper... +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + valString := args[0] + validator, err := sdk.ValAddressFromBech32(valString) + if err != nil { + return err + } + + res, err := queryClient.FeederDelegation( + context.Background(), + &types.QueryFeederDelegationRequest{ValidatorAddr: validator.String()}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryMissCounter implements the query miss counter of the validator command +func GetCmdQueryMissCounter() *cobra.Command { + cmd := &cobra.Command{ + Use: "miss [validator]", + Args: cobra.ExactArgs(1), + Short: "Query the # of the miss count", + Long: strings.TrimSpace(` +Query the # of vote periods missed in this oracle slash window. + +$ nibid query oracle miss nibivaloper... +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + valString := args[0] + validator, err := sdk.ValAddressFromBech32(valString) + if err != nil { + return err + } + + res, err := queryClient.MissCounter( + context.Background(), + &types.QueryMissCounterRequest{ValidatorAddr: validator.String()}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryAggregatePrevote implements the query aggregate prevote of the validator command +func GetCmdQueryAggregatePrevote() *cobra.Command { + cmd := &cobra.Command{ + Use: "aggregate-prevotes [validator]", + Args: cobra.RangeArgs(0, 1), + Short: "Query outstanding oracle aggregate prevotes.", + Long: strings.TrimSpace(` +Query outstanding oracle aggregate prevotes. + +$ nibid query oracle aggregate-prevotes + +Or, can filter with voter address + +$ nibid query oracle aggregate-prevotes nibivaloper... +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + if len(args) == 0 { + res, err := queryClient.AggregatePrevotes( + context.Background(), + &types.QueryAggregatePrevotesRequest{}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + } + + valString := args[0] + validator, err := sdk.ValAddressFromBech32(valString) + if err != nil { + return err + } + + res, err := queryClient.AggregatePrevote( + context.Background(), + &types.QueryAggregatePrevoteRequest{ValidatorAddr: validator.String()}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryAggregateVote implements the query aggregate prevote of the validator command +func GetCmdQueryAggregateVote() *cobra.Command { + cmd := &cobra.Command{ + Use: "aggregate-votes [validator]", + Args: cobra.RangeArgs(0, 1), + Short: "Query outstanding oracle aggregate votes.", + Long: strings.TrimSpace(` +Query outstanding oracle aggregate vote. + +$ nibid query oracle aggregate-votes + +Or, can filter with voter address + +$ nibid query oracle aggregate-votes nibivaloper... +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + if len(args) == 0 { + res, err := queryClient.AggregateVotes( + context.Background(), + &types.QueryAggregateVotesRequest{}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + } + + valString := args[0] + validator, err := sdk.ValAddressFromBech32(valString) + if err != nil { + return err + } + + res, err := queryClient.AggregateVote( + context.Background(), + &types.QueryAggregateVoteRequest{ValidatorAddr: validator.String()}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// GetCmdQueryVoteTargets implements the query params command. +func GetCmdQueryVoteTargets() *cobra.Command { + cmd := &cobra.Command{ + Use: "vote-targets", + Args: cobra.NoArgs, + Short: "Query the current Oracle vote targets", + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.VoteTargets( + context.Background(), + &types.QueryVoteTargetsRequest{}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/oracle/client/cli/tx.go b/x/oracle/client/cli/tx.go new file mode 100644 index 00000000..8f1c283a --- /dev/null +++ b/x/oracle/client/cli/tx.go @@ -0,0 +1,207 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/pkg/errors" + + "github.com/archway-network/archway/x/oracle/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/spf13/cobra" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + oracleTxCmd := &cobra.Command{ + Use: "oracle", + Short: "Oracle transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + oracleTxCmd.AddCommand( + GetCmdDelegateFeederPermission(), + GetCmdAggregateExchangeRatePrevote(), + GetCmdAggregateExchangeRateVote(), + ) + + return oracleTxCmd +} + +// GetCmdDelegateFeederPermission will create a feeder permission delegation tx and sign it with the given key. +func GetCmdDelegateFeederPermission() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-feeder [feeder]", + Args: cobra.ExactArgs(1), + Short: "Delegate the permission to vote for the oracle to an address", + Long: strings.TrimSpace(` +Delegate the permission to submit exchange rate votes for the oracle to an address. + +Delegation can keep your validator operator key offline and use a separate replaceable key online. + +$ nibid tx oracle set-feeder nibi1... + +where "nibi1..." is the address you want to delegate your voting rights to. +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + // Get from address + voter := clientCtx.GetFromAddress() + + // The address the right is being delegated from + validator := sdk.ValAddress(voter) + + feederStr := args[0] + feeder, err := sdk.AccAddressFromBech32(feederStr) + if err != nil { + return err + } + + msg := types.NewMsgDelegateFeedConsent(validator, feeder) + if err = msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdAggregateExchangeRatePrevote will create a aggregateExchangeRatePrevote tx and sign it with the given key. +func GetCmdAggregateExchangeRatePrevote() *cobra.Command { + cmd := &cobra.Command{ + Use: "aggregate-prevote [salt] [exchange-rates] [validator]", + Args: cobra.RangeArgs(2, 3), + Short: "Submit an oracle aggregate prevote for the exchange rates of Nibiru", + Long: strings.TrimSpace(` +Submit an oracle aggregate prevote for the exchange rates of a pair. +The purpose of aggregate prevote is to hide aggregate exchange rate vote with hash which is formatted +as hex string in SHA256("{salt}:({pair},{exchange_rate})|...|({pair},{exchange_rate}):{voter}") + +# Aggregate Prevote +$ nibid tx oracle aggregate-prevote 1234 (40000.0,BTC:USD)|(1.243,NIBI:USD) + +where "BTC:USD,NIBI:USD" is the pair, and "40000.0, 1.243" is the exchange rates expressed in decimal value. + +If voting from a voting delegate, set "validator" to the address of the validator to vote on behalf of: +$ nibid tx oracle aggregate-prevote 1234 1234 (40000.0,BTC:USD)|(1.243,NIBI:USD) nibivaloper1... +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + salt := args[0] + exchangeRatesStr := args[1] + _, err = types.ParseExchangeRateTuples(exchangeRatesStr) + if err != nil { + return fmt.Errorf("given exchange_rates {%s} is not a valid format; exchange_rate should be formatted as DecCoins; %s", exchangeRatesStr, err.Error()) + } + + // Get from address + feeder := clientCtx.GetFromAddress() + + // By default, the feeder is voting on behalf of itself + validator := sdk.ValAddress(feeder) + + // Override validator if validator is given + if len(args) == 3 { + parsedVal, err := sdk.ValAddressFromBech32(args[2]) + if err != nil { + return errors.Wrap(err, "validator address is invalid") + } + + validator = parsedVal + } + + hash := types.GetAggregateVoteHash(salt, exchangeRatesStr, validator) + + msg := types.NewMsgAggregateExchangeRatePrevote(hash, feeder, validator) + if err = msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdAggregateExchangeRateVote will create a aggregateExchangeRateVote tx and sign it with the given key. +func GetCmdAggregateExchangeRateVote() *cobra.Command { + cmd := &cobra.Command{ + Use: "aggregate-vote [salt] [exchange-rates] [validator]", + Args: cobra.RangeArgs(2, 3), + Short: "Submit an oracle aggregate vote for the exchange_rates of Nibiru", + Long: strings.TrimSpace(` +Submit an aggregate vote for the exchange_rates of the proposed pairs. Companion to a prevote submitted in the previous vote period. + +$ nibid tx oracle aggregate-vote 1234 (40000.0,BTC:USD)|(1.243,NIBI:USD) + +where "BTC:USD, NIBI:USD" is the pairs, and "40000.0,1.243" is the exchange rates as decimal string. + +"salt" should match the salt used to generate the SHA256 hex in the aggregated pre-vote. + +If voting from a voting delegate, set "validator" to the address of the validator to vote on behalf of: +$ nibid tx oracle aggregate-vote 1234 (40000.0,BTC:USD)|(1.243,NIBI:USD) nibivaloper1.... +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + salt := args[0] + exchangeRatesStr := args[1] + _, err = types.ParseExchangeRateTuples(exchangeRatesStr) + if err != nil { + return fmt.Errorf("given exchange_rate {%s} is not a valid format; exchange rate should be formatted as DecCoin; %s", exchangeRatesStr, err.Error()) + } + + // Get from address + feeder := clientCtx.GetFromAddress() + + // By default, the feeder is voting on behalf of itself + validator := sdk.ValAddress(feeder) + + // Override validator if validator is given + if len(args) == 3 { + parsedVal, err := sdk.ValAddressFromBech32(args[2]) + if err != nil { + return errors.Wrap(err, "validator address is invalid") + } + validator = parsedVal + } + + msg := types.NewMsgAggregateExchangeRateVote(salt, exchangeRatesStr, feeder, validator) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/oracle/denoms/denoms.go b/x/oracle/denoms/denoms.go new file mode 100644 index 00000000..5256f86c --- /dev/null +++ b/x/oracle/denoms/denoms.go @@ -0,0 +1,20 @@ +package denoms + +const ( // stablecoins + USDC = "uusdc" + NUSD = "unusd" + USD = "uusd" + USDT = "uusdt" +) + +const ( // volatile assets + NIBI = "unibi" + BTC = "ubtc" + ETH = "ueth" + ATOM = "uatom" + OSMO = "uosmo" + AVAX = "uavax" + SOL = "usol" + BNB = "ubnb" + ADA = "uada" +) diff --git a/x/oracle/genesis.go b/x/oracle/genesis.go new file mode 100644 index 00000000..16ba1283 --- /dev/null +++ b/x/oracle/genesis.go @@ -0,0 +1,208 @@ +package oracle + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" +) + +// InitGenesis initialize default parameters +// and the keeper's address to pubkey map +func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState) { + for _, d := range data.FeederDelegations { + voter, err := sdk.ValAddressFromBech32(d.ValidatorAddress) + if err != nil { + panic(err) + } + + feeder, err := sdk.AccAddressFromBech32(d.FeederAddress) + if err != nil { + panic(err) + } + + err = keeper.FeederDelegations.Set(ctx, voter, feeder) + if err != nil { + panic(err) + } + } + + for _, ex := range data.ExchangeRates { + keeper.SetPrice(ctx, ex.Pair, ex.ExchangeRate) + } + + for _, missCounter := range data.MissCounters { + operator, err := sdk.ValAddressFromBech32(missCounter.ValidatorAddress) + if err != nil { + panic(err) + } + + err = keeper.MissCounters.Set(ctx, operator, missCounter.MissCounter) + if err != nil { + panic(err) + } + } + + for _, aggregatePrevote := range data.AggregateExchangeRatePrevotes { + valAddr, err := sdk.ValAddressFromBech32(aggregatePrevote.Voter) + if err != nil { + panic(err) + } + + err = keeper.Prevotes.Set(ctx, valAddr, aggregatePrevote) + if err != nil { + panic(err) + } + } + + for _, aggregateVote := range data.AggregateExchangeRateVotes { + valAddr, err := sdk.ValAddressFromBech32(aggregateVote.Voter) + if err != nil { + panic(err) + } + + err = keeper.Votes.Set(ctx, valAddr, aggregateVote) + if err != nil { + panic(err) + } + } + + if len(data.Pairs) > 0 { + for _, tt := range data.Pairs { + err := keeper.WhitelistedPairs.Set(ctx, tt) + if err != nil { + panic(err) + } + } + } else { + for _, item := range data.Params.Whitelist { + err := keeper.WhitelistedPairs.Set(ctx, item) + if err != nil { + panic(err) + } + } + } + + for _, pr := range data.Rewards { + err := keeper.Rewards.Set(ctx, pr.Id, pr) + if err != nil { + panic(err) + } + } + + // set last ID based on the last pair reward + if len(data.Rewards) != 0 { + err := keeper.RewardsID.Set(ctx, data.Rewards[len(data.Rewards)-1].Id) + if err != nil { + panic(err) + } + } + err := keeper.Params.Set(ctx, data.Params) + if err != nil { + panic(err) + } + + // check if the module account exists + moduleAcc := keeper.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) + if moduleAcc == nil { + panic(fmt.Sprintf("%s module account has not been set", types.ModuleName)) + } +} + +// ExportGenesis writes the current store values +// to a genesis file, which can be imported again +// with InitGenesis +func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState { + params, err := keeper.Params.Get(ctx) + if err != nil { + panic(err) + } + + feederDelegations := []types.FeederDelegation{} + err = keeper.FeederDelegations.Walk(ctx, nil, func(valBytes []byte, accBytes []byte) (bool, error) { + feederDelegations = append(feederDelegations, types.FeederDelegation{ + FeederAddress: sdk.AccAddress(accBytes).String(), + ValidatorAddress: sdk.ValAddress(valBytes).String(), + }) + return false, nil + }) + if err != nil { + panic(err) + } + + exchangeRates := []types.ExchangeRateTuple{} + err = keeper.ExchangeRates.Walk(ctx, nil, func(pair asset.Pair, price types.DatedPrice) (bool, error) { + exchangeRates = append(exchangeRates, types.ExchangeRateTuple{ + Pair: pair, + ExchangeRate: price.ExchangeRate, + }) + return false, nil + }) + if err != nil { + panic(err) + } + + missCounters := []types.MissCounter{} + err = keeper.MissCounters.Walk(ctx, nil, func(valAddrBytes []byte, counter uint64) (bool, error) { + missCounters = append(missCounters, types.MissCounter{ + ValidatorAddress: sdk.ValAddress(valAddrBytes).String(), + MissCounter: counter, + }) + return false, nil + }) + if err != nil { + panic(err) + } + + var pairs []asset.Pair + iter, err := keeper.WhitelistedPairs.Iterate(ctx, nil) + if err != nil { + panic(err) + } + keys, err := iter.Keys() + if err != nil { + panic(err) + } + pairs = append(pairs, keys...) + + prevotesIter, err := keeper.Prevotes.Iterate(ctx, nil) + if err != nil { + panic(err) + } + prevotes, err := prevotesIter.Values() + if err != nil { + panic(err) + } + + votesIter, err := keeper.Votes.Iterate(ctx, nil) + if err != nil { + panic(err) + } + votes, err := votesIter.Values() + if err != nil { + panic(err) + } + + rewardsIter, err := keeper.Rewards.Iterate(ctx, nil) + if err != nil { + panic(err) + } + rewards, err := rewardsIter.Values() + if err != nil { + panic(err) + } + + return types.NewGenesisState( + params, + exchangeRates, + feederDelegations, + missCounters, + prevotes, + votes, + pairs, + rewards, + ) +} diff --git a/x/oracle/genesis_test.go b/x/oracle/genesis_test.go new file mode 100644 index 00000000..e5d38856 --- /dev/null +++ b/x/oracle/genesis_test.go @@ -0,0 +1,166 @@ +package oracle_test + +import ( + "testing" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/x/oracle" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestExportInitGenesis(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(2)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + vals := chain.GetCurrentValSet().Validators + AccAddrs := make([]sdk.AccAddress, len(vals)) + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + AccAddrs[i] = sdk.AccAddress(vals[i].Address) + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, types.DefaultParams())) + require.NoError(t, keepers.OracleKeeper.FeederDelegations.Set(ctx, ValAddrs[0], AccAddrs[1])) + require.NoError(t, keepers.OracleKeeper.ExchangeRates.Set(ctx, "pair1:pair2", types.DatedPrice{ + ExchangeRate: math.LegacyNewDec(123), + CreationHeight: 0, + CreationTimeUnixMs: 0, + })) + require.NoError(t, keepers.OracleKeeper.Prevotes.Set(ctx, ValAddrs[0], types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash{123}, ValAddrs[0], uint64(2)))) + require.NoError(t, keepers.OracleKeeper.Votes.Set(ctx, ValAddrs[0], types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{{Pair: "foo", ExchangeRate: math.LegacyNewDec(123)}}, ValAddrs[0]))) + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Set(ctx, "pair1:pair1")) + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Set(ctx, "pair2:pair2")) + require.NoError(t, keepers.OracleKeeper.MissCounters.Set(ctx, ValAddrs[0], 10)) + require.NoError(t, keepers.OracleKeeper.Rewards.Set(ctx, 0, types.Rewards{ + Id: 0, + VotePeriods: 100, + Coins: sdk.NewCoins(sdk.NewInt64Coin("test", 1000)), + })) + genesis := oracle.ExportGenesis(ctx, keepers.OracleKeeper) + + chain = e2eTesting.NewTestChain(t, 2) + keepers = chain.GetApp().Keepers + ctx = chain.GetContext() + oracle.InitGenesis(ctx, keepers.OracleKeeper, genesis) + newGenesis := oracle.ExportGenesis(ctx, keepers.OracleKeeper) + + require.Equal(t, genesis, newGenesis) +} + +func TestInitGenesis(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(1)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + vals := chain.GetCurrentValSet().Validators + AccAddrs := make([]sdk.AccAddress, len(vals)) + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + AccAddrs[i] = sdk.AccAddress(vals[i].Address) + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + genesis := types.DefaultGenesisState() + require.NotPanics(t, func() { + oracle.InitGenesis(ctx, keepers.OracleKeeper, genesis) + }) + + genesis.FeederDelegations = []types.FeederDelegation{{ + FeederAddress: AccAddrs[0].String(), + ValidatorAddress: "invalid", + }} + + require.Panics(t, func() { + oracle.InitGenesis(ctx, keepers.OracleKeeper, genesis) + }) + + genesis.FeederDelegations = []types.FeederDelegation{{ + FeederAddress: "invalid", + ValidatorAddress: ValAddrs[0].String(), + }} + + require.Panics(t, func() { + oracle.InitGenesis(ctx, keepers.OracleKeeper, genesis) + }) + + genesis.FeederDelegations = []types.FeederDelegation{{ + FeederAddress: AccAddrs[0].String(), + ValidatorAddress: ValAddrs[0].String(), + }} + + genesis.MissCounters = []types.MissCounter{ + { + ValidatorAddress: "invalid", + MissCounter: 10, + }, + } + + require.Panics(t, func() { + oracle.InitGenesis(ctx, keepers.OracleKeeper, genesis) + }) + + genesis.MissCounters = []types.MissCounter{ + { + ValidatorAddress: ValAddrs[0].String(), + MissCounter: 10, + }, + } + + genesis.AggregateExchangeRatePrevotes = []types.AggregateExchangeRatePrevote{ + { + Hash: "hash", + Voter: "invalid", + SubmitBlock: 100, + }, + } + + require.Panics(t, func() { + oracle.InitGenesis(ctx, keepers.OracleKeeper, genesis) + }) + + genesis.AggregateExchangeRatePrevotes = []types.AggregateExchangeRatePrevote{ + { + Hash: "hash", + Voter: ValAddrs[0].String(), + SubmitBlock: 100, + }, + } + + genesis.AggregateExchangeRateVotes = []types.AggregateExchangeRateVote{ + { + ExchangeRateTuples: []types.ExchangeRateTuple{ + { + Pair: "nibi:usd", + ExchangeRate: math.LegacyNewDec(10), + }, + }, + Voter: "invalid", + }, + } + + require.Panics(t, func() { + oracle.InitGenesis(ctx, keepers.OracleKeeper, genesis) + }) + + genesis.AggregateExchangeRateVotes = []types.AggregateExchangeRateVote{ + { + ExchangeRateTuples: []types.ExchangeRateTuple{ + { + Pair: "nibi:usd", + ExchangeRate: math.LegacyNewDec(10), + }, + }, + Voter: ValAddrs[0].String(), + }, + } + + require.NotPanics(t, func() { + oracle.InitGenesis(ctx, keepers.OracleKeeper, genesis) + }) +} diff --git a/x/oracle/keeper/ballot.go b/x/oracle/keeper/ballot.go new file mode 100644 index 00000000..ace8485e --- /dev/null +++ b/x/oracle/keeper/ballot.go @@ -0,0 +1,188 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "cosmossdk.io/math" + + "github.com/archway-network/archway/types/set" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/types" +) + +// GroupVotesByPair takes a collection of votes and groups them by their +// associated asset pair. This method only considers votes from active validators +// and disregards votes from validators that are not in the provided validator set. +// +// Note that any abstain votes (votes with a non-positive exchange rate) are +// assigned zero vote power. This function then returns a map where each +// asset pair is associated with its collection of ExchangeRateVotes. +func (k Keeper) GroupVotesByPair( + ctx sdk.Context, + validatorPerformances types.ValidatorPerformances, +) map[asset.Pair]types.ExchangeRateVotes { + pairVotes := map[asset.Pair]types.ExchangeRateVotes{} + + err := k.Votes.Walk(ctx, nil, func(voterAddrBytes []byte, aggregateVote types.AggregateExchangeRateVote) (bool, error) { + voterAddr := sdk.ValAddress(voterAddrBytes) + // skip votes from inactive validators + validatorPerformance, exists := validatorPerformances[aggregateVote.Voter] + if !exists { + return false, nil + } + + for _, tuple := range aggregateVote.ExchangeRateTuples { + power := validatorPerformance.Power + if !tuple.ExchangeRate.IsPositive() { + // Make the power of abstain vote zero + power = 0 + } + + pairVotes[tuple.Pair] = append( + pairVotes[tuple.Pair], + types.NewExchangeRateVote( + tuple.ExchangeRate, + tuple.Pair, + voterAddr, + power, + ), + ) + } + + return false, nil + }) + if err != nil { + panic(err) + } + + return pairVotes +} + +// ClearVotesAndPrevotes clears all tallied prevotes and votes from the store +func (k Keeper) ClearVotesAndPrevotes(ctx sdk.Context, votePeriod uint64) { + // Clear all aggregate prevotes + _ = k.Prevotes.Walk(ctx, nil, func(valAddrBytes []byte, aggregatePrevote types.AggregateExchangeRatePrevote) (bool, error) { + valAddr := sdk.ValAddress(valAddrBytes) + if ctx.BlockHeight() >= int64(aggregatePrevote.SubmitBlock+votePeriod) { + err := k.Prevotes.Remove(ctx, valAddr) + if err != nil { + k.Logger(ctx).Error("failed to delete prevote", "error", err) + } + } + return false, nil + }) + + // Clear all aggregate votes + err := k.Votes.Clear(ctx, nil) + if err != nil { + k.Logger(ctx).Error("failed to clear votes", "error", err) + } +} + +// IsPassingVoteThreshold votes is passing the threshold amount of voting power +func IsPassingVoteThreshold( + votes types.ExchangeRateVotes, thresholdVotingPower math.Int, minVoters uint64, +) error { + totalPower := math.NewInt(votes.Power()) + if totalPower.IsZero() { + return fmt.Errorf("total voting power is 0") + } + + if totalPower.LT(thresholdVotingPower) { + return fmt.Errorf("total voting power is less then thresholdVotingPower (%g)", thresholdVotingPower) + } + + if votes.NumValidVoters() < minVoters { + return fmt.Errorf("number of validators (%d) is less then minVoters (%d)", votes.NumValidVoters(), minVoters) + } + + return nil +} + +// RemoveInvalidVotes removes the votes which have not reached the vote +// threshold or which are not part of the whitelisted pairs anymore: example +// when params change during a vote period but some votes were already made. +// +// ALERT: This function mutates the pairVotes map, it removes the votes for +// the pair which is not passing the threshold or which is not whitelisted +// anymore. +func (k Keeper) RemoveInvalidVotes( + ctx sdk.Context, + pairVotes map[asset.Pair]types.ExchangeRateVotes, + whitelistedPairs set.Set[asset.Pair], +) { + boundTokens, err := k.StakingKeeper.TotalBondedTokens(ctx) + if err != nil { + panic(err) + } + totalBondedPower := sdk.TokensToConsensusPower( + boundTokens, + k.StakingKeeper.PowerReduction(ctx), + ) + + for pair, votes := range pairVotes { + // If pair is not whitelisted, or the votes for it has failed, then skip + // and remove it from pairBallotsMap for iteration efficiency + if !whitelistedPairs.Has(pair) { + delete(pairVotes, pair) + } + + // If the votes is not passed, remove it from the whitelistedPairs set + // to prevent slashing validators who did valid vote. + if err := IsPassingVoteThreshold( + votes, + k.VoteThreshold(ctx).MulInt64(totalBondedPower).RoundInt(), + k.MinVoters(ctx), + ); err != nil { + whitelistedPairs.Remove(pair) + delete(pairVotes, pair) + continue + } + } +} + +// Tally calculates the median and returns it. Sets the set of voters to be +// rewarded, i.e. voted within a reasonable spread from the weighted median to +// the store. +// +// ALERT: This function mutates validatorPerformances slice based on the votes +// made by the validators. +func Tally( + votes types.ExchangeRateVotes, + rewardBand math.LegacyDec, + validatorPerformances types.ValidatorPerformances, +) math.LegacyDec { + weightedMedian := votes.WeightedMedianWithAssertion() + standardDeviation := votes.StandardDeviation(weightedMedian) + rewardSpread := weightedMedian.Mul(rewardBand.QuoInt64(2)) + + if standardDeviation.GT(rewardSpread) { + rewardSpread = standardDeviation + } + + for _, v := range votes { + // Filter votes winners & abstain voters + isInsideSpread := v.ExchangeRate.GTE(weightedMedian.Sub(rewardSpread)) && + v.ExchangeRate.LTE(weightedMedian.Add(rewardSpread)) + isAbstainVote := !v.ExchangeRate.IsPositive() // strictly less than zero, don't want to include zero + isMiss := !isInsideSpread && !isAbstainVote + + validatorPerformance := validatorPerformances[v.Voter.String()] + + switch { + case isInsideSpread: + validatorPerformance.RewardWeight += v.Power + validatorPerformance.WinCount++ + case isMiss: + validatorPerformance.MissCount++ + case isAbstainVote: + validatorPerformance.AbstainCount++ + } + + validatorPerformances[v.Voter.String()] = validatorPerformance + } + + return weightedMedian +} diff --git a/x/oracle/keeper/ballot_test.go b/x/oracle/keeper/ballot_test.go new file mode 100644 index 00000000..004c6745 --- /dev/null +++ b/x/oracle/keeper/ballot_test.go @@ -0,0 +1,381 @@ +package keeper_test + +import ( + "sort" + "testing" + + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + fuzz "github.com/google/gofuzz" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/types/set" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestGroupVotesByPair(t *testing.T) { + power := int64(100) + + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(3), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + _, err := keepers.StakingKeeper.EndBlocker(ctx) + require.NoError(t, err) + + pairBtc := asset.Registry.Pair(denoms.BTC, denoms.NUSD) + pairEth := asset.Registry.Pair(denoms.ETH, denoms.NUSD) + btcVotes := types.ExchangeRateVotes{ + {Pair: pairBtc, ExchangeRate: math.LegacyNewDec(17), Voter: ValAddrs[0], Power: power}, + {Pair: pairBtc, ExchangeRate: math.LegacyNewDec(10), Voter: ValAddrs[1], Power: power}, + {Pair: pairBtc, ExchangeRate: math.LegacyNewDec(6), Voter: ValAddrs[2], Power: power}, + } + ethVotes := types.ExchangeRateVotes{ + {Pair: pairEth, ExchangeRate: math.LegacyNewDec(1_000), Voter: ValAddrs[0], Power: power}, + {Pair: pairEth, ExchangeRate: math.LegacyNewDec(1_300), Voter: ValAddrs[1], Power: power}, + {Pair: pairEth, ExchangeRate: math.LegacyNewDec(2_000), Voter: ValAddrs[2], Power: power}, + } + + for i, v := range btcVotes { + require.NoError(t, keepers.OracleKeeper.Votes.Set( + ctx, + ValAddrs[i], + types.NewAggregateExchangeRateVote( + types.ExchangeRateTuples{ + {Pair: v.Pair, ExchangeRate: v.ExchangeRate}, + {Pair: ethVotes[i].Pair, ExchangeRate: ethVotes[i].ExchangeRate}, + }, + ValAddrs[i], + ), + )) + } + + // organize votes by pair + pairVotes := keepers.OracleKeeper.GroupVotesByPair(ctx, types.ValidatorPerformances{ + ValAddrs[0].String(): { + Power: power, + WinCount: 0, + ValAddress: ValAddrs[0], + }, + ValAddrs[1].String(): { + Power: power, + WinCount: 0, + ValAddress: ValAddrs[1], + }, + ValAddrs[2].String(): { + Power: power, + WinCount: 0, + ValAddress: ValAddrs[2], + }, + }) + + // sort each votes for comparison + sort.Sort(btcVotes) + sort.Sort(ethVotes) + sort.Sort(pairVotes[asset.Registry.Pair(denoms.BTC, denoms.NUSD)]) + sort.Sort(pairVotes[asset.Registry.Pair(denoms.ETH, denoms.NUSD)]) + + require.Equal(t, btcVotes, pairVotes[asset.Registry.Pair(denoms.BTC, denoms.NUSD)]) + require.Equal(t, ethVotes, pairVotes[asset.Registry.Pair(denoms.ETH, denoms.NUSD)]) +} + +func TestClearVotesAndPrevotes(t *testing.T) { + power := int64(100) + + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(3)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + _, err := keepers.StakingKeeper.EndBlocker(ctx) + require.NoError(t, err) + + btcVotes := types.ExchangeRateVotes{ + types.NewExchangeRateVote(math.LegacyNewDec(17), asset.Registry.Pair(denoms.BTC, denoms.NUSD), ValAddrs[0], power), + types.NewExchangeRateVote(math.LegacyNewDec(10), asset.Registry.Pair(denoms.BTC, denoms.NUSD), ValAddrs[1], power), + types.NewExchangeRateVote(math.LegacyNewDec(6), asset.Registry.Pair(denoms.BTC, denoms.NUSD), ValAddrs[2], power), + } + ethVotes := types.ExchangeRateVotes{ + types.NewExchangeRateVote(math.LegacyNewDec(1000), asset.Registry.Pair(denoms.ETH, denoms.NUSD), ValAddrs[0], power), + types.NewExchangeRateVote(math.LegacyNewDec(1300), asset.Registry.Pair(denoms.ETH, denoms.NUSD), ValAddrs[1], power), + types.NewExchangeRateVote(math.LegacyNewDec(2000), asset.Registry.Pair(denoms.ETH, denoms.NUSD), ValAddrs[2], power), + } + + for i := range btcVotes { + require.NoError(t, keepers.OracleKeeper.Prevotes.Set(ctx, ValAddrs[i], types.AggregateExchangeRatePrevote{ + Hash: "", + Voter: ValAddrs[i].String(), + SubmitBlock: uint64(ctx.BlockHeight()), + })) + + require.NoError(t, keepers.OracleKeeper.Votes.Set(ctx, ValAddrs[i], + types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{ + {Pair: btcVotes[i].Pair, ExchangeRate: btcVotes[i].ExchangeRate}, + {Pair: ethVotes[i].Pair, ExchangeRate: ethVotes[i].ExchangeRate}, + }, ValAddrs[i]))) + } + + keepers.OracleKeeper.ClearVotesAndPrevotes(ctx, 10) + + prevoteCounterIter, err := keepers.OracleKeeper.Prevotes.Iterate(ctx, nil) + require.NoError(t, err) + prevoteCounterKeys, err := prevoteCounterIter.Keys() + require.NoError(t, err) + prevoteCounter := len(prevoteCounterKeys) + + voteCounterIter, err := keepers.OracleKeeper.Votes.Iterate(ctx, nil) + require.NoError(t, err) + voteCounterKeys, err := voteCounterIter.Keys() + require.NoError(t, err) + voteCounter := len(voteCounterKeys) + + require.Equal(t, prevoteCounter, 3) + require.Equal(t, voteCounter, 0) + + // vote period starts at b=10, clear the votes at b=0 and below. + keepers.OracleKeeper.ClearVotesAndPrevotes(ctx.WithBlockHeight(ctx.BlockHeight()+10), 10) + prevoteCounterIter, err = keepers.OracleKeeper.Prevotes.Iterate(ctx, nil) + require.NoError(t, err) + prevoteCounterKeys, err = prevoteCounterIter.Keys() + require.NoError(t, err) + prevoteCounter = len(prevoteCounterKeys) + require.Equal(t, prevoteCounter, 0) +} + +func TestFuzzTally(t *testing.T) { + validators := map[string]int64{} + + f := fuzz.New().NilChance(0).Funcs( + func(e *math.LegacyDec, c fuzz.Continue) { + *e = math.LegacyNewDec(c.Int63()) + }, + func(e *map[string]int64, c fuzz.Continue) { + numValidators := c.Intn(100) + 5 + + for i := 0; i < numValidators; i++ { + (*e)[sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()).String()] = c.Int63n(100) + } + }, + func(e *types.ValidatorPerformances, c fuzz.Continue) { + for validator, power := range validators { + addr, err := sdk.ValAddressFromBech32(validator) + require.NoError(t, err) + (*e)[validator] = types.NewValidatorPerformance(power, addr) + } + }, + func(e *types.ExchangeRateVotes, c fuzz.Continue) { + votes := types.ExchangeRateVotes{} + for addr, power := range validators { + addr, _ := sdk.ValAddressFromBech32(addr) + + var rate math.LegacyDec + c.Fuzz(&rate) + + votes = append(votes, types.NewExchangeRateVote(rate, asset.NewPair(c.RandString(), c.RandString()), addr, power)) + } + + *e = votes + }, + ) + + // set random pairs and validators + f.Fuzz(&validators) + + claimMap := types.ValidatorPerformances{} + f.Fuzz(&claimMap) + + votes := types.ExchangeRateVotes{} + f.Fuzz(&votes) + + var rewardBand math.LegacyDec + f.Fuzz(&rewardBand) + + require.NotPanics(t, func() { + keeper.Tally(votes, rewardBand, claimMap) + }) +} + +type VoteMap = map[asset.Pair]types.ExchangeRateVotes + +func TestRemoveInvalidBallots(t *testing.T) { + testCases := []struct { + name string + voteMap VoteMap + }{ + { + name: "empty key, empty votes", + voteMap: VoteMap{ + "": types.ExchangeRateVotes{}, + }, + }, + { + name: "nonempty key, empty votes", + voteMap: VoteMap{ + "xxx": types.ExchangeRateVotes{}, + }, + }, + { + name: "nonempty keys, empty votes", + voteMap: VoteMap{ + "xxx": types.ExchangeRateVotes{}, + "abc123": types.ExchangeRateVotes{}, + }, + }, + { + name: "mixed empty keys, empty votes", + voteMap: VoteMap{ + "xxx": types.ExchangeRateVotes{}, + "": types.ExchangeRateVotes{}, + "abc123": types.ExchangeRateVotes{}, + "0x": types.ExchangeRateVotes{}, + }, + }, + { + name: "empty key, nonempty votes, not whitelisted", + voteMap: VoteMap{ + "": types.ExchangeRateVotes{ + {Pair: "", ExchangeRate: math.LegacyZeroDec(), Voter: sdk.ValAddress{}, Power: 0}, + }, + }, + }, + { + name: "nonempty key, nonempty votes, whitelisted", + voteMap: VoteMap{ + "x": types.ExchangeRateVotes{ + {Pair: "x", ExchangeRate: math.LegacyZeroDec(), Voter: sdk.ValAddress{123}, Power: 5}, + }, + asset.Registry.Pair(denoms.BTC, denoms.NUSD): types.ExchangeRateVotes{ + {Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), ExchangeRate: math.LegacyZeroDec(), Voter: sdk.ValAddress{123}, Power: 5}, + }, + asset.Registry.Pair(denoms.ETH, denoms.NUSD): types.ExchangeRateVotes{ + {Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), ExchangeRate: math.LegacyZeroDec(), Voter: sdk.ValAddress{123}, Power: 5}, + }, + }, + }, + } + + for i, testCase := range testCases { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + chain := e2eTesting.NewTestChain(t, i) + keepers := chain.GetApp().Keepers + assert.NotPanics(t, func() { + keepers.OracleKeeper.RemoveInvalidVotes(chain.GetContext(), tc.voteMap, set.New[asset.Pair]( + asset.NewPair(denoms.BTC, denoms.NUSD), + asset.NewPair(denoms.ETH, denoms.NUSD), + )) + }, "voteMap: %v", tc.voteMap) + }) + } +} + +func TestFuzzPickReferencePair(t *testing.T) { + var pairs []asset.Pair + + f := fuzz.New().NilChance(0).Funcs( + func(e *asset.Pair, c fuzz.Continue) { + *e = asset.NewPair(RandLetters(5), RandLetters(5)) + }, + func(e *[]asset.Pair, c fuzz.Continue) { + numPairs := c.Intn(100) + 5 + + for i := 0; i < numPairs; i++ { + *e = append(*e, asset.NewPair(RandLetters(5), RandLetters(5))) + } + }, + func(e *math.LegacyDec, c fuzz.Continue) { + *e = math.LegacyNewDec(c.Int63()) + }, + func(e *map[asset.Pair]math.LegacyDec, c fuzz.Continue) { + for _, pair := range pairs { + var rate math.LegacyDec + c.Fuzz(&rate) + + (*e)[pair] = rate + } + }, + func(e *map[string]int64, c fuzz.Continue) { + for i := 0; i < 5+c.Intn(100); i++ { + (*e)[sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()).String()] = int64(c.Intn(100) + 1) + } + }, + func(e *map[asset.Pair]types.ExchangeRateVotes, c fuzz.Continue) { + validators := map[string]int64{} + c.Fuzz(&validators) + + for _, pair := range pairs { + votes := types.ExchangeRateVotes{} + + for addr, power := range validators { + addr, _ := sdk.ValAddressFromBech32(addr) + + var rate math.LegacyDec + c.Fuzz(&rate) + + votes = append(votes, types.NewExchangeRateVote(rate, pair, addr, power)) + } + + (*e)[pair] = votes + } + }, + ) + + // set random pairs + f.Fuzz(&pairs) + + chain := e2eTesting.NewTestChain(t, 1) + + // test OracleKeeper.Pairs.Insert + voteTargets := set.Set[asset.Pair]{} + f.Fuzz(&voteTargets) + whitelistedPairs := make(set.Set[asset.Pair]) + + for key := range voteTargets { + whitelistedPairs.Add(key) + } + + // test OracleKeeper.RemoveInvalidBallots + voteMap := map[asset.Pair]types.ExchangeRateVotes{} + f.Fuzz(&voteMap) + + assert.NotPanics(t, func() { + chain.GetApp().Keepers.OracleKeeper.RemoveInvalidVotes(chain.GetContext(), voteMap, whitelistedPairs) + }, "voteMap: %v", voteMap) +} + +func TestZeroBallotPower(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(3)) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + btcVotess := types.ExchangeRateVotes{ + types.NewExchangeRateVote(math.LegacyNewDec(17), asset.Registry.Pair(denoms.BTC, denoms.NUSD), ValAddrs[0], 0), + types.NewExchangeRateVote(math.LegacyNewDec(10), asset.Registry.Pair(denoms.BTC, denoms.NUSD), ValAddrs[1], 0), + types.NewExchangeRateVote(math.LegacyNewDec(6), asset.Registry.Pair(denoms.BTC, denoms.NUSD), ValAddrs[2], 0), + } + + assert.Error(t, keeper.IsPassingVoteThreshold(btcVotess, math.ZeroInt(), 0)) +} diff --git a/x/oracle/keeper/keeper.go b/x/oracle/keeper/keeper.go new file mode 100644 index 00000000..23ab0dcc --- /dev/null +++ b/x/oracle/keeper/keeper.go @@ -0,0 +1,240 @@ +package keeper + +import ( + "context" + "fmt" + "time" + + storetypes "cosmossdk.io/store/types" + + sdkerrors "cosmossdk.io/errors" + "cosmossdk.io/log" + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + "cosmossdk.io/collections" + + "github.com/archway-network/archway/internal/collcompat" + archcodec "github.com/archway-network/archway/types/codec" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/types" +) + +// Keeper of the oracle store +type Keeper struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + + AccountKeeper types.AccountKeeper + bankKeeper types.BankKeeper + distrKeeper types.DistributionKeeper + StakingKeeper types.StakingKeeper + slashingKeeper types.SlashingKeeper + + distrModuleName string + + // Module parameters + Params collections.Item[types.Params] + ExchangeRates collections.Map[asset.Pair, types.DatedPrice] + FeederDelegations collections.Map[[]byte, []byte] + MissCounters collections.Map[[]byte, uint64] + Prevotes collections.Map[[]byte, types.AggregateExchangeRatePrevote] + Votes collections.Map[[]byte, types.AggregateExchangeRateVote] + + // PriceSnapshots maps types.PriceSnapshot to the asset.Pair of the snapshot and the creation timestamp as keys.Uint64Key. + PriceSnapshots collections.Map[ + collections.Pair[asset.Pair, time.Time], + types.PriceSnapshot] + WhitelistedPairs collections.KeySet[asset.Pair] + Rewards collections.Map[uint64, types.Rewards] + RewardsID collections.Sequence +} + +// NewKeeper constructs a new keeper for oracle +func NewKeeper( + cdc codec.BinaryCodec, + storeKey storetypes.StoreKey, + + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, + distrKeeper types.DistributionKeeper, + stakingKeeper types.StakingKeeper, + slashingKeeper types.SlashingKeeper, + + distrName string, +) Keeper { + // ensure oracle module account is set + if addr := accountKeeper.GetModuleAddress(types.ModuleName); addr == nil { + panic(fmt.Sprintf("%s module account has not been set", types.ModuleName)) + } + + sb := collections.NewSchemaBuilder(collcompat.NewKVStoreService(storeKey)) + + k := Keeper{ + cdc: cdc, + storeKey: storeKey, + AccountKeeper: accountKeeper, + bankKeeper: bankKeeper, + distrKeeper: distrKeeper, + StakingKeeper: stakingKeeper, + slashingKeeper: slashingKeeper, + distrModuleName: distrName, + Params: collections.NewItem(sb, collections.NewPrefix(11), "Params", collcompat.ProtoValue[types.Params](cdc)), + ExchangeRates: collections.NewMap(sb, collections.NewPrefix(1), "ExchangeRates", asset.PairKeyEncoder, collcompat.ProtoValue[types.DatedPrice](cdc)), + PriceSnapshots: collections.NewMap(sb, collections.NewPrefix(10), "PriceSnapshots", collections.PairKeyCodec(asset.PairKeyEncoder, archcodec.TimeKeyEncoder), collcompat.ProtoValue[types.PriceSnapshot](cdc)), + FeederDelegations: collections.NewMap(sb, collections.NewPrefix(2), "FeederDelegations", collections.BytesKey, collections.BytesValue), + MissCounters: collections.NewMap(sb, collections.NewPrefix(3), "MissCounters", collections.BytesKey, collections.Uint64Value), + Prevotes: collections.NewMap(sb, collections.NewPrefix(4), "Prevotes", collections.BytesKey, collcompat.ProtoValue[types.AggregateExchangeRatePrevote](cdc)), + Votes: collections.NewMap(sb, collections.NewPrefix(5), "Votes", collections.BytesKey, collcompat.ProtoValue[types.AggregateExchangeRateVote](cdc)), + WhitelistedPairs: collections.NewKeySet(sb, collections.NewPrefix(6), "WhitelistedPairs", asset.PairKeyEncoder), + Rewards: collections.NewMap(sb, collections.NewPrefix(7), "Rewards", collections.Uint64Key, collcompat.ProtoValue[types.Rewards](cdc)), + RewardsID: collections.NewSequence(sb, collections.NewPrefix(9), "RewardsID"), + } + return k +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +// ValidateFeeder return the given feeder is allowed to feed the message or not +func (k Keeper) ValidateFeeder( + ctx context.Context, feederAddr sdk.AccAddress, validatorAddr sdk.ValAddress, +) error { + // A validator delegates price feeder consent to itself by default. + // Thus, we only need to verify consent for price feeder addresses that don't + // match the validator address. + if !feederAddr.Equals(validatorAddr) { + delegateStr, err := k.FeederDelegations.Get( + sdk.UnwrapSDKContext(ctx), + validatorAddr, + ) + var delegate sdk.Address + if err == nil { + delegate = sdk.AccAddress(delegateStr) + } else { + delegate = sdk.AccAddress(validatorAddr) + } + if !delegate.Equals(feederAddr) { + return sdkerrors.Wrapf( + types.ErrNoVotingPermission, + "wanted: %s, got: %s", delegate.String(), feederAddr.String()) + } + } + + // Check that the given validator is in the active set for consensus. + val, err := k.StakingKeeper.Validator(ctx, validatorAddr) + if err != nil { + return sdkerrors.Wrapf( + err, + "failed to get validator %s", + validatorAddr.String(), + ) + } + if !val.IsBonded() { + return sdkerrors.Wrapf( + fmt.Errorf("Invalid Validator Status"), + "validator %s is not active set", + validatorAddr.String(), + ) + } + + return nil +} + +func (k Keeper) GetExchangeRateTwap(ctx sdk.Context, pair asset.Pair) (price math.LegacyDec, err error) { + params, err := k.Params.Get(ctx) + if err != nil { + return math.LegacyOneDec().Neg(), err + } + + snapshotsIter, err := k.PriceSnapshots.Iterate( + ctx, + collections.NewPrefixedPairRange[asset.Pair, time.Time](pair). + StartInclusive( + ctx.BlockTime().Add(-1*params.TwapLookbackWindow)). + EndInclusive( + ctx.BlockTime()), + ) + if err != nil { + return math.LegacyOneDec().Neg(), err + } + + snapshots, err := snapshotsIter.Values() + if err != nil { + return math.LegacyOneDec().Neg(), err + } + + if len(snapshots) == 0 { + // if there are no snapshots, return -1 for the price + return math.LegacyOneDec().Neg(), types.ErrNoValidTWAP.Wrapf("no snapshots for pair %s", pair.String()) + } + + if len(snapshots) == 1 { + return snapshots[0].Price, nil + } + + firstTimestampMs := snapshots[0].TimestampMs + if firstTimestampMs > ctx.BlockTime().UnixMilli() { + // should never happen, or else we have corrupted state + return math.LegacyOneDec().Neg(), types.ErrNoValidTWAP.Wrapf( + "Possible corrupted state. First timestamp %d is after current blocktime %d", firstTimestampMs, ctx.BlockTime().UnixMilli()) + } + + if firstTimestampMs == ctx.BlockTime().UnixMilli() { + // shouldn't happen because we check for len(snapshots) == 1, but if it does, return the first snapshot price + return snapshots[0].Price, nil + } + + cumulativePrice := math.LegacyZeroDec() + for i, s := range snapshots { + var nextTimestampMs int64 + if i == len(snapshots)-1 { + // if we're at the last snapshot, then consider that price as ongoing until the current blocktime + nextTimestampMs = ctx.BlockTime().UnixMilli() + } else { + nextTimestampMs = snapshots[i+1].TimestampMs + } + + price := s.Price.MulInt64(nextTimestampMs - s.TimestampMs) + cumulativePrice = cumulativePrice.Add(price) + } + + return cumulativePrice.QuoInt64(ctx.BlockTime().UnixMilli() - firstTimestampMs), nil +} + +func (k Keeper) GetExchangeRate(ctx sdk.Context, pair asset.Pair) (price math.LegacyDec, err error) { + exchangeRate, err := k.ExchangeRates.Get(ctx, pair) + price = exchangeRate.ExchangeRate + return +} + +// SetPrice sets the price for a pair as well as the price snapshot. +func (k Keeper) SetPrice(ctx sdk.Context, pair asset.Pair, price math.LegacyDec) { + if err := k.ExchangeRates.Set(ctx, pair, types.DatedPrice{ + ExchangeRate: price, + CreationHeight: ctx.BlockHeight(), + CreationTimeUnixMs: uint64(ctx.BlockTime().UnixMilli()), + }); err != nil { + ctx.Logger().Error("failed to set DatedPrice", "pair", pair, "error", err) + } + + key := collections.Join(pair, ctx.BlockTime()) + timestampMs := ctx.BlockTime().UnixMilli() + if err := k.PriceSnapshots.Set(ctx, key, types.PriceSnapshot{ + Pair: pair, + Price: price, + TimestampMs: timestampMs, + }); err != nil { + ctx.Logger().Error("failed to set PriceSnapshot", "pair", pair, "error", err) + } + if err := ctx.EventManager().EmitTypedEvent(&types.EventPriceUpdate{ + Pair: pair.String(), + Price: price, + TimestampMs: timestampMs, + }); err != nil { + ctx.Logger().Error("failed to emit OraclePriceUpdate", "pair", pair, "error", err) + } +} diff --git a/x/oracle/keeper/keeper_test.go b/x/oracle/keeper/keeper_test.go new file mode 100644 index 00000000..fc814b37 --- /dev/null +++ b/x/oracle/keeper/keeper_test.go @@ -0,0 +1,73 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" +) + +func TestValidateFeeder(t *testing.T) { + // initial setup + accNum := 3 + + amt := sdk.TokensFromConsensusPower(50, sdk.DefaultPowerReduction) + InitTokens := sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction) + + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(accNum), + e2eTesting.WithGenAccounts(accNum), + e2eTesting.WithBondAmount(amt.String()), + e2eTesting.WithGenDefaultCoinBalance(InitTokens.String()), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + AccAddrs := make([]sdk.AccAddress, accNum) + ValAddrs := make([]sdk.ValAddress, accNum) + for i := 0; i < accNum; i++ { + AccAddrs[i] = chain.GetAccount(i).Address + } + for i, val := range chain.GetCurrentValSet().Validators { + ValAddrs[i] = sdk.ValAddress(val.Address) + } + + _, err := keepers.StakingKeeper.EndBlocker(ctx) + require.NoError(t, err) + + stakingparams, err := keepers.StakingKeeper.GetParams(ctx) + require.NoError(t, err) + require.Equal( + t, + sdk.NewCoins(sdk.NewCoin(stakingparams.BondDenom, InitTokens.Sub(amt))), + keepers.BankKeeper.GetAllBalances(ctx, AccAddrs[0]), + ) + validator, err := keepers.StakingKeeper.GetValidator(ctx, ValAddrs[0]) + require.NoError(t, err) + require.Equal(t, amt, validator.GetBondedTokens()) + require.Equal( + t, + sdk.NewCoins(sdk.NewCoin(stakingparams.BondDenom, InitTokens.Sub(amt))), + keepers.BankKeeper.GetAllBalances(ctx, AccAddrs[1]), + ) + validator1, err := keepers.StakingKeeper.GetValidator(ctx, ValAddrs[1]) + require.NoError(t, err) + require.Equal(t, amt, validator1.GetBondedTokens()) + + // test self delegation + require.NoError(t, keepers.OracleKeeper.ValidateFeeder(ctx, sdk.AccAddress(ValAddrs[0]), ValAddrs[0])) + require.NoError(t, keepers.OracleKeeper.ValidateFeeder(ctx, sdk.AccAddress(ValAddrs[1]), ValAddrs[1])) + + // delegate works + require.NoError(t, keepers.OracleKeeper.FeederDelegations.Set(ctx, ValAddrs[0], AccAddrs[1])) + require.NoError(t, keepers.OracleKeeper.ValidateFeeder(ctx, AccAddrs[1], ValAddrs[0])) + require.Error(t, keepers.OracleKeeper.ValidateFeeder(ctx, AccAddrs[2], ValAddrs[0])) + + // only active validators can do oracle votes + validator.Status = stakingtypes.Unbonded + require.NoError(t, keepers.StakingKeeper.SetValidator(ctx, validator)) + require.Error(t, keepers.OracleKeeper.ValidateFeeder(ctx, AccAddrs[1], ValAddrs[0])) +} diff --git a/x/oracle/keeper/msg_server.go b/x/oracle/keeper/msg_server.go new file mode 100644 index 00000000..880f87f5 --- /dev/null +++ b/x/oracle/keeper/msg_server.go @@ -0,0 +1,184 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/types/errors" + + sdkerrors "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/archway-network/archway/x/oracle/types" +) + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the oracle MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +func (ms msgServer) AggregateExchangeRatePrevote( + goCtx context.Context, + msg *types.MsgAggregateExchangeRatePrevote, +) (*types.MsgAggregateExchangeRatePrevoteResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + valAddr, err := sdk.ValAddressFromBech32(msg.Validator) + if err != nil { + return nil, err + } + + feederAddr, err := sdk.AccAddressFromBech32(msg.Feeder) + if err != nil { + return nil, err + } + + if err := ms.ValidateFeeder(ctx, feederAddr, valAddr); err != nil { + return nil, err + } + + // Convert hex string to votehash + voteHash, err := types.AggregateVoteHashFromHexString(msg.Hash) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrInvalidHash, err.Error()) + } + + if err := ms.Keeper.Prevotes.Set(ctx, valAddr, types.NewAggregateExchangeRatePrevote(voteHash, valAddr, uint64(ctx.BlockHeight()))); err != nil { + return nil, err + } + + err = ctx.EventManager().EmitTypedEvent(&types.EventAggregatePrevote{ + Validator: msg.Validator, + Feeder: msg.Feeder, + }) + return &types.MsgAggregateExchangeRatePrevoteResponse{}, err +} + +func (ms msgServer) AggregateExchangeRateVote( + goCtx context.Context, msg *types.MsgAggregateExchangeRateVote, +) (msgResp *types.MsgAggregateExchangeRateVoteResponse, err error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + valAddr, err := sdk.ValAddressFromBech32(msg.Validator) + if err != nil { + return nil, err + } + + feederAddr, err := sdk.AccAddressFromBech32(msg.Feeder) + if err != nil { + return nil, err + } + + if err := ms.ValidateFeeder(ctx, feederAddr, valAddr); err != nil { + return nil, err + } + + params, err := ms.Keeper.Params.Get(ctx) + if err != nil { + return nil, err + } + + // An aggergate prevote is required to get an aggregate vote. + aggregatePrevote, err := ms.Keeper.Prevotes.Get(ctx, valAddr) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrNoAggregatePrevote, msg.Validator) + } + + // Check a msg is submitted proper period + // This condition necessary for the commit-reveal scheme. + if (uint64(ctx.BlockHeight())/params.VotePeriod)-(aggregatePrevote.SubmitBlock/params.VotePeriod) != 1 { + return nil, types.ErrRevealPeriodMissMatch.Wrapf( + "aggregate prevote block: %d, current block: %d, vote period: %d", + aggregatePrevote.SubmitBlock, ctx.BlockHeight(), params.VotePeriod, + ) + } + + // Slice of (Pair, ExchangeRate) tuples. + exchangeRateTuples, err := types.ParseExchangeRateTuples(msg.ExchangeRates) + if err != nil { + return nil, sdkerrors.Wrap(errors.ErrInvalidCoins, err.Error()) + } + + // Check all pairs are in the vote target + for _, tuple := range exchangeRateTuples { + flag, err := ms.IsWhitelistedPair(ctx, tuple.Pair) + if err != nil { + return nil, err + } + if !flag { + return nil, sdkerrors.Wrap(types.ErrUnknownPair, tuple.Pair.String()) + } + } + + // Verify an exchange rate with aggregate prevote hash + hash := types.GetAggregateVoteHash(msg.Salt, msg.ExchangeRates, valAddr) + if aggregatePrevote.Hash != hash.String() { + return nil, sdkerrors.Wrapf( + types.ErrHashVerificationFailed, "must be given %s not %s", aggregatePrevote.Hash, hash, + ) + } + + // Move aggregate prevote to aggregate vote with given exchange rates + err = ms.Keeper.Votes.Set( + ctx, valAddr, types.NewAggregateExchangeRateVote(exchangeRateTuples, valAddr), + ) + if err != nil { + return nil, err + } + + err = ms.Keeper.Prevotes.Remove(ctx, valAddr) + if err != nil { + return nil, err + } + + priceTuples, err := types.NewExchangeRateTuplesFromString(msg.ExchangeRates) + if err != nil { + return + } + err = ctx.EventManager().EmitTypedEvent(&types.EventAggregateVote{ + Validator: msg.Validator, + Feeder: msg.Feeder, + Prices: priceTuples, + }) + + return &types.MsgAggregateExchangeRateVoteResponse{}, err +} + +func (ms msgServer) DelegateFeedConsent( + goCtx context.Context, msg *types.MsgDelegateFeedConsent, +) (*types.MsgDelegateFeedConsentResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + operatorAddr, err := sdk.ValAddressFromBech32(msg.Operator) + if err != nil { + return nil, err + } + + delegateAddr, err := sdk.AccAddressFromBech32(msg.Delegate) + if err != nil { + return nil, err + } + + // Check the delegator is a validator + _, err = ms.StakingKeeper.Validator(ctx, operatorAddr) + if err != nil { + return nil, sdkerrors.Wrap(err, msg.Operator) + } + + // Set the delegation + err = ms.Keeper.FeederDelegations.Set(ctx, operatorAddr, delegateAddr) + if err != nil { + return nil, err + } + + err = ctx.EventManager().EmitTypedEvent(&types.EventDelegateFeederConsent{ + Feeder: msg.Delegate, + Validator: msg.Operator, + }) + + return &types.MsgDelegateFeedConsentResponse{}, err +} diff --git a/x/oracle/keeper/msg_server_test.go b/x/oracle/keeper/msg_server_test.go new file mode 100644 index 00000000..f86aaca4 --- /dev/null +++ b/x/oracle/keeper/msg_server_test.go @@ -0,0 +1,230 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "cosmossdk.io/math" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestFeederDelegation(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(3), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + AccAddrs := make([]sdk.AccAddress, len(vals)) + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + AccAddrs[i] = sdk.AccAddress(vals[i].Address) + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + exchangeRates := types.ExchangeRateTuples{ + { + Pair: asset.Registry.Pair(denoms.BTC, denoms.USD), + ExchangeRate: testExchangeRate, + }, + } + + exchangeRateStr, err := exchangeRates.ToString() + require.NoError(t, err) + salt := "1" + hash := types.GetAggregateVoteHash(salt, exchangeRateStr, ValAddrs[0]) + + // Case 1: empty message + delegateFeedConsentMsg := types.MsgDelegateFeedConsent{} + _, err = msgServer.DelegateFeedConsent(ctx, &delegateFeedConsentMsg) + require.Error(t, err) + + // Case 2: Normal Prevote - without delegation + prevoteMsg := types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[0], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRatePrevote(ctx, prevoteMsg) + require.NoError(t, err) + + // Case 2.1: Normal Prevote - with delegation fails + prevoteMsg = types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[1], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRatePrevote(ctx, prevoteMsg) + require.Error(t, err) + + // Case 2.2: Normal Vote - without delegation + voteMsg := types.NewMsgAggregateExchangeRateVote(salt, exchangeRateStr, AccAddrs[0], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(2), voteMsg) + require.NoError(t, err) + + // Case 2.3: Normal Vote - with delegation fails + voteMsg = types.NewMsgAggregateExchangeRateVote(salt, exchangeRateStr, AccAddrs[1], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(2), voteMsg) + require.Error(t, err) + + // Case 3: Normal MsgDelegateFeedConsent succeeds + msg := types.NewMsgDelegateFeedConsent(ValAddrs[0], AccAddrs[1]) + _, err = msgServer.DelegateFeedConsent(ctx, msg) + require.NoError(t, err) + + // Case 4.1: Normal Prevote - without delegation fails + prevoteMsg = types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[2], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRatePrevote(ctx, prevoteMsg) + require.Error(t, err) + + // Case 4.2: Normal Prevote - with delegation succeeds + prevoteMsg = types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[1], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRatePrevote(ctx, prevoteMsg) + require.NoError(t, err) + + // Case 4.3: Normal Vote - without delegation fails + voteMsg = types.NewMsgAggregateExchangeRateVote(salt, exchangeRateStr, AccAddrs[2], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(2), voteMsg) + require.Error(t, err) + + // Case 4.4: Normal Vote - with delegation succeeds + voteMsg = types.NewMsgAggregateExchangeRateVote(salt, exchangeRateStr, AccAddrs[1], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(2), voteMsg) + require.NoError(t, err) +} + +func TestAggregatePrevoteVote(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(2)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + AccAddrs := make([]sdk.AccAddress, len(vals)) + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + AccAddrs[i] = sdk.AccAddress(vals[i].Address) + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + salt := "1" + exchangeRates := types.ExchangeRateTuples{ + { + Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), + ExchangeRate: math.LegacyMustNewDecFromStr("1000.23"), + }, + { + Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), + ExchangeRate: math.LegacyMustNewDecFromStr("0.29"), + }, + + { + Pair: asset.Registry.Pair(denoms.BTC, denoms.USD), + ExchangeRate: math.LegacyMustNewDecFromStr("0.27"), + }, + } + + otherExchangeRate := types.ExchangeRateTuples{ + { + Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), + ExchangeRate: math.LegacyMustNewDecFromStr("1000.23"), + }, + { + Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), + ExchangeRate: math.LegacyMustNewDecFromStr("0.29"), + }, + + { + Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), + ExchangeRate: math.LegacyMustNewDecFromStr("0.27"), + }, + } + + unintendedExchangeRateStr := types.ExchangeRateTuples{ + { + Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), + ExchangeRate: math.LegacyMustNewDecFromStr("1000.23"), + }, + { + Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), + ExchangeRate: math.LegacyMustNewDecFromStr("0.29"), + }, + { + Pair: "BTC:CNY", + ExchangeRate: math.LegacyMustNewDecFromStr("0.27"), + }, + } + exchangeRatesStr, err := exchangeRates.ToString() + require.NoError(t, err) + + otherExchangeRateStr, err := otherExchangeRate.ToString() + require.NoError(t, err) + + unintendedExchageRateStr, err := unintendedExchangeRateStr.ToString() + require.NoError(t, err) + + hash := types.GetAggregateVoteHash(salt, exchangeRatesStr, ValAddrs[0]) + + aggregateExchangeRatePrevoteMsg := types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[0], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRatePrevote(ctx, aggregateExchangeRatePrevoteMsg) + require.NoError(t, err) + + // Unauthorized feeder + aggregateExchangeRatePrevoteMsg = types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[1], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRatePrevote(ctx, aggregateExchangeRatePrevoteMsg) + require.Error(t, err) + + // Invalid addr + aggregateExchangeRatePrevoteMsg = types.NewMsgAggregateExchangeRatePrevote(hash, sdk.AccAddress{}, ValAddrs[0]) + _, err = msgServer.AggregateExchangeRatePrevote(ctx, aggregateExchangeRatePrevoteMsg) + require.Error(t, err) + + // Invalid validator addr + aggregateExchangeRatePrevoteMsg = types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[0], sdk.ValAddress{}) + _, err = msgServer.AggregateExchangeRatePrevote(ctx, aggregateExchangeRatePrevoteMsg) + require.Error(t, err) + + // Invalid reveal period + aggregateExchangeRateVoteMsg := types.NewMsgAggregateExchangeRateVote(salt, exchangeRatesStr, AccAddrs[0], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx, aggregateExchangeRateVoteMsg) + require.Error(t, err) + + // Invalid reveal period + ctx = ctx.WithBlockHeight(3) + aggregateExchangeRateVoteMsg = types.NewMsgAggregateExchangeRateVote(salt, exchangeRatesStr, AccAddrs[0], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx, aggregateExchangeRateVoteMsg) + require.Error(t, err) + + // Other exchange rate with valid real period + ctx = ctx.WithBlockHeight(2) + aggregateExchangeRateVoteMsg = types.NewMsgAggregateExchangeRateVote(salt, otherExchangeRateStr, AccAddrs[0], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx, aggregateExchangeRateVoteMsg) + require.Error(t, err) + + // Unauthorized feeder + aggregateExchangeRateVoteMsg = types.NewMsgAggregateExchangeRateVote(salt, exchangeRatesStr, AccAddrs[1], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx, aggregateExchangeRateVoteMsg) + require.Error(t, err) + + // Unintended denom vote + aggregateExchangeRateVoteMsg = types.NewMsgAggregateExchangeRateVote(salt, unintendedExchageRateStr, AccAddrs[0], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx, aggregateExchangeRateVoteMsg) + require.Error(t, err) + + // Valid exchange rate reveal submission + ctx = ctx.WithBlockHeight(2) + aggregateExchangeRateVoteMsg = types.NewMsgAggregateExchangeRateVote(salt, exchangeRatesStr, AccAddrs[0], ValAddrs[0]) + _, err = msgServer.AggregateExchangeRateVote(ctx, aggregateExchangeRateVoteMsg) + require.NoError(t, err) +} diff --git a/x/oracle/keeper/params.go b/x/oracle/keeper/params.go new file mode 100644 index 00000000..ff3b7b50 --- /dev/null +++ b/x/oracle/keeper/params.go @@ -0,0 +1,75 @@ +package keeper + +import ( + "cosmossdk.io/math" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// UpdateParams updates the oracle parameters +func (k Keeper) UpdateParams(ctx sdk.Context, params types.Params) { + _ = k.Params.Set(ctx, params) +} + +// VotePeriod returns the number of blocks during which voting takes place. +func (k Keeper) VotePeriod(ctx sdk.Context) (res uint64) { + params, _ := k.Params.Get(ctx) + return params.VotePeriod +} + +// VoteThreshold returns the minimum percentage of votes that must be received for a votes to pass. +func (k Keeper) VoteThreshold(ctx sdk.Context) (res math.LegacyDec) { + params, _ := k.Params.Get(ctx) + return params.VoteThreshold +} + +// MinVoters returns the minimum percentage of votes that must be received for a votes to pass. +func (k Keeper) MinVoters(ctx sdk.Context) (res uint64) { + params, _ := k.Params.Get(ctx) + return params.MinVoters +} + +// RewardBand returns a maxium divergence that a price vote can have from the +// weighted median in the votes. If a vote lies within the valid range +// defined by: +// +// μ := weightedMedian, +// validRange := μ ± (μ * rewardBand / 2), +// +// then rewards are added to the validator performance. +// Note that if the reward band is smaller than 1 standard +// deviation, the band is taken to be 1 standard deviation. +func (k Keeper) RewardBand(ctx sdk.Context) (res math.LegacyDec) { + params, _ := k.Params.Get(ctx) + return params.RewardBand +} + +// Whitelist returns the pair list that can be activated +func (k Keeper) Whitelist(ctx sdk.Context) (res []asset.Pair) { + params, _ := k.Params.Get(ctx) + return params.Whitelist +} + +// SlashFraction returns oracle voting penalty rate +func (k Keeper) SlashFraction(ctx sdk.Context) (res math.LegacyDec) { + params, _ := k.Params.Get(ctx) + return params.SlashFraction +} + +// SlashWindow returns the number of voting periods that specify a "slash window". +// After each slash window, all oracles that have missed more than the penalty +// threshold are slashed. Missing the penalty threshold is synonymous with +// submitting fewer valid votes than `MinValidPerWindow`. +func (k Keeper) SlashWindow(ctx sdk.Context) (res uint64) { + params, _ := k.Params.Get(ctx) + return params.SlashWindow +} + +// MinValidPerWindow returns oracle slashing threshold +func (k Keeper) MinValidPerWindow(ctx sdk.Context) (res math.LegacyDec) { + params, _ := k.Params.Get(ctx) + return params.MinValidPerWindow +} diff --git a/x/oracle/keeper/params_test.go b/x/oracle/keeper/params_test.go new file mode 100644 index 00000000..483a3984 --- /dev/null +++ b/x/oracle/keeper/params_test.go @@ -0,0 +1,58 @@ +package keeper_test + +import ( + "testing" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestParams(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + // Test default params setting + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, types.DefaultParams())) + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + require.NotNil(t, params) + + // Test custom params setting + votePeriod := uint64(10) + voteThreshold := math.LegacyNewDecWithPrec(33, 2) + minVoters := uint64(4) + oracleRewardBand := math.LegacyNewDecWithPrec(1, 2) + slashFraction := math.LegacyNewDecWithPrec(1, 2) + slashWindow := uint64(1000) + minValidPerWindow := math.LegacyNewDecWithPrec(1, 4) + minFeeRatio := math.LegacyNewDecWithPrec(1, 2) + whitelist := []asset.Pair{ + asset.Registry.Pair(denoms.BTC, denoms.NUSD), + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + } + + // Should really test validateParams, but skipping because obvious + newParams := types.Params{ + VotePeriod: votePeriod, + VoteThreshold: voteThreshold, + MinVoters: minVoters, + RewardBand: oracleRewardBand, + Whitelist: whitelist, + SlashFraction: slashFraction, + SlashWindow: slashWindow, + MinValidPerWindow: minValidPerWindow, + ValidatorFeeRatio: minFeeRatio, + } + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, newParams)) + + storedParams, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + require.NotNil(t, storedParams) + require.Equal(t, storedParams, newParams) +} diff --git a/x/oracle/keeper/querier.go b/x/oracle/keeper/querier.go new file mode 100644 index 00000000..31997f42 --- /dev/null +++ b/x/oracle/keeper/querier.go @@ -0,0 +1,234 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/types" +) + +// querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over q +type querier struct { + Keeper +} + +// NewQuerier returns an implementation of the oracle QueryServer interface +// for the provided Keeper. +func NewQuerier(keeper Keeper) types.QueryServer { + return &querier{Keeper: keeper} +} + +var _ types.QueryServer = querier{} + +// Params queries params of distribution module +func (q querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + var params types.Params + + params, err := q.Keeper.Params.Get(ctx) + if err != nil { + return nil, err + } + + return &types.QueryParamsResponse{Params: params}, nil +} + +// ExchangeRate queries exchange rate of a pair +func (q querier) ExchangeRate(c context.Context, req *types.QueryExchangeRateRequest) (*types.QueryExchangeRateResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + if len(req.Pair) == 0 { + return nil, status.Error(codes.InvalidArgument, "empty pair") + } + + ctx := sdk.UnwrapSDKContext(c) + exchangeRate, err := q.Keeper.GetExchangeRate(ctx, req.Pair) + if err != nil { + return nil, err + } + + return &types.QueryExchangeRateResponse{ExchangeRate: exchangeRate}, nil +} + +/* +Gets the time-weighted average price from ( ctx.BlockTime() - interval, ctx.BlockTime() ] +Note the open-ended right bracket. + +If there's only one snapshot, then this function returns the price from that single snapshot. + +Returns -1 if there's no price. +*/ +func (q querier) ExchangeRateTwap(c context.Context, req *types.QueryExchangeRateRequest) (response *types.QueryExchangeRateResponse, err error) { + if _, err = q.ExchangeRate(c, req); err != nil { + return + } + + ctx := sdk.UnwrapSDKContext(c) + twap, err := q.Keeper.GetExchangeRateTwap(ctx, req.Pair) + if err != nil { + return &types.QueryExchangeRateResponse{}, err + } + return &types.QueryExchangeRateResponse{ExchangeRate: twap}, nil +} + +// ExchangeRates queries exchange rates of all pairs +func (q querier) ExchangeRates(ctx context.Context, _ *types.QueryExchangeRatesRequest) (*types.QueryExchangeRatesResponse, error) { + var exchangeRates types.ExchangeRateTuples + _ = q.Keeper.ExchangeRates.Walk(ctx, nil, func(key asset.Pair, value types.DatedPrice) (bool, error) { + exchangeRates = append(exchangeRates, types.ExchangeRateTuple{ + Pair: key, + ExchangeRate: value.ExchangeRate, + }) + return false, nil + }) + + return &types.QueryExchangeRatesResponse{ExchangeRates: exchangeRates}, nil +} + +// Actives queries all pairs for which exchange rates exist +func (q querier) Actives(ctx context.Context, _ *types.QueryActivesRequest) (*types.QueryActivesResponse, error) { + iter, err := q.Keeper.ExchangeRates.Iterate(ctx, nil) + if err != nil { + return nil, err + } + keys, err := iter.Keys() + if err != nil { + return nil, err + } + return &types.QueryActivesResponse{ + Actives: keys, + }, nil +} + +// VoteTargets queries the voting target list on current vote period +func (q querier) VoteTargets(c context.Context, _ *types.QueryVoteTargetsRequest) (*types.QueryVoteTargetsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + targets, err := q.GetWhitelistedPairs(ctx) + if err != nil { + return nil, err + } + return &types.QueryVoteTargetsResponse{ + VoteTargets: targets, + }, nil +} + +// FeederDelegation queries the account address that the validator operator delegated oracle vote rights to +func (q querier) FeederDelegation(ctx context.Context, req *types.QueryFeederDelegationRequest) (*types.QueryFeederDelegationResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + valueBytes, err := q.Keeper.FeederDelegations.Get(ctx, valAddr) + var value sdk.Address + if err == nil { + value = sdk.AccAddress(valueBytes) + } else { + value = sdk.AccAddress(valAddr) + } + return &types.QueryFeederDelegationResponse{ + FeederAddr: value.String(), + }, nil +} + +// MissCounter queries oracle miss counter of a validator +func (q querier) MissCounter(ctx context.Context, req *types.QueryMissCounterRequest) (*types.QueryMissCounterResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + value, err := q.MissCounters.Get(ctx, valAddr) + if err != nil { + value = 0 + } + return &types.QueryMissCounterResponse{ + MissCounter: value, + }, nil +} + +// AggregatePrevote queries an aggregate prevote of a validator +func (q querier) AggregatePrevote(ctx context.Context, req *types.QueryAggregatePrevoteRequest) (*types.QueryAggregatePrevoteResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + prevote, err := q.Prevotes.Get(ctx, valAddr) + if err != nil { + return nil, err + } + + return &types.QueryAggregatePrevoteResponse{ + AggregatePrevote: prevote, + }, nil +} + +// AggregatePrevotes queries aggregate prevotes of all validators +func (q querier) AggregatePrevotes(ctx context.Context, _ *types.QueryAggregatePrevotesRequest) (*types.QueryAggregatePrevotesResponse, error) { + iter, err := q.Prevotes.Iterate(ctx, nil) + if err != nil { + return nil, err + } + values, err := iter.Values() + if err != nil { + return nil, err + } + return &types.QueryAggregatePrevotesResponse{ + AggregatePrevotes: values, + }, nil +} + +// AggregateVote queries an aggregate vote of a validator +func (q querier) AggregateVote(ctx context.Context, req *types.QueryAggregateVoteRequest) (*types.QueryAggregateVoteResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + valAddr, err := sdk.ValAddressFromBech32(req.ValidatorAddr) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + vote, err := q.Keeper.Votes.Get(ctx, valAddr) + if err != nil { + return nil, err + } + + return &types.QueryAggregateVoteResponse{ + AggregateVote: vote, + }, nil +} + +// AggregateVotes queries aggregate votes of all validators +func (q querier) AggregateVotes(ctx context.Context, _ *types.QueryAggregateVotesRequest) (*types.QueryAggregateVotesResponse, error) { + iter, err := q.Keeper.Votes.Iterate(ctx, nil) + if err != nil { + return nil, err + } + values, err := iter.Values() + if err != nil { + return nil, err + } + return &types.QueryAggregateVotesResponse{ + AggregateVotes: values, + }, nil +} diff --git a/x/oracle/keeper/querier_test.go b/x/oracle/keeper/querier_test.go new file mode 100644 index 00000000..9368b526 --- /dev/null +++ b/x/oracle/keeper/querier_test.go @@ -0,0 +1,440 @@ +package keeper_test + +import ( + "testing" + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestQueryParams(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + querier := keeper.NewQuerier(keepers.OracleKeeper) + res, err := querier.Params(ctx, &types.QueryParamsRequest{}) + require.NoError(t, err) + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + + require.Equal(t, params, res.Params) +} + +func TestQueryExchangeRate(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + rate := math.LegacyNewDec(1700) + require.NoError(t, keepers.OracleKeeper.ExchangeRates.Set(ctx, asset.Registry.Pair(denoms.ETH, denoms.NUSD), types.DatedPrice{ + ExchangeRate: rate, + CreationHeight: ctx.BlockHeight(), + CreationTimeUnixMs: uint64(ctx.BlockTime().UnixMilli()), + })) + + // empty request + _, err := querier.ExchangeRate(ctx, nil) + require.Error(t, err) + + // Query to grpc + res, err := querier.ExchangeRate(ctx, &types.QueryExchangeRateRequest{ + Pair: asset.Registry.Pair(denoms.ETH, denoms.NUSD), + }) + require.NoError(t, err) + require.Equal(t, rate, res.ExchangeRate) +} + +func TestQueryMissCounter(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(1)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + missCounter := uint64(1) + require.NoError(t, keepers.OracleKeeper.MissCounters.Set(ctx, ValAddrs[0], missCounter)) + + // empty request + _, err := querier.MissCounter(ctx, nil) + require.Error(t, err) + + // Query to grpc + res, err := querier.MissCounter(ctx, &types.QueryMissCounterRequest{ + ValidatorAddr: ValAddrs[0].String(), + }) + require.NoError(t, err) + require.Equal(t, missCounter, res.MissCounter) +} + +func TestQueryExchangeRates(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + rate := math.LegacyNewDec(1700) + require.NoError(t, keepers.OracleKeeper.ExchangeRates.Set(ctx, asset.Registry.Pair(denoms.BTC, denoms.NUSD), types.DatedPrice{ + ExchangeRate: rate, + CreationHeight: ctx.BlockHeight(), + CreationTimeUnixMs: uint64(ctx.BlockTime().UnixMilli()), + })) + require.NoError(t, keepers.OracleKeeper.ExchangeRates.Set(ctx, asset.Registry.Pair(denoms.ETH, denoms.NUSD), types.DatedPrice{ + ExchangeRate: rate, + CreationHeight: ctx.BlockHeight(), + CreationTimeUnixMs: uint64(ctx.BlockTime().UnixMilli()), + })) + + res, err := querier.ExchangeRates(ctx, &types.QueryExchangeRatesRequest{}) + require.NoError(t, err) + + require.Equal(t, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), ExchangeRate: rate}, + {Pair: asset.Registry.Pair(denoms.ETH, denoms.NUSD), ExchangeRate: rate}, + }, res.ExchangeRates) +} + +func TestQueryExchangeRateTwap(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + rate := math.LegacyNewDec(1700) + keepers.OracleKeeper.SetPrice(ctx, asset.Registry.Pair(denoms.BTC, denoms.NUSD), rate) + RequireContainsTypedEvent( + t, + ctx, + &types.EventPriceUpdate{ + Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), + Price: rate, + TimestampMs: ctx.BlockTime().UnixMilli(), + }, + ) + + ctx = ctx. + WithBlockTime(ctx.BlockTime().Add(time.Second)). + WithBlockHeight(ctx.BlockHeight() + 1) + + _, err := querier.ExchangeRateTwap(ctx, &types.QueryExchangeRateRequest{Pair: asset.Registry.Pair(denoms.ETH, denoms.NUSD)}) + require.Error(t, err) + + res, err := querier.ExchangeRateTwap(ctx, &types.QueryExchangeRateRequest{Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD)}) + require.NoError(t, err) + require.Equal(t, math.LegacyMustNewDecFromStr("1700"), res.ExchangeRate) +} + +func TestCalcTwap(t *testing.T) { + tests := []struct { + name string + pair asset.Pair + priceSnapshots []types.PriceSnapshot + currentBlockTime time.Time + currentBlockHeight int64 + lookbackInterval time.Duration + assetAmount math.LegacyDec + expectedPrice math.LegacyDec + expectedErr error + }{ + // expected price: (9.5 * (35 - 30) + 8.5 * (30 - 20) + 9.0 * (20 - 5)) / 30 = 8.916666 + { + name: "spot price twap calc, t=(5,35]", + pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), + priceSnapshots: []types.PriceSnapshot{ + { + Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), + Price: math.LegacyMustNewDecFromStr("90000.0"), + TimestampMs: time.UnixMilli(1).UnixMilli(), + }, + { + Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), + Price: math.LegacyMustNewDecFromStr("9.0"), + TimestampMs: time.UnixMilli(10).UnixMilli(), + }, + { + Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), + Price: math.LegacyMustNewDecFromStr("8.5"), + TimestampMs: time.UnixMilli(20).UnixMilli(), + }, + { + Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), + Price: math.LegacyMustNewDecFromStr("9.5"), + TimestampMs: time.UnixMilli(30).UnixMilli(), + }, + }, + currentBlockTime: time.UnixMilli(35), + currentBlockHeight: 3, + lookbackInterval: 30 * time.Millisecond, + expectedPrice: math.LegacyMustNewDecFromStr("8.900000000000000000"), + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + querier := keeper.NewQuerier(keepers.OracleKeeper) + ctx := chain.GetContext() + + newParams := types.Params{ + VotePeriod: types.DefaultVotePeriod, + VoteThreshold: types.DefaultVoteThreshold, + MinVoters: types.DefaultMinVoters, + RewardBand: types.DefaultRewardBand, + Whitelist: types.DefaultWhitelist, + SlashFraction: types.DefaultSlashFraction, + SlashWindow: types.DefaultSlashWindow, + MinValidPerWindow: types.DefaultMinValidPerWindow, + TwapLookbackWindow: tc.lookbackInterval, + ValidatorFeeRatio: types.DefaultValidatorFeeRatio, + } + + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, newParams)) + ctx = ctx.WithBlockTime(time.UnixMilli(0)) + for _, reserve := range tc.priceSnapshots { + ctx = ctx.WithBlockTime(time.UnixMilli(reserve.TimestampMs)) + keepers.OracleKeeper.SetPrice(ctx, asset.Registry.Pair(denoms.BTC, denoms.NUSD), reserve.Price) + } + + ctx = ctx.WithBlockTime(tc.currentBlockTime).WithBlockHeight(tc.currentBlockHeight) + + price, err := querier.ExchangeRateTwap(ctx, &types.QueryExchangeRateRequest{Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD)}) + require.NoError(t, err) + + require.EqualValuesf(t, tc.expectedPrice, price.ExchangeRate, + "expected %s, got %s", tc.expectedPrice.String(), price.ExchangeRate.String()) + }) + } +} + +func TestQueryActives(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + queryClient := keeper.NewQuerier(keepers.OracleKeeper) + + rate := math.LegacyNewDec(1700) + + require.NoError(t, keepers.OracleKeeper.ExchangeRates.Set(ctx, asset.Registry.Pair(denoms.BTC, denoms.NUSD), types.DatedPrice{ + ExchangeRate: rate, + CreationHeight: ctx.BlockHeight(), + CreationTimeUnixMs: uint64(ctx.BlockTime().UnixMilli()), + })) + + require.NoError(t, keepers.OracleKeeper.ExchangeRates.Set(ctx, asset.Registry.Pair(denoms.NIBI, denoms.NUSD), types.DatedPrice{ + ExchangeRate: rate, + CreationHeight: ctx.BlockHeight(), + CreationTimeUnixMs: uint64(ctx.BlockTime().UnixMilli()), + })) + + require.NoError(t, keepers.OracleKeeper.ExchangeRates.Set(ctx, asset.Registry.Pair(denoms.ETH, denoms.NUSD), types.DatedPrice{ + ExchangeRate: rate, + CreationHeight: ctx.BlockHeight(), + CreationTimeUnixMs: uint64(ctx.BlockTime().UnixMilli()), + })) + + res, err := queryClient.Actives(ctx, &types.QueryActivesRequest{}) + require.NoError(t, err) + + targetPairs := []asset.Pair{ + asset.Registry.Pair(denoms.BTC, denoms.NUSD), + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + asset.Registry.Pair(denoms.NIBI, denoms.NUSD), + } + + require.Equal(t, targetPairs, res.Actives) +} + +func TestQueryFeederDelegation(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(2)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + AccAddrs := make([]sdk.AccAddress, len(vals)) + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + AccAddrs[i] = sdk.AccAddress(vals[i].Address) + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + require.NoError(t, keepers.OracleKeeper.FeederDelegations.Set(ctx, ValAddrs[0], AccAddrs[1])) + + // empty request + _, err := querier.FeederDelegation(ctx, nil) + require.Error(t, err) + + res, err := querier.FeederDelegation(ctx, &types.QueryFeederDelegationRequest{ + ValidatorAddr: ValAddrs[0].String(), + }) + require.NoError(t, err) + + require.Equal(t, AccAddrs[1].String(), res.FeederAddr) +} + +func TestQueryAggregatePrevote(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(2)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + prevote1 := types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash{}, ValAddrs[0], 0) + require.NoError(t, keepers.OracleKeeper.Prevotes.Set(ctx, ValAddrs[0], prevote1)) + prevote2 := types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash{}, ValAddrs[1], 0) + require.NoError(t, keepers.OracleKeeper.Prevotes.Set(ctx, ValAddrs[1], prevote2)) + + // validator 0 address params + res, err := querier.AggregatePrevote(ctx, &types.QueryAggregatePrevoteRequest{ + ValidatorAddr: ValAddrs[0].String(), + }) + require.NoError(t, err) + require.Equal(t, prevote1, res.AggregatePrevote) + + // empty request + _, err = querier.AggregatePrevote(ctx, nil) + require.Error(t, err) + + // validator 1 address params + res, err = querier.AggregatePrevote(ctx, &types.QueryAggregatePrevoteRequest{ + ValidatorAddr: ValAddrs[1].String(), + }) + require.NoError(t, err) + require.Equal(t, prevote2, res.AggregatePrevote) +} + +func TestQueryAggregatePrevotes(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(3)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + prevote1 := types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash{}, ValAddrs[0], 0) + require.NoError(t, keepers.OracleKeeper.Prevotes.Set(ctx, ValAddrs[0], prevote1)) + prevote2 := types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash{}, ValAddrs[1], 0) + require.NoError(t, keepers.OracleKeeper.Prevotes.Set(ctx, ValAddrs[1], prevote2)) + prevote3 := types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash{}, ValAddrs[2], 0) + require.NoError(t, keepers.OracleKeeper.Prevotes.Set(ctx, ValAddrs[2], prevote3)) + + expectedPrevotes := []types.AggregateExchangeRatePrevote{prevote1, prevote2, prevote3} + // sort.SliceStable(expectedPrevotes, func(i, j int) bool { + // return expectedPrevotes[i].Voter <= expectedPrevotes[j].Voter + // }) + + res, err := querier.AggregatePrevotes(ctx, &types.QueryAggregatePrevotesRequest{}) + require.NoError(t, err) + require.Equal(t, expectedPrevotes, res.AggregatePrevotes) +} + +func TestQueryAggregateVote(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(2)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + vote1 := types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{{Pair: "", ExchangeRate: math.LegacyOneDec()}}, ValAddrs[0]) + require.NoError(t, keepers.OracleKeeper.Votes.Set(ctx, ValAddrs[0], vote1)) + vote2 := types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{{Pair: "", ExchangeRate: math.LegacyOneDec()}}, ValAddrs[1]) + require.NoError(t, keepers.OracleKeeper.Votes.Set(ctx, ValAddrs[1], vote2)) + + // empty request + _, err := querier.AggregateVote(ctx, nil) + require.Error(t, err) + + // validator 0 address params + res, err := querier.AggregateVote(ctx, &types.QueryAggregateVoteRequest{ + ValidatorAddr: ValAddrs[0].String(), + }) + require.NoError(t, err) + require.Equal(t, vote1, res.AggregateVote) + + // validator 1 address params + res, err = querier.AggregateVote(ctx, &types.QueryAggregateVoteRequest{ + ValidatorAddr: ValAddrs[1].String(), + }) + require.NoError(t, err) + require.Equal(t, vote2, res.AggregateVote) +} + +func TestQueryAggregateVotes(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(3)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + vote1 := types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{{Pair: "", ExchangeRate: math.LegacyOneDec()}}, ValAddrs[0]) + require.NoError(t, keepers.OracleKeeper.Votes.Set(ctx, ValAddrs[0], vote1)) + vote2 := types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{{Pair: "", ExchangeRate: math.LegacyOneDec()}}, ValAddrs[1]) + require.NoError(t, keepers.OracleKeeper.Votes.Set(ctx, ValAddrs[1], vote2)) + vote3 := types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{{Pair: "", ExchangeRate: math.LegacyOneDec()}}, ValAddrs[2]) + require.NoError(t, keepers.OracleKeeper.Votes.Set(ctx, ValAddrs[2], vote3)) + + expectedVotes := []types.AggregateExchangeRateVote{vote1, vote2, vote3} + // sort.SliceStable(expectedVotes, func(i, j int) bool { + // return expectedVotes[i].Voter <= expectedVotes[j].Voter + // }) + + res, err := querier.AggregateVotes(ctx, &types.QueryAggregateVotesRequest{}) + require.NoError(t, err) + require.Equal(t, expectedVotes, res.AggregateVotes) +} + +func TestQueryVoteTargets(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + querier := keeper.NewQuerier(keepers.OracleKeeper) + + // clear pairs + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil)) + + voteTargets := []asset.Pair{"denom1:denom2", "denom3:denom4", "denom5:denom6"} + for _, target := range voteTargets { + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Set(ctx, target)) + } + + res, err := querier.VoteTargets(ctx, &types.QueryVoteTargetsRequest{}) + require.NoError(t, err) + require.Equal(t, voteTargets, res.VoteTargets) +} diff --git a/x/oracle/keeper/reward.go b/x/oracle/keeper/reward.go new file mode 100644 index 00000000..bca8afad --- /dev/null +++ b/x/oracle/keeper/reward.go @@ -0,0 +1,108 @@ +package keeper + +import ( + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/archway-network/archway/x/oracle/types" +) + +func (k Keeper) AllocateRewards(ctx sdk.Context, funderModule string, totalCoins sdk.Coins, votePeriods uint64) error { + votePeriodCoins := make(sdk.Coins, len(totalCoins)) + for i, coin := range totalCoins { + newCoin := sdk.NewCoin(coin.Denom, coin.Amount.QuoRaw(int64(votePeriods))) + votePeriodCoins[i] = newCoin + } + + id, err := k.RewardsID.Next(ctx) + if err != nil { + return err + } + err = k.Rewards.Set(ctx, id, types.Rewards{ + Id: id, + VotePeriods: votePeriods, + Coins: votePeriodCoins, + }) + if err != nil { + return err + } + + return k.bankKeeper.SendCoinsFromModuleToModule(ctx, funderModule, types.ModuleName, totalCoins) +} + +// rewardWinners gives out a portion of spread fees collected in the +// oracle reward pool to the oracle voters that voted faithfully. +func (k Keeper) rewardWinners( + ctx sdk.Context, + validatorPerformances types.ValidatorPerformances, +) { + totalRewardWeight := validatorPerformances.TotalRewardWeight() + if totalRewardWeight == 0 { + return + } + + var totalRewards sdk.DecCoins + rewards := k.GatherRewardsForVotePeriod(ctx) + totalRewards = totalRewards.Add(sdk.NewDecCoinsFromCoins(rewards...)...) + + var distributedRewards sdk.Coins + for _, validatorPerformance := range validatorPerformances { + validator, err := k.StakingKeeper.Validator(ctx, validatorPerformance.ValAddress) + if err != nil { + continue + } + + rewardPortion, _ := totalRewards.MulDec(math.LegacyNewDec(validatorPerformance.RewardWeight).QuoInt64(totalRewardWeight)).TruncateDecimal() + err = k.distrKeeper.AllocateTokensToValidator(ctx, validator, sdk.NewDecCoinsFromCoins(rewardPortion...)) + if err != nil { + continue + } + + distributedRewards = distributedRewards.Add(rewardPortion...) + } + + // Move distributed reward to distribution module + err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.distrModuleName, distributedRewards) + if err != nil { + k.Logger(ctx).Error("failed to send coins to distribution module", "err", err) + } +} + +// GatherRewardsForVotePeriod retrieves the pair rewards for the provided pair and current vote period. +func (k Keeper) GatherRewardsForVotePeriod(ctx sdk.Context) sdk.Coins { + coins := sdk.NewCoins() + // iterate over + iter, err := k.Rewards.Iterate(ctx, nil) + if err != nil { + panic(err) + } + keys, err := iter.Keys() + if err != nil { + panic(err) + } + for _, rewardId := range keys { + pairReward, err := k.Rewards.Get(ctx, rewardId) + if err != nil { + k.Logger(ctx).Error("failed to get reward", "err", err) + continue + } + coins = coins.Add(pairReward.Coins...) + + // Decrease the remaining vote periods of the PairReward. + pairReward.VotePeriods -= 1 + if pairReward.VotePeriods == 0 { + // If the distribution period count drops to 0: the reward instance is removed. + err := k.Rewards.Remove(ctx, rewardId) + if err != nil { + k.Logger(ctx).Error("failed to delete pair reward", "err", err) + } + } else { + err := k.Rewards.Set(ctx, rewardId, pairReward) + if err != nil { + k.Logger(ctx).Error("failed to set pair reward", "err", err) + } + } + } + + return coins +} diff --git a/x/oracle/keeper/reward_test.go b/x/oracle/keeper/reward_test.go new file mode 100644 index 00000000..c6774657 --- /dev/null +++ b/x/oracle/keeper/reward_test.go @@ -0,0 +1,88 @@ +package keeper_test + +import ( + "testing" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestKeeperRewardsDistributionMultiVotePeriods(t *testing.T) { + // this simulates allocating rewards for the pair atom:usd + // over 5 voting periods. It simulates rewards are correctly + // distributed over 5 voting periods to 5 validators. + // then we simulate that after the 5 voting periods are + // finished no more rewards distribution happen. + const periods uint64 = 5 + const validators = 5 + + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(validators)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + + rewards := sdk.NewInt64Coin("reward", 1000000) + valPeriodicRewards := sdk.NewDecCoinsFromCoins(rewards). + QuoDec(math.LegacyNewDec(int64(periods))). + QuoDec(math.LegacyNewDec(int64(validators))) + require.NoError(t, keepers.BankKeeper.MintCoins(ctx, minttypes.ModuleName, sdk.NewCoins(rewards))) + require.NoError(t, keepers.OracleKeeper.AllocateRewards(ctx, minttypes.ModuleName, sdk.NewCoins(rewards), periods)) + + for i := uint64(1); i <= periods; i++ { + for _, val := range vals { + // for doc's sake, this function is capable of making prevotes and votes because it + // passes the current context block height for pre vote + // then changes the height to current height + vote period for the vote + MakeAggregatePrevoteAndVote(t, ctx, msgServer, ctx.BlockHeight(), types.ExchangeRateTuples{ + { + Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), + ExchangeRate: testExchangeRate, + }, + }, val) + } + + keepers.OracleKeeper.UpdateExchangeRates(ctx) + + for valIndex := 0; valIndex < validators; valIndex++ { + distributionRewards, err := keepers.DistrKeeper.GetValidatorOutstandingRewards(ctx, sdk.ValAddress(vals[0].Address)) + require.NoError(t, err) + truncatedGot, _ := distributionRewards.Rewards. + QuoDec(math.LegacyNewDec(int64(i))). // outstanding rewards will count for the previous vote period too, so we divide it by current period + TruncateDecimal() // NOTE: not applying this on truncatedExpected because of rounding the test fails + truncatedExpected, _ := valPeriodicRewards.TruncateDecimal() + + require.Equalf(t, truncatedExpected, truncatedGot, "period: %d, %s <-> %s", i, truncatedExpected.String(), truncatedGot.String()) + } + // assert rewards + + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + int64(params.VotePeriod)) + } + + // assert there are no rewards + require.True(t, keepers.OracleKeeper.GatherRewardsForVotePeriod(ctx).IsZero()) + + // assert that there are no rewards instances + iter, err := keepers.OracleKeeper.Rewards.Iterate(ctx, nil) + require.NoError(t, err) + keys, err := iter.Keys() + require.NoError(t, err) + require.Empty(t, keys) +} diff --git a/x/oracle/keeper/slash.go b/x/oracle/keeper/slash.go new file mode 100644 index 00000000..639e2794 --- /dev/null +++ b/x/oracle/keeper/slash.go @@ -0,0 +1,66 @@ +package keeper + +import ( + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SlashAndResetMissCounters do slash any operator who over criteria & clear all operators miss counter to zero +func (k Keeper) SlashAndResetMissCounters(ctx sdk.Context) { + height := ctx.BlockHeight() + distributionHeight := height - sdk.ValidatorUpdateDelay - 1 + + // slash_window / vote_period + votePeriodsPerWindow := uint64( + math.LegacyNewDec(int64(k.SlashWindow(ctx))). + QuoInt64(int64(k.VotePeriod(ctx))). + TruncateInt64(), + ) + minValidPerWindow := k.MinValidPerWindow(ctx) + slashFraction := k.SlashFraction(ctx) + powerReduction := k.StakingKeeper.PowerReduction(ctx) + + _ = k.MissCounters.Walk(ctx, nil, func(operatorBytes []byte, missCounter uint64) (bool, error) { + operator := sdk.ValAddress(operatorBytes) + + // Calculate valid vote rate; (SlashWindow - MissCounter)/SlashWindow + validVoteRate := math.LegacyNewDecFromInt( + math.NewInt(int64(votePeriodsPerWindow - missCounter))). + QuoInt64(int64(votePeriodsPerWindow)) + + // Penalize the validator whose the valid vote rate is smaller than min threshold + if validVoteRate.LT(minValidPerWindow) { + validator, err := k.StakingKeeper.Validator(ctx, operator) + if err != nil { + k.Logger(ctx).Error("failed to get validator", "operator", operator) + } + if validator.IsBonded() && !validator.IsJailed() { + consAddr, err := validator.GetConsAddr() + if err != nil { + k.Logger(ctx).Error("failed to get consensus address", "validator", validator.GetOperator()) + return false, nil + } + + err = k.slashingKeeper.Slash( + ctx, consAddr, slashFraction, validator.GetConsensusPower(powerReduction), distributionHeight, + ) + if err != nil { + k.Logger(ctx).Error("failed to slash validator", "validator", validator.GetOperator()) + return false, nil + } + k.Logger(ctx).Info("oracle slash", "validator", string(consAddr), "fraction", slashFraction.String()) + err = k.slashingKeeper.Jail(ctx, consAddr) + if err != nil { + k.Logger(ctx).Error("failed to jail validator", "validator", validator.GetOperator()) + return false, nil + } + } + } + + err := k.MissCounters.Remove(ctx, operator) + if err != nil { + k.Logger(ctx).Error("failed to delete miss counter", "operator", operator.String(), "error", err) + } + return false, nil + }) +} diff --git a/x/oracle/keeper/slash_test.go b/x/oracle/keeper/slash_test.go new file mode 100644 index 00000000..3a28e78c --- /dev/null +++ b/x/oracle/keeper/slash_test.go @@ -0,0 +1,377 @@ +package keeper_test + +import ( + "testing" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestSlashAndResetMissCounters(t *testing.T) { + // initial setup + accNum := 2 + amt := sdk.TokensFromConsensusPower(50, sdk.DefaultPowerReduction) + InitTokens := sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction) + + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(accNum), + e2eTesting.WithGenAccounts(accNum), + e2eTesting.WithBondAmount(amt.String()), + e2eTesting.WithGenDefaultCoinBalance(InitTokens.String()), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + AccAddrs := make([]sdk.AccAddress, accNum) + ValAddrs := make([]sdk.ValAddress, accNum) + for i := 0; i < accNum; i++ { + AccAddrs[i] = chain.GetAccount(i).Address + } + for i, val := range chain.GetCurrentValSet().Validators { + ValAddrs[i] = sdk.ValAddress(val.Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + _, err = keepers.StakingKeeper.EndBlocker(ctx) + require.NoError(t, err) + + stakingparams, err := keepers.StakingKeeper.GetParams(ctx) + require.NoError(t, err) + require.Equal( + t, + sdk.NewCoins(sdk.NewCoin(stakingparams.BondDenom, InitTokens.Sub(amt))), + keepers.BankKeeper.GetAllBalances(ctx, AccAddrs[0]), + ) + validator, err := keepers.StakingKeeper.GetValidator(ctx, ValAddrs[0]) + require.NoError(t, err) + require.Equal(t, amt, validator.GetBondedTokens()) + require.Equal( + t, + sdk.NewCoins(sdk.NewCoin(stakingparams.BondDenom, InitTokens.Sub(amt))), + keepers.BankKeeper.GetAllBalances(ctx, AccAddrs[1]), + ) + validator1, err := keepers.StakingKeeper.GetValidator(ctx, ValAddrs[1]) + require.NoError(t, err) + require.Equal(t, amt, validator1.GetBondedTokens()) + + votePeriodsPerWindow := math.LegacyNewDec(int64(keepers.OracleKeeper.SlashWindow(ctx))).QuoInt64(int64(keepers.OracleKeeper.VotePeriod(ctx))).TruncateInt64() + slashFraction := keepers.OracleKeeper.SlashFraction(ctx) + minValidVotes := keepers.OracleKeeper.MinValidPerWindow(ctx).MulInt64(votePeriodsPerWindow).Ceil().TruncateInt64() + // Case 1, no slash + require.NoError(t, keepers.OracleKeeper.MissCounters.Set(ctx, ValAddrs[0], uint64(votePeriodsPerWindow-minValidVotes))) + keepers.OracleKeeper.SlashAndResetMissCounters(ctx) + _, err = keepers.StakingKeeper.EndBlocker(ctx) + require.NoError(t, err) + + validator, _ = keepers.StakingKeeper.GetValidator(ctx, ValAddrs[0]) + require.NoError(t, err) + require.Equal(t, amt, validator.GetBondedTokens()) + + // Case 2, slash + require.NoError(t, keepers.OracleKeeper.MissCounters.Set(ctx, ValAddrs[0], uint64(votePeriodsPerWindow-minValidVotes+1))) + keepers.OracleKeeper.SlashAndResetMissCounters(ctx) + validator, _ = keepers.StakingKeeper.GetValidator(ctx, ValAddrs[0]) + require.Equal(t, amt.Sub(slashFraction.MulInt(amt).TruncateInt()), validator.GetBondedTokens()) + require.True(t, validator.IsJailed()) + + // Case 3, slash unbonded validator + validator, _ = keepers.StakingKeeper.GetValidator(ctx, ValAddrs[0]) + validator.Status = stakingtypes.Unbonded + validator.Jailed = false + validator.Tokens = amt + require.NoError(t, keepers.StakingKeeper.SetValidator(ctx, validator)) + + require.NoError(t, keepers.OracleKeeper.MissCounters.Set(ctx, ValAddrs[0], uint64(votePeriodsPerWindow-minValidVotes+1))) + keepers.OracleKeeper.SlashAndResetMissCounters(ctx) + validator, _ = keepers.StakingKeeper.GetValidator(ctx, ValAddrs[0]) + require.Equal(t, amt, validator.Tokens) + require.False(t, validator.IsJailed()) + + // Case 4, slash jailed validator + validator, _ = keepers.StakingKeeper.GetValidator(ctx, ValAddrs[0]) + validator.Status = stakingtypes.Bonded + validator.Jailed = true + validator.Tokens = amt + require.NoError(t, keepers.StakingKeeper.SetValidator(ctx, validator)) + + require.NoError(t, keepers.OracleKeeper.MissCounters.Set(ctx, ValAddrs[0], uint64(votePeriodsPerWindow-minValidVotes+1))) + keepers.OracleKeeper.SlashAndResetMissCounters(ctx) + validator, _ = keepers.StakingKeeper.GetValidator(ctx, ValAddrs[0]) + require.Equal(t, amt, validator.Tokens) +} + +func TestInvalidVotesSlashing(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(5), + e2eTesting.WithBondAmount(testStakingAmt.String()), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + params.Whitelist = []asset.Pair{asset.Registry.Pair(denoms.ATOM, denoms.USD)} + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Set(ctx, asset.Registry.Pair(denoms.ATOM, denoms.USD))) + + votePeriodsPerWindow := math.LegacyNewDec(int64(keepers.OracleKeeper.SlashWindow(ctx))).QuoInt64(int64(keepers.OracleKeeper.VotePeriod(ctx))).TruncateInt64() + slashFraction := keepers.OracleKeeper.SlashFraction(ctx) + minValidPerWindow := keepers.OracleKeeper.MinValidPerWindow(ctx) + + for i := uint64(0); i < uint64(math.LegacyOneDec().Sub(minValidPerWindow).MulInt64(votePeriodsPerWindow).TruncateInt64()); i++ { + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + + // Account 1, govstable + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[0]) + + // Account 2, govstable, miss vote + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate.Add(math.LegacyNewDec(100000000000000))}, + }, vals[1]) + + // Account 3, govstable + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[2]) + + // Account 4, govstable + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[3]) + + keepers.OracleKeeper.UpdateExchangeRates(ctx) + // keepers.OracleKeeper.SlashAndResetMissCounters(ctx) + // keepers.OracleKeeper.UpdateExchangeRates(ctx) + + counter, err := keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[1]) + if err != nil { + counter = 0 + } + require.Equal(t, i+1, counter) + } + + validator, err := keepers.StakingKeeper.GetValidator(ctx, ValAddrs[1]) + require.NoError(t, err) + require.Equal(t, testStakingAmt, validator.GetBondedTokens()) + + // one more miss vote will inccur ValAddrs[1] slashing + // Account 1, govstable + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[0]) + + // Account 2, govstable, miss vote + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate.Add(math.LegacyNewDec(100000000000000))}, + }, vals[1]) + + // Account 3, govstable + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[2]) + + // Account 4, govstable + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[3]) + + ctx = ctx.WithBlockHeight(votePeriodsPerWindow - 1) + keepers.OracleKeeper.UpdateExchangeRates(ctx) + keepers.OracleKeeper.SlashAndResetMissCounters(ctx) + // keepers.OracleKeeper.UpdateExchangeRates(ctx) + + validator, err = keepers.StakingKeeper.GetValidator(ctx, ValAddrs[1]) + require.NoError(t, err) + require.Equal(t, math.LegacyOneDec().Sub(slashFraction).MulInt(testStakingAmt).TruncateInt(), validator.GetBondedTokens()) +} + +// TestWhitelistSlashing: Creates a scenario where one valoper (valIdx 0) does +// not vote throughout an entire vote window, while valopers 1 and 2 do. +func TestWhitelistSlashing(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(5), + e2eTesting.WithBondAmount(testStakingAmt.String()), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + votePeriodsPerSlashWindow := math.LegacyNewDec(int64(keepers.OracleKeeper.SlashWindow(ctx))).QuoInt64(int64(keepers.OracleKeeper.VotePeriod(ctx))).TruncateInt64() + minValidVotePeriodsPerWindow := keepers.OracleKeeper.MinValidPerWindow(ctx) + + pair := asset.Registry.Pair(denoms.ATOM, denoms.USD) + priceVoteFromVal := func(valIdx int, block int64, erate math.LegacyDec) { + MakeAggregatePrevoteAndVote(t, ctx, msgServer, block, + types.ExchangeRateTuples{{Pair: pair, ExchangeRate: erate}}, + vals[valIdx]) + } + err = keepers.OracleKeeper.WhitelistedPairs.Set(ctx, pair) + require.NoError(t, err) + perfs := keepers.OracleKeeper.UpdateExchangeRates(ctx) + require.EqualValues(t, 0, perfs.TotalRewardWeight()) + + allowedMissPct := math.LegacyOneDec().Sub(minValidVotePeriodsPerWindow) + allowedMissVotePeriods := allowedMissPct.MulInt64(votePeriodsPerSlashWindow). + TruncateInt64() + t.Logf("For %v blocks, valoper0 does not vote, while 1 and 2 do.", allowedMissVotePeriods) + for idxMissPeriod := uint64(0); idxMissPeriod < uint64(allowedMissVotePeriods); idxMissPeriod++ { + block := ctx.BlockHeight() + 1 + ctx = ctx.WithBlockHeight(block) + + valIdx := 0 // Valoper doesn't vote (abstain) + priceVoteFromVal(valIdx+1, block, testExchangeRate) + priceVoteFromVal(valIdx+2, block, testExchangeRate) + + perfs := keepers.OracleKeeper.UpdateExchangeRates(ctx) + missCount, err := keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[0]) + if err != nil { + missCount = 0 + } + require.EqualValues(t, 0, missCount, perfs.String()) + } + + t.Log("valoper0 should not be slashed") + validator, err := keepers.StakingKeeper.Validator(ctx, ValAddrs[0]) + require.NoError(t, err) + require.Equal(t, testStakingAmt, validator.GetBondedTokens()) +} + +func TestNotPassedBallotSlashing(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(5)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + params.Whitelist = []asset.Pair{asset.Registry.Pair(denoms.ATOM, denoms.USD)} + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + // clear tobin tax to reset vote targets + err = keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil) + require.NoError(t, err) + err = keepers.OracleKeeper.WhitelistedPairs.Set(ctx, asset.Registry.Pair(denoms.ATOM, denoms.USD)) + require.NoError(t, err) + + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + + // Account 1, govstable + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{{Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}}, vals[0]) + + keepers.OracleKeeper.UpdateExchangeRates(ctx) + keepers.OracleKeeper.SlashAndResetMissCounters(ctx) + // keepers.OracleKeeper.UpdateExchangeRates(ctx) + counter, err := keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[0]) + if err != nil { + counter = 0 + } + require.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[1]) + if err != nil { + counter = 0 + } + require.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[2]) + if err != nil { + counter = 0 + } + require.Equal(t, uint64(0), counter) +} + +func TestAbstainSlashing(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(5), + e2eTesting.WithBondAmount(testStakingAmt.String()), + ) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + // reset whitelisted pairs + params.Whitelist = []asset.Pair{asset.Registry.Pair(denoms.ATOM, denoms.USD)} + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + err = keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil) + require.NoError(t, err) + err = keepers.OracleKeeper.WhitelistedPairs.Set(ctx, asset.Registry.Pair(denoms.ATOM, denoms.USD)) + require.NoError(t, err) + + votePeriodsPerWindow := math.LegacyNewDec(int64(keepers.OracleKeeper.SlashWindow(ctx))).QuoInt64(int64(keepers.OracleKeeper.VotePeriod(ctx))).TruncateInt64() + minValidPerWindow := keepers.OracleKeeper.MinValidPerWindow(ctx) + + for i := uint64(0); i <= uint64(math.LegacyOneDec().Sub(minValidPerWindow).MulInt64(votePeriodsPerWindow).TruncateInt64()); i++ { + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + + // Account 1, ATOM/USD + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{{Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}}, vals[0]) + + // Account 2, ATOM/USD, abstain vote + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{{Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: math.LegacyOneDec().Neg()}}, vals[1]) + + // Account 3, ATOM/USD + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{{Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}}, vals[2]) + + keepers.OracleKeeper.UpdateExchangeRates(ctx) + keepers.OracleKeeper.SlashAndResetMissCounters(ctx) + // keepers.OracleKeeper.UpdateExchangeRates(ctx) + counter, err := keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[1]) + if err != nil { + counter = 0 + } + require.Equal(t, uint64(0), counter) + } + + validator, err := keepers.StakingKeeper.Validator(ctx, ValAddrs[1]) + require.NoError(t, err) + require.Equal(t, testStakingAmt, validator.GetBondedTokens()) +} diff --git a/x/oracle/keeper/update_exchange_rates.go b/x/oracle/keeper/update_exchange_rates.go new file mode 100644 index 00000000..78a800f9 --- /dev/null +++ b/x/oracle/keeper/update_exchange_rates.go @@ -0,0 +1,173 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/archway-network/archway/types/set" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/types" +) + +// UpdateExchangeRates updates the ExchangeRates, this is supposed to be executed on EndBlock. +func (k Keeper) UpdateExchangeRates(ctx sdk.Context) types.ValidatorPerformances { + k.Logger(ctx).Info("processing validator price votes") + validatorPerformances := k.newValidatorPerformances(ctx) + pairs, err := k.GetWhitelistedPairs(ctx) + if err != nil { + panic(err) + } + whitelistedPairs := set.New[asset.Pair](pairs...) + + pairVotes := k.getPairVotes(ctx, validatorPerformances, whitelistedPairs) + + k.ClearExchangeRates(ctx, pairVotes) + k.tallyVotesAndUpdatePrices(ctx, pairVotes, validatorPerformances) + + k.incrementMissCounters(ctx, validatorPerformances) + k.incrementAbstainsByOmission(ctx, whitelistedPairs.Len(), validatorPerformances) + + k.rewardWinners(ctx, validatorPerformances) + + params, _ := k.Params.Get(ctx) + k.ClearVotesAndPrevotes(ctx, params.VotePeriod) + k.RefreshWhitelist(ctx, params.Whitelist, whitelistedPairs) + + for _, validatorPerformance := range validatorPerformances { + _ = ctx.EventManager().EmitTypedEvent(&types.EventValidatorPerformance{ + Validator: validatorPerformance.ValAddress.String(), + VotingPower: validatorPerformance.Power, + RewardWeight: validatorPerformance.RewardWeight, + WinCount: validatorPerformance.WinCount, + AbstainCount: validatorPerformance.AbstainCount, + MissCount: validatorPerformance.MissCount, + }) + } + + return validatorPerformances +} + +// incrementMissCounters it parses all validators performance and increases the +// missed vote of those that did not vote. +func (k Keeper) incrementMissCounters( + ctx sdk.Context, + validatorPerformances types.ValidatorPerformances, +) { + for _, validatorPerformance := range validatorPerformances { + if int(validatorPerformance.MissCount) > 0 { + counter, err := k.MissCounters.Get(ctx, validatorPerformance.ValAddress) + if err != nil { + counter = 0 + } + counter = counter + uint64(validatorPerformance.MissCount) + err = k.MissCounters.Set( + ctx, validatorPerformance.ValAddress, + counter, + ) + if err == nil { + k.Logger(ctx).Info("vote miss", "validator", validatorPerformance.ValAddress.String()) + } else { + k.Logger(ctx).Error("failed to set MissCounter", "validator", validatorPerformance.ValAddress.String(), "counter", counter, "error", err) + } + } + } +} + +func (k Keeper) incrementAbstainsByOmission( + _ sdk.Context, + numPairs int, + validatorPerformances types.ValidatorPerformances, +) { + for valAddr, performance := range validatorPerformances { + omitCount := int64(numPairs) - (performance.WinCount + performance.AbstainCount + performance.MissCount) + if omitCount > 0 { + performance.AbstainCount += omitCount + validatorPerformances[valAddr] = performance + } + } +} + +// tallyVotesAndUpdatePrices processes the votes and updates the ExchangeRates based on the results. +func (k Keeper) tallyVotesAndUpdatePrices( + ctx sdk.Context, + pairVotes map[asset.Pair]types.ExchangeRateVotes, + validatorPerformances types.ValidatorPerformances, +) { + rewardBand := k.RewardBand(ctx) + for pair, votes := range pairVotes { + exchangeRate := Tally(votes, rewardBand, validatorPerformances) + k.SetPrice(ctx, pair, exchangeRate) + } +} + +// getPairVotes returns a map of pairs and votes excluding abstained votes and votes that don't meet the threshold criteria +func (k Keeper) getPairVotes( + ctx sdk.Context, + validatorPerformances types.ValidatorPerformances, + whitelistedPairs set.Set[asset.Pair], +) map[asset.Pair]types.ExchangeRateVotes { + pairVotes := k.GroupVotesByPair(ctx, validatorPerformances) + + k.RemoveInvalidVotes(ctx, pairVotes, whitelistedPairs) + + return pairVotes +} + +// ClearExchangeRates removes all exchange rates from the state +// We remove the price for pair with expired prices or valid votes +func (k Keeper) ClearExchangeRates(ctx sdk.Context, pairVotes map[asset.Pair]types.ExchangeRateVotes) { + params, _ := k.Params.Get(ctx) + + _ = k.ExchangeRates.Walk(ctx, nil, func(key asset.Pair, _ types.DatedPrice) (bool, error) { + _, isValid := pairVotes[key] + previousExchangeRate, _ := k.ExchangeRates.Get(ctx, key) + isExpired := uint64(previousExchangeRate.CreationHeight)+params.ExpirationBlocks <= uint64(ctx.BlockHeight()) + + if isValid || isExpired { + err := k.ExchangeRates.Remove(ctx, key) + if err != nil { + k.Logger(ctx).Error("failed to delete exchange rate", "pair", key.String(), "error", err) + } + } + return false, nil + }) +} + +// newValidatorPerformances creates a new map of validators and their performance, excluding validators that are +// not bonded. +func (k Keeper) newValidatorPerformances(ctx sdk.Context) types.ValidatorPerformances { + validatorPerformances := make(map[string]types.ValidatorPerformance) + + maxValidators, err := k.StakingKeeper.MaxValidators(ctx) + if err != nil { + panic(err) + } + powerReduction := k.StakingKeeper.PowerReduction(ctx) + + iterator, err := k.StakingKeeper.ValidatorsPowerStoreIterator(ctx) + if err != nil { + panic(err) + } + defer iterator.Close() + + for i := 0; iterator.Valid() && i < int(maxValidators); iterator.Next() { + validator, err := k.StakingKeeper.Validator(ctx, iterator.Value()) + + // exclude not bonded + if err != nil || !validator.IsBonded() { + continue + } + + valAddrStr := validator.GetOperator() + valAddr, err := sdk.ValAddressFromBech32(valAddrStr) + if err != nil { + panic(err) + } + validatorPerformances[valAddrStr] = types.NewValidatorPerformance( + validator.GetConsensusPower(powerReduction), + valAddr, + ) + i++ + } + + return validatorPerformances +} diff --git a/x/oracle/keeper/update_exchange_rates_test.go b/x/oracle/keeper/update_exchange_rates_test.go new file mode 100644 index 00000000..d10d7bac --- /dev/null +++ b/x/oracle/keeper/update_exchange_rates_test.go @@ -0,0 +1,650 @@ +package keeper_test + +import ( + "fmt" + "math" + "sort" + "testing" + + "github.com/cometbft/cometbft/libs/rand" + sdk "github.com/cosmos/cosmos-sdk/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + sdkmath "cosmossdk.io/math" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestOracleThreshold(t *testing.T) { + exchangeRates := types.ExchangeRateTuples{ + { + Pair: asset.Registry.Pair(denoms.BTC, denoms.USD), + ExchangeRate: testExchangeRate, + }, + } + exchangeRateStr, err := exchangeRates.ToString() + require.NoError(t, err) + + chain := e2eTesting.NewTestChain(t, 1, + e2eTesting.WithValidatorsNum(5), + e2eTesting.WithBondAmount(testStakingAmt.String()), + ) + keepers := chain.GetApp().Keepers + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + ctx := chain.GetContext() + + vals := chain.GetCurrentValSet().Validators + AccAddrs := make([]sdk.AccAddress, len(vals)) + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + AccAddrs[i] = sdk.AccAddress(vals[i].Address) + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + params.ExpirationBlocks = 0 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + // Case 1. + // Less than the threshold signs, exchange rate consensus fails + for i := 0; i < 1; i++ { + salt := fmt.Sprintf("%d", i) + hash := types.GetAggregateVoteHash(salt, exchangeRateStr, ValAddrs[i]) + prevoteMsg := types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[i], ValAddrs[i]) + voteMsg := types.NewMsgAggregateExchangeRateVote(salt, exchangeRateStr, AccAddrs[i], ValAddrs[i]) + + _, err1 := msgServer.AggregateExchangeRatePrevote(ctx.WithBlockHeight(0), prevoteMsg) + _, err2 := msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(1), voteMsg) + require.NoError(t, err1) + require.NoError(t, err2) + } + keepers.OracleKeeper.UpdateExchangeRates(ctx) + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx.WithBlockHeight(1), exchangeRates[0].Pair) + assert.Error(t, err) + + // Case 2. + // More than the threshold signs, exchange rate consensus succeeds + for i := 0; i < 4; i++ { + salt := fmt.Sprintf("%d", i) + hash := types.GetAggregateVoteHash(salt, exchangeRateStr, ValAddrs[i]) + prevoteMsg := types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[i], ValAddrs[i]) + voteMsg := types.NewMsgAggregateExchangeRateVote(salt, exchangeRateStr, AccAddrs[i], ValAddrs[i]) + + _, err1 := msgServer.AggregateExchangeRatePrevote(ctx.WithBlockHeight(0), prevoteMsg) + _, err2 := msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(1), voteMsg) + require.NoError(t, err1) + require.NoError(t, err2) + } + keepers.OracleKeeper.UpdateExchangeRates(ctx) + rate, err := keepers.OracleKeeper.ExchangeRates.Get(ctx, exchangeRates[0].Pair) + require.NoError(t, err) + assert.Equal(t, testExchangeRate, rate.ExchangeRate) + + // Case 3. + // Increase voting power of absent validator, exchange rate consensus fails + delegateAmount := testStakingAmt.MulRaw(8) + delegateCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, delegateAmount)) + // topup not-bonded pool to withdraw for delegate + err = keepers.BankKeeper.MintCoins( + ctx, + minttypes.ModuleName, + delegateCoins, + ) + require.NoError(t, err) + err = keepers.BankKeeper.SendCoinsFromModuleToModule( + ctx, + minttypes.ModuleName, + stakingtypes.NotBondedPoolName, + delegateCoins, + ) + require.NoError(t, err) + val, err := keepers.StakingKeeper.GetValidator(ctx, ValAddrs[4]) + require.NoError(t, err) + _, err = keepers.StakingKeeper.Delegate(ctx.WithBlockHeight(0), AccAddrs[4], delegateAmount, stakingtypes.Unbonded, val, false) + require.NoError(t, err) + + for i := 0; i < 4; i++ { + salt := fmt.Sprintf("%d", i) + hash := types.GetAggregateVoteHash(salt, exchangeRateStr, ValAddrs[i]) + prevoteMsg := types.NewMsgAggregateExchangeRatePrevote(hash, AccAddrs[i], ValAddrs[i]) + voteMsg := types.NewMsgAggregateExchangeRateVote(salt, exchangeRateStr, AccAddrs[i], ValAddrs[i]) + + _, err = msgServer.AggregateExchangeRatePrevote(ctx.WithBlockHeight(0), prevoteMsg) + require.NoError(t, err) + _, err = msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(1), voteMsg) + require.NoError(t, err) + } + keepers.OracleKeeper.UpdateExchangeRates(ctx) + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, exchangeRates[0].Pair) + assert.Error(t, err) +} + +func TestResetExchangeRates(t *testing.T) { + pair := asset.Registry.Pair(denoms.BTC, denoms.USD) + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + emptyVotes := map[asset.Pair]types.ExchangeRateVotes{} + validVotes := map[asset.Pair]types.ExchangeRateVotes{pair: {}} + + // Set expiration blocks to 10 + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.ExpirationBlocks = 10 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + // Post a price at block 1 + keepers.OracleKeeper.SetPrice(ctx.WithBlockHeight(1), pair, testExchangeRate) + + // reset exchange rates at block 2 + // Price should still be there because not expired yet + keepers.OracleKeeper.ClearExchangeRates(ctx.WithBlockHeight(2), emptyVotes) + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, pair) + assert.NoError(t, err) + + // reset exchange rates at block 3 but pair is in votes + // Price should be removed there because there was a valid votes + keepers.OracleKeeper.ClearExchangeRates(ctx.WithBlockHeight(3), validVotes) + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, pair) + assert.Error(t, err) + + // Post a price at block 69 + // reset exchange rates at block 79 + // Price should not be there anymore because expired + keepers.OracleKeeper.SetPrice(ctx.WithBlockHeight(69), pair, testExchangeRate) + keepers.OracleKeeper.ClearExchangeRates(ctx.WithBlockHeight(79), emptyVotes) + + _, err = keepers.OracleKeeper.ExchangeRates.Get(ctx, pair) + assert.Error(t, err) +} + +func TestOracleTally(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + votes := types.ExchangeRateVotes{} + rates, valAddrs, stakingKeeper := types.GenerateRandomTestCase() + keepers.OracleKeeper.StakingKeeper = stakingKeeper + h := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + for i, rate := range rates { + decExchangeRate := sdkmath.LegacyNewDecWithPrec(int64(rate*math.Pow10(OracleDecPrecision)), int64(OracleDecPrecision)) + exchangeRateStr, err := types.ExchangeRateTuples{ + {ExchangeRate: decExchangeRate, Pair: asset.Registry.Pair(denoms.BTC, denoms.USD)}, + }.ToString() + require.NoError(t, err) + + salt := fmt.Sprintf("%d", i) + hash := types.GetAggregateVoteHash(salt, exchangeRateStr, valAddrs[i]) + prevoteMsg := types.NewMsgAggregateExchangeRatePrevote(hash, sdk.AccAddress(valAddrs[i]), valAddrs[i]) + voteMsg := types.NewMsgAggregateExchangeRateVote(salt, exchangeRateStr, sdk.AccAddress(valAddrs[i]), valAddrs[i]) + + _, err1 := h.AggregateExchangeRatePrevote(ctx.WithBlockHeight(0), prevoteMsg) + _, err2 := h.AggregateExchangeRateVote(ctx.WithBlockHeight(1), voteMsg) + require.NoError(t, err1) + require.NoError(t, err2) + + power := testStakingAmt.QuoRaw(int64(6)).Int64() + if decExchangeRate.IsZero() { + power = int64(0) + } + + vote := types.NewExchangeRateVote( + decExchangeRate, asset.Registry.Pair(denoms.BTC, denoms.USD), valAddrs[i], power) + votes = append(votes, vote) + + // change power of every three validator + if i%3 == 0 { + stakingKeeper.Validators()[i].SetConsensusPower(int64(i + 1)) + } + } + + validatorPerformances := make(types.ValidatorPerformances) + for _, valAddr := range valAddrs { + val, err := stakingKeeper.Validator(ctx, valAddr) + require.NoError(t, err) + validatorPerformances[valAddr.String()] = types.NewValidatorPerformance( + val.GetConsensusPower(sdk.DefaultPowerReduction), + valAddr, + ) + } + sort.Sort(votes) + weightedMedian := votes.WeightedMedianWithAssertion() + standardDeviation := votes.StandardDeviation(weightedMedian) + maxSpread := weightedMedian.Mul(keepers.OracleKeeper.RewardBand(ctx).QuoInt64(2)) + + if standardDeviation.GT(maxSpread) { + maxSpread = standardDeviation + } + + expectedValidatorPerformances := make(types.ValidatorPerformances) + for _, valAddr := range valAddrs { + val, err := stakingKeeper.Validator(ctx, valAddr) + require.NoError(t, err) + expectedValidatorPerformances[valAddr.String()] = types.NewValidatorPerformance( + val.GetConsensusPower(sdk.DefaultPowerReduction), + valAddr, + ) + } + + for _, vote := range votes { + key := vote.Voter.String() + validatorPerformance := expectedValidatorPerformances[key] + if vote.ExchangeRate.GTE(weightedMedian.Sub(maxSpread)) && + vote.ExchangeRate.LTE(weightedMedian.Add(maxSpread)) { + validatorPerformance.RewardWeight += vote.Power + validatorPerformance.WinCount++ + } else if !vote.ExchangeRate.IsPositive() { + validatorPerformance.AbstainCount++ + } else { + validatorPerformance.MissCount++ + } + expectedValidatorPerformances[key] = validatorPerformance + } + + tallyMedian := keeper.Tally( + votes, keepers.OracleKeeper.RewardBand(ctx), validatorPerformances, + ) + + assert.Equal(t, expectedValidatorPerformances, validatorPerformances) + assert.Equal(t, tallyMedian.MulInt64(100).TruncateInt(), weightedMedian.MulInt64(100).TruncateInt()) + assert.NotEqualValues(t, 0, validatorPerformances.TotalRewardWeight(), validatorPerformances.String()) +} + +func TestOracleRewardBand(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(4)) + keepers := chain.GetApp().Keepers + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + ctx := chain.GetContext() + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + params.Whitelist = []asset.Pair{asset.Registry.Pair(denoms.ATOM, denoms.USD)} + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + // clear pairs to reset vote targets + err = keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil) + require.NoError(t, err) + err = keepers.OracleKeeper.WhitelistedPairs.Set(ctx, asset.Registry.Pair(denoms.ATOM, denoms.USD)) + require.NoError(t, err) + + rewardSpread := testExchangeRate.Mul(keepers.OracleKeeper.RewardBand(ctx).QuoInt64(2)) + + // Account 1, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate.Sub(rewardSpread)}, + }, vals[0]) + + // Account 2, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[1]) + + // Account 3, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[2]) + + // Account 4, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate.Add(rewardSpread)}, + }, vals[3]) + + keepers.OracleKeeper.UpdateExchangeRates(ctx) + + counter, err := keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[0]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[1]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[2]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[3]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + + // Account 1 will miss the vote due to raward band condition + // Account 1, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate.Sub(rewardSpread.Add(sdkmath.LegacyOneDec()))}, + }, vals[0]) + + // Account 2, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[1]) + + // Account 3, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}, + }, vals[2]) + + // Account 4, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate.Add(rewardSpread)}, + }, vals[3]) + + keepers.OracleKeeper.UpdateExchangeRates(ctx) + + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[0]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(1), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[1]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[2]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[3]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) +} + +/* TODO(Mercilex): not appliable right now: https://github.com/archway-network/archway/issues/805 +func TestOracleMultiRewardDistribution(t *testing.T) { + input, h := setup(t) + + // SDR and KRW have the same voting power, but KRW has been chosen as referencepair by alphabetical order. + // Account 1, SDR, KRW + makeAggregatePrevoteAndVote(t, input, h, 0, types.ExchangeRateTuples{{Pair: common.Pairbtc:usd.String(), ExchangeRate: randomExchangeRate}, {Pair: common.Pairatom:usd.String(), ExchangeRate: randomExchangeRate}}, vals[0]) + + // Account 2, SDR + makeAggregatePrevoteAndVote(t, input, h, 0, types.ExchangeRateTuples{{Pair: common.Pairbtc:usd.String(), ExchangeRate: randomExchangeRate}}, vals[1]) + + // Account 3, KRW + makeAggregatePrevoteAndVote(t, input, h, 0, types.ExchangeRateTuples{{Pair: common.Pairbtc:usd.String(), ExchangeRate: randomExchangeRate}}, vals[2]) + + rewardAmt := math.NewInt(1e6) + err := input.BankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(denoms.Gov, rewardAmt))) + require.NoError(t, err) + + keepers.OracleKeeper.UpdateExchangeRates(ctx) + + rewardDistributedWindow := keepers.OracleKeeper.RewardDistributionWindow(ctx) + + expectedRewardAmt := math.LegacyNewDecFromInt(rewardAmt.QuoRaw(3).MulRaw(2)).QuoInt64(int64(rewardDistributedWindow)).TruncateInt() + expectedRewardAmt2 := math.ZeroInt() // even vote power is same KRW with SDR, KRW chosen referenceTerra because alphabetical order + expectedRewardAmt3 := math.LegacyNewDecFromInt(rewardAmt.QuoRaw(3)).QuoInt64(int64(rewardDistributedWindow)).TruncateInt() + + rewards := keepers.DistrKeeper.GetValidatorOutstandingRewards(ctx.WithBlockHeight(2), ValAddrs[0]) + assert.Equal(t, expectedRewardAmt, rewards.Rewards.AmountOf(denoms.Gov).TruncateInt()) + rewards = keepers.DistrKeeper.GetValidatorOutstandingRewards(ctx.WithBlockHeight(2), ValAddrs[1]) + assert.Equal(t, expectedRewardAmt2, rewards.Rewards.AmountOf(denoms.Gov).TruncateInt()) + rewards = keepers.DistrKeeper.GetValidatorOutstandingRewards(ctx.WithBlockHeight(2), ValAddrs[2]) + assert.Equal(t, expectedRewardAmt3, rewards.Rewards.AmountOf(denoms.Gov).TruncateInt()) +} +*/ + +func TestOracleExchangeRate(t *testing.T) { + // The following scenario tests four validators providing prices for eth:usd, atom:usd, and btc:usd. + // eth:usd and atom:usd pass, but btc:usd fails due to not enough validators voting. + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(4)) + keepers := chain.GetApp().Keepers + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + ctx := chain.GetContext() + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + atomUsdExchangeRate := sdkmath.LegacyNewDec(1000000) + ethUsdExchangeRate := sdkmath.LegacyNewDec(1000000) + btcusdExchangeRate := sdkmath.LegacyNewDec(1e6) + + // Account 1, eth:usd, atom:usd, btc:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), ExchangeRate: ethUsdExchangeRate}, + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: atomUsdExchangeRate}, + {Pair: asset.Registry.Pair(denoms.BTC, denoms.USD), ExchangeRate: btcusdExchangeRate}, + }, vals[0]) + + // Account 2, eth:usd, atom:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), ExchangeRate: ethUsdExchangeRate}, + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: atomUsdExchangeRate}, + }, vals[1]) + + // Account 3, eth:usd, atom:usd, btc:usd(abstain) + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), ExchangeRate: ethUsdExchangeRate}, + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: atomUsdExchangeRate}, + {Pair: asset.Registry.Pair(denoms.BTC, denoms.USD), ExchangeRate: sdkmath.LegacyZeroDec()}, + }, vals[2]) + + // Account 4, eth:usd, atom:usd, btc:usd + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), ExchangeRate: ethUsdExchangeRate}, + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: atomUsdExchangeRate}, + {Pair: asset.Registry.Pair(denoms.BTC, denoms.USD), ExchangeRate: sdkmath.LegacyZeroDec()}, + }, vals[3]) + + ethUsdRewards := sdk.NewInt64Coin("ETHREWARD", 2000000) + atomUsdRewards := sdk.NewInt64Coin("ATOMREWARD", 3000000) + + require.NoError(t, keepers.BankKeeper.MintCoins(ctx, minttypes.ModuleName, sdk.NewCoins(ethUsdRewards))) + require.NoError(t, keepers.OracleKeeper.AllocateRewards(ctx, minttypes.ModuleName, sdk.NewCoins(ethUsdRewards), 1)) + require.NoError(t, keepers.BankKeeper.MintCoins(ctx, minttypes.ModuleName, sdk.NewCoins(atomUsdRewards))) + require.NoError(t, keepers.OracleKeeper.AllocateRewards(ctx, minttypes.ModuleName, sdk.NewCoins(atomUsdRewards), 1)) + + keepers.OracleKeeper.UpdateExchangeRates(ctx) + + // total reward pool for the current vote period is 1* common.TO_MICRO for eth:usd and 1* common.TO_MICRO for atom:usd + // val 1,2,3,4 all won on 2 pairs + // so total votes are 2 * 2 + 2 + 2 = 8 + expectedRewardAmt := sdk.NewDecCoinsFromCoins(ethUsdRewards, atomUsdRewards). + QuoDec(sdkmath.LegacyNewDec(8)). // total votes + MulDec(sdkmath.LegacyNewDec(2)) // votes won by val1 and val2 + rewards, err := keepers.DistrKeeper.GetValidatorOutstandingRewards(ctx.WithBlockHeight(2), ValAddrs[0]) + require.NoError(t, err) + assert.Equalf(t, expectedRewardAmt, rewards.Rewards, "%s <-> %s", expectedRewardAmt, rewards.Rewards) + rewards, err = keepers.DistrKeeper.GetValidatorOutstandingRewards(ctx.WithBlockHeight(2), ValAddrs[1]) + require.NoError(t, err) + assert.Equalf(t, expectedRewardAmt, rewards.Rewards, "%s <-> %s", expectedRewardAmt, rewards.Rewards) + rewards, err = keepers.DistrKeeper.GetValidatorOutstandingRewards(ctx.WithBlockHeight(2), ValAddrs[2]) + require.NoError(t, err) + assert.Equalf(t, expectedRewardAmt, rewards.Rewards, "%s <-> %s", expectedRewardAmt, rewards.Rewards) + rewards, err = keepers.DistrKeeper.GetValidatorOutstandingRewards(ctx.WithBlockHeight(2), ValAddrs[3]) + require.NoError(t, err) + assert.Equalf(t, expectedRewardAmt, rewards.Rewards, "%s <-> %s", expectedRewardAmt, rewards.Rewards) +} + +func TestOracleRandomPrices(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(4)) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + + vals := chain.GetCurrentValSet().Validators + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + for i := 0; i < 100; i++ { + for _, val := range vals { + MakeAggregatePrevoteAndVote(t, ctx, msgServer, 0, types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.ETH, denoms.USD), ExchangeRate: sdkmath.LegacyNewDec(int64(rand.Uint64() % 1e6))}, + {Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: sdkmath.LegacyNewDec(int64(rand.Uint64() % 1e6))}, + }, val) + } + + require.NotPanics(t, func() { + keepers.OracleKeeper.UpdateExchangeRates(ctx) + }) + } +} + +func TestWhitelistedPairs(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithValidatorsNum(5)) + keepers := chain.GetApp().Keepers + msgServer := keeper.NewMsgServerImpl(keepers.OracleKeeper) + ctx := chain.GetContext() + + vals := chain.GetCurrentValSet().Validators + ValAddrs := make([]sdk.ValAddress, len(vals)) + for i := range vals { + ValAddrs[i] = sdk.ValAddress(vals[i].Address) + } + + params, err := keepers.OracleKeeper.Params.Get(ctx) + require.NoError(t, err) + params.VotePeriod = 1 + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + + t.Log("whitelist ONLY atom:usd") + err = keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil) + require.NoError(t, err) + err = keepers.OracleKeeper.WhitelistedPairs.Set(ctx, asset.Registry.Pair(denoms.ATOM, denoms.USD)) + require.NoError(t, err) + + t.Log("vote and prevote from all vals on atom:usd") + priceVoteFromVal := func(valIdx int, block int64) { + MakeAggregatePrevoteAndVote(t, ctx, msgServer, block, types.ExchangeRateTuples{{Pair: asset.Registry.Pair(denoms.ATOM, denoms.USD), ExchangeRate: testExchangeRate}}, vals[valIdx]) + } + block := int64(0) + priceVoteFromVal(0, block) + priceVoteFromVal(1, block) + priceVoteFromVal(2, block) + priceVoteFromVal(3, block) + + t.Log("whitelist btc:usd for next vote period") + params.Whitelist = []asset.Pair{asset.Registry.Pair(denoms.ATOM, denoms.USD), asset.Registry.Pair(denoms.BTC, denoms.USD)} + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + keepers.OracleKeeper.UpdateExchangeRates(ctx) + + t.Log("assert: no miss counts for all vals") + counter, err := keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[0]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[1]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[2]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + counter, err = keepers.OracleKeeper.MissCounters.Get(ctx, ValAddrs[3]) + if err != nil { + counter = 0 + } + assert.Equal(t, uint64(0), counter) + + t.Log("whitelisted pairs are {atom:usd, btc:usd}") + pairs, err := keepers.OracleKeeper.GetWhitelistedPairs(ctx) + require.NoError(t, err) + assert.Equal(t, + []asset.Pair{ + asset.Registry.Pair(denoms.ATOM, denoms.USD), + asset.Registry.Pair(denoms.BTC, denoms.USD), + }, + pairs, + ) + + t.Log("vote from vals 0-3 on atom:usd (but not btc:usd)") + priceVoteFromVal(0, block) + priceVoteFromVal(1, block) + priceVoteFromVal(2, block) + priceVoteFromVal(3, block) + + t.Log("delete btc:usd for next vote period") + params.Whitelist = []asset.Pair{asset.Registry.Pair(denoms.ATOM, denoms.USD)} + require.NoError(t, keepers.OracleKeeper.Params.Set(ctx, params)) + perfs := keepers.OracleKeeper.UpdateExchangeRates(ctx) + + t.Log("validators 0-3 all voted -> expect win") + for valIdx := 0; valIdx < 4; valIdx++ { + perf := perfs[ValAddrs[valIdx].String()] + assert.EqualValues(t, 1, perf.WinCount) + assert.EqualValues(t, 1, perf.AbstainCount) + assert.EqualValues(t, 0, perf.MissCount) + } + t.Log("validators 4 didn't vote -> expect abstain") + perf := perfs[ValAddrs[4].String()] + assert.EqualValues(t, 0, perf.WinCount) + assert.EqualValues(t, 2, perf.AbstainCount) + assert.EqualValues(t, 0, perf.MissCount) + + t.Log("btc:usd must be deleted") + pairs, err = keepers.OracleKeeper.GetWhitelistedPairs(ctx) + require.NoError(t, err) + assert.Equal(t, + []asset.Pair{asset.Registry.Pair(denoms.ATOM, denoms.USD)}, + pairs, + ) + has, err := keepers.OracleKeeper.WhitelistedPairs.Has(ctx, asset.Registry.Pair(denoms.BTC, denoms.USD)) + require.NoError(t, err) + require.False(t, has) + + t.Log("vote from vals 0-3 on atom:usd") + priceVoteFromVal(0, block) + priceVoteFromVal(1, block) + priceVoteFromVal(2, block) + priceVoteFromVal(3, block) + perfs = keepers.OracleKeeper.UpdateExchangeRates(ctx) + + t.Log("Although validators 0-2 voted, it's for the same period -> expect abstains for everyone") + for valIdx := 0; valIdx < 4; valIdx++ { + perf := perfs[ValAddrs[valIdx].String()] + assert.EqualValues(t, 1, perf.WinCount) + assert.EqualValues(t, 0, perf.AbstainCount) + assert.EqualValues(t, 0, perf.MissCount) + } + perf = perfs[ValAddrs[4].String()] + assert.EqualValues(t, 0, perf.WinCount) + assert.EqualValues(t, 1, perf.AbstainCount) + assert.EqualValues(t, 0, perf.MissCount) +} diff --git a/x/oracle/keeper/utils_test.go b/x/oracle/keeper/utils_test.go new file mode 100644 index 00000000..9b13bcf3 --- /dev/null +++ b/x/oracle/keeper/utils_test.go @@ -0,0 +1,96 @@ +// nolint +package keeper_test + +import ( + "math/rand" + "reflect" + "testing" + + "cosmossdk.io/math" + e2eTesting "github.com/archway-network/archway/e2e/testing" + oracletypes "github.com/archway-network/archway/x/oracle/types" + + abci "github.com/cometbft/cometbft/abci/types" + cmTypes "github.com/cometbft/cometbft/types" + sdk "github.com/cosmos/cosmos-sdk/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + "github.com/cosmos/gogoproto/proto" + "github.com/stretchr/testify/require" +) + +// Test addresses +var ( + InitTokens = sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction) + InitCoins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, InitTokens)) + + testStakingAmt = sdk.TokensFromConsensusPower(10, sdk.DefaultPowerReduction) + testExchangeRate = math.LegacyNewDec(1700) + + OracleDecPrecision = 8 +) + +func AllocateRewards(t *testing.T, chain e2eTesting.TestChain, rewards sdk.Coins, votePeriods uint64) { + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + require.NoError(t, keepers.BankKeeper.MintCoins(ctx, minttypes.ModuleName, rewards)) + require.NoError(t, keepers.OracleKeeper.AllocateRewards(ctx, minttypes.ModuleName, rewards, votePeriods)) +} + +func MakeAggregatePrevoteAndVote( + t *testing.T, + ctx sdk.Context, + msgServer oracletypes.MsgServer, + height int64, + rates oracletypes.ExchangeRateTuples, + val *cmTypes.Validator, +) { + accAddr := sdk.AccAddress(val.Address) + valAddr := sdk.ValAddress(val.Address) + + salt := "1" + ratesStr, err := rates.ToString() + require.NoError(t, err) + hash := oracletypes.GetAggregateVoteHash(salt, ratesStr, valAddr) + + prevoteMsg := oracletypes.NewMsgAggregateExchangeRatePrevote(hash, accAddr, valAddr) + _, err = msgServer.AggregateExchangeRatePrevote(ctx.WithBlockHeight(height), prevoteMsg) + require.NoError(t, err) + + // chain.GetApp().Keepers.OracleKeeper.VotePeriod(ctx) + voteMsg := oracletypes.NewMsgAggregateExchangeRateVote(salt, ratesStr, accAddr, valAddr) + _, err = msgServer.AggregateExchangeRateVote(ctx.WithBlockHeight(height+1), voteMsg) + require.NoError(t, err) +} + +var alphabet = "abcdefghijklmnopqrstuvwxyz" + +func RandLetters(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = alphabet[rand.Intn(len(alphabet))] + } + return string(b) +} + +func RequireContainsTypedEvent(t require.TestingT, ctx sdk.Context, event proto.Message) { + foundEvents := []proto.Message{} + for _, abciEvent := range ctx.EventManager().Events() { + eventType := proto.MessageName(event) + if abciEvent.Type != eventType { + continue + } + typedEvent, err := sdk.ParseTypedEvent(abci.Event{ + Type: abciEvent.Type, + Attributes: abciEvent.Attributes, + }) + require.NoError(t, err) + + if reflect.DeepEqual(typedEvent, event) { + return + } else { + foundEvents = append(foundEvents, typedEvent) + } + } + + t.Errorf("event not found, event: %+v, found events: %+v", event, foundEvents) +} diff --git a/x/oracle/keeper/whitelist.go b/x/oracle/keeper/whitelist.go new file mode 100644 index 00000000..15154acd --- /dev/null +++ b/x/oracle/keeper/whitelist.go @@ -0,0 +1,57 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/archway-network/archway/types/set" + "github.com/archway-network/archway/x/oracle/asset" +) + +// IsWhitelistedPair returns existence of a pair in the voting target list +func (k Keeper) IsWhitelistedPair(ctx sdk.Context, pair asset.Pair) (bool, error) { + return k.WhitelistedPairs.Has(ctx, pair) +} + +// GetWhitelistedPairs returns the whitelisted pairs list on current vote period +func (k Keeper) GetWhitelistedPairs(ctx sdk.Context) ([]asset.Pair, error) { + iter, err := k.WhitelistedPairs.Iterate(ctx, nil) + if err != nil { + return nil, err + } + keys, err := iter.Keys() + if err != nil { + return nil, err + } + return keys, nil +} + +// RefreshWhitelist updates the whitelist by detecting possible changes between +// the current vote targets and the current updated whitelist. +func (k Keeper) RefreshWhitelist(ctx sdk.Context, nextWhitelist []asset.Pair, currentWhitelist set.Set[asset.Pair]) { + updateRequired := false + + if currentWhitelist.Len() != len(nextWhitelist) { + updateRequired = true + } else { + for _, pair := range nextWhitelist { + _, exists := currentWhitelist[pair] + if !exists { + updateRequired = true + break + } + } + } + + if updateRequired { + err := k.WhitelistedPairs.Clear(ctx, nil) + if err != nil { + panic(err) + } + for _, pair := range nextWhitelist { + err = k.WhitelistedPairs.Set(ctx, pair) + if err != nil { + panic(err) + } + } + } +} diff --git a/x/oracle/keeper/whitelist_test.go b/x/oracle/keeper/whitelist_test.go new file mode 100644 index 00000000..1bdac388 --- /dev/null +++ b/x/oracle/keeper/whitelist_test.go @@ -0,0 +1,143 @@ +package keeper_test + +import ( + "sort" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/types/set" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" +) + +func TestKeeper_GetVoteTargets(t *testing.T) { + type TestCase struct { + name string + in []asset.Pair + panic bool + } + + panicCases := []TestCase{ + {name: "blank pair", in: []asset.Pair{""}, panic: true}, + {name: "blank pair and others", in: []asset.Pair{"", "x", "abc", "defafask"}, panic: true}, + {name: "denom len too short", in: []asset.Pair{"x:y", "xx:yy"}, panic: true}, + } + happyCases := []TestCase{ + {name: "happy", in: []asset.Pair{"foo:bar", "whoo:whoo"}}, + } + + for _, testCase := range append(panicCases, happyCases...) { + tc := testCase + t.Run(tc.name, func(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + err := keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil) + require.NoError(t, err) + + expectedTargets := tc.in + for _, target := range expectedTargets { + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Set(ctx, target)) + } + + var panicAssertFn func(t assert.TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) bool + switch tc.panic { + case true: + panicAssertFn = assert.Panics + default: + panicAssertFn = assert.NotPanics + } + panicAssertFn(t, func() { + targets, err := keepers.OracleKeeper.GetWhitelistedPairs(ctx) + require.NoError(t, err) + assert.Equal(t, expectedTargets, targets) + }) + }) + } + + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + err := keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil) + require.NoError(t, err) + + expectedTargets := []asset.Pair{"foo:bar", "whoo:whoo"} + for _, target := range expectedTargets { + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Set(ctx, target)) + } + + targets, err := keepers.OracleKeeper.GetWhitelistedPairs(ctx) + require.NoError(t, err) + require.Equal(t, expectedTargets, targets) +} + +func TestIsWhitelistedPair(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + err := keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil) + require.NoError(t, err) + + validPairs := []asset.Pair{"foo:bar", "xxx:yyy", "whoo:whoo"} + for _, target := range validPairs { + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Set(ctx, target)) + flag, err := keepers.OracleKeeper.IsWhitelistedPair(ctx, target) + require.NoError(t, err) + require.True(t, flag) + } +} + +func TestUpdateWhitelist(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + keepers := chain.GetApp().Keepers + ctx := chain.GetContext() + + // prepare test by resetting the genesis pairs + err := keepers.OracleKeeper.WhitelistedPairs.Clear(ctx, nil) + require.NoError(t, err) + + currentWhitelist := set.New(asset.NewPair(denoms.NIBI, denoms.USD), asset.NewPair(denoms.BTC, denoms.USD)) + for p := range currentWhitelist { + require.NoError(t, keepers.OracleKeeper.WhitelistedPairs.Set(ctx, p)) + } + + nextWhitelist := set.New(asset.NewPair(denoms.NIBI, denoms.USD), asset.NewPair(denoms.BTC, denoms.USD)) + + // no updates case + whitelistSlice := nextWhitelist.ToSlice() + sort.Slice(whitelistSlice, func(i, j int) bool { + return whitelistSlice[i].String() < whitelistSlice[j].String() + }) + keepers.OracleKeeper.RefreshWhitelist(ctx, whitelistSlice, currentWhitelist) + pairs, err := keepers.OracleKeeper.GetWhitelistedPairs(ctx) + require.NoError(t, err) + assert.Equal(t, whitelistSlice, pairs) + + // len update (fast path) + nextWhitelist.Add(asset.NewPair(denoms.NIBI, denoms.ETH)) + whitelistSlice = nextWhitelist.ToSlice() + sort.Slice(whitelistSlice, func(i, j int) bool { + return whitelistSlice[i].String() < whitelistSlice[j].String() + }) + keepers.OracleKeeper.RefreshWhitelist(ctx, whitelistSlice, currentWhitelist) + pairs, err = keepers.OracleKeeper.GetWhitelistedPairs(ctx) + require.NoError(t, err) + assert.Equal(t, whitelistSlice, pairs) + + // diff update (slow path) + currentWhitelist.Add(asset.NewPair(denoms.NIBI, denoms.ATOM)) + whitelistSlice = nextWhitelist.ToSlice() + sort.Slice(whitelistSlice, func(i, j int) bool { + return whitelistSlice[i].String() < whitelistSlice[j].String() + }) + keepers.OracleKeeper.RefreshWhitelist(ctx, whitelistSlice, currentWhitelist) + pairs, err = keepers.OracleKeeper.GetWhitelistedPairs(ctx) + require.NoError(t, err) + assert.Equal(t, whitelistSlice, pairs) +} diff --git a/x/oracle/module.go b/x/oracle/module.go new file mode 100644 index 00000000..7e94fd1d --- /dev/null +++ b/x/oracle/module.go @@ -0,0 +1,197 @@ +package oracle + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/archway-network/archway/x/oracle/client/cli" + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/simulation" + "github.com/archway-network/archway/x/oracle/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModuleSimulation = AppModule{} + _ module.HasABCIEndBlock = AppModule{} + _ module.HasABCIGenesis = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesisBasics = AppModule{} + _ module.HasInvariants = AppModule{} + _ module.HasName = AppModule{} + _ module.HasServices = AppModule{} +) + +// AppModuleBasic defines the basic application module used by the oracle module. +type AppModuleBasic struct { + cdc codec.Codec +} + +// Name returns the module's name +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the module's types on the given LegacyAmino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +// RegisterInterfaces registers the module's interface types +func (b AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + types.RegisterInterfaces(registry) +} + +// DefaultGenesis returns default genesis state as raw bytes for the staking +// module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the oracle module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var data types.GenesisState + if err := cdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + + return types.ValidateGenesis(&data) +} + +// RegisterRESTRoutes registers the REST routes for the oracle module. +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { +} + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} + +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the oracle module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + _ = types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) +} + +// GetTxCmd returns the root tx command for the oracle module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns no root query command for the oracle module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +//___________________________ + +// AppModule implements an application module for the oracle module. +type AppModule struct { + AppModuleBasic + keeper keeper.Keeper + accountKeeper types.AccountKeeper + bankKeeper types.BankKeeper +} + +// NewAppModule creates a new AppModule object +func NewAppModule( + cdc codec.Codec, + keeper keeper.Keeper, + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, +) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{cdc}, + keeper: keeper, + accountKeeper: accountKeeper, + bankKeeper: bankKeeper, + } +} + +// Name returns the oracle module's name. +func (AppModule) Name() string { return types.ModuleName } + +// RegisterInvariants performs a no-op. +func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + querier := keeper.NewQuerier(am.keeper) + types.RegisterQueryServer(cfg.QueryServer(), querier) +} + +// InitGenesis performs genesis initialization for the oracle module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + InitGenesis(ctx, am.keeper, &genesisState) + + return nil +} + +// ExportGenesis returns the exported genesis state as raw bytes for the oracle +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs := ExportGenesis(ctx, am.keeper) + return cdc.MustMarshalJSON(gs) +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// BeginBlock returns the begin blocker for the oracle module. +func (AppModule) BeginBlock(_ sdk.Context) {} + +// EndBlock returns the end blocker for the oracle module. +func (am AppModule) EndBlock(ctx context.Context) ([]abci.ValidatorUpdate, error) { + err := EndBlocker(sdk.UnwrapSDKContext(ctx), am.keeper) + if err != nil { + return nil, err + } + return []abci.ValidatorUpdate{}, nil +} + +//____________________________________________________________________________ + +// AppModuleSimulation functions + +// GenerateGenesisState creates a randomized GenState of the oracle module. +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState) +} + +// ProposalContents returns all the oracle content functions used to +// simulate governance proposals. +func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalMsg { + return nil +} + +// RegisterStoreDecoder registers a decoder for oracle module's types +func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) { + sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc) +} + +// WeightedOperations returns the all the oracle module operations with their respective weights. +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { + return simulation.WeightedOperations( + simState.AppParams, simState.Cdc, + am.accountKeeper, am.bankKeeper, am.keeper, + ) +} diff --git a/x/oracle/simulation/decoder.go b/x/oracle/simulation/decoder.go new file mode 100644 index 00000000..6e7bde0d --- /dev/null +++ b/x/oracle/simulation/decoder.go @@ -0,0 +1,63 @@ +package simulation + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/kv" + gogotypes "github.com/cosmos/gogoproto/types" + + "cosmossdk.io/collections" + + archcodec "github.com/archway-network/archway/types/codec" + "github.com/archway-network/archway/x/oracle/types" +) + +// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's +// Value to the corresponding oracle type. +func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string { + return func(kvA, kvB kv.Pair) string { + switch kvA.Key[0] { + case 1: + _, a, err := archcodec.DecValueEncoder.Decode(kvA.Value) + if err != nil { + panic(err) + } + _, b, err := archcodec.DecValueEncoder.Decode(kvB.Value) + if err != nil { + panic(err) + } + return fmt.Sprintf("%v\n%v", a, b) + case 2: + return fmt.Sprintf("%v\n%v", sdk.AccAddress(kvA.Value), sdk.AccAddress(kvB.Value)) + case 3: + var counterA, counterB gogotypes.UInt64Value + cdc.MustUnmarshal(kvA.Value, &counterA) + cdc.MustUnmarshal(kvB.Value, &counterB) + return fmt.Sprintf("%v\n%v", counterA.Value, counterB.Value) + case 4: + var prevoteA, prevoteB types.AggregateExchangeRatePrevote + cdc.MustUnmarshal(kvA.Value, &prevoteA) + cdc.MustUnmarshal(kvB.Value, &prevoteB) + return fmt.Sprintf("%v\n%v", prevoteA, prevoteB) + case 5: + var voteA, voteB types.AggregateExchangeRateVote + cdc.MustUnmarshal(kvA.Value, &voteA) + cdc.MustUnmarshal(kvB.Value, &voteB) + return fmt.Sprintf("%v\n%v", voteA, voteB) + case 6: + _, a, err := collections.StringKey.Decode(kvA.Key[1:]) + if err != nil { + panic(err) + } + _, b, err := collections.StringKey.Decode(kvB.Key[1:]) + if err != nil { + panic(err) + } + return fmt.Sprintf("%s\n%s", a, b) + default: + panic(fmt.Sprintf("invalid oracle key prefix %X", kvA.Key[:1])) + } + } +} diff --git a/x/oracle/simulation/decoder_test.go b/x/oracle/simulation/decoder_test.go new file mode 100644 index 00000000..05359f24 --- /dev/null +++ b/x/oracle/simulation/decoder_test.go @@ -0,0 +1,82 @@ +package simulation_test + +import ( + "fmt" + "testing" + + "cosmossdk.io/math" + "github.com/cometbft/cometbft/crypto/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/kv" + gogotypes "github.com/cosmos/gogoproto/types" + "github.com/stretchr/testify/require" + + e2eTesting "github.com/archway-network/archway/e2e/testing" + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + sim "github.com/archway-network/archway/x/oracle/simulation" + "github.com/archway-network/archway/x/oracle/types" +) + +var ( + delPk = ed25519.GenPrivKey().PubKey() + feederAddr = sdk.AccAddress(delPk.Address()) + valAddr = sdk.ValAddress(delPk.Address()) +) + +func TestDecodeDistributionStore(t *testing.T) { + chain := e2eTesting.NewTestChain(t, 1) + cdc := chain.GetAppCodec() + dec := sim.NewDecodeStore(cdc) + + exchangeRate := math.LegacyNewDecWithPrec(1234, 1) + missCounter := uint64(23) + + aggregatePrevote := types.NewAggregateExchangeRatePrevote(types.AggregateVoteHash([]byte("12345")), valAddr, 123) + aggregateVote := types.NewAggregateExchangeRateVote(types.ExchangeRateTuples{ + {Pair: asset.Registry.Pair(denoms.NIBI, denoms.NUSD), ExchangeRate: math.LegacyNewDecWithPrec(1234, 1)}, + {Pair: asset.Registry.Pair(denoms.ETH, denoms.NUSD), ExchangeRate: math.LegacyNewDecWithPrec(4321, 1)}, + }, valAddr) + + pair := "btc:usd" + + erBytes, err := exchangeRate.Marshal() + require.NoError(t, err) + + kvPairs := kv.Pairs{ + Pairs: []kv.Pair{ + {Key: []byte{0x1, 0x2, 0x3, 0x4, 0x5}, Value: erBytes}, + {Key: []byte{0x2, 0x3, 0x4, 0x5, 0x6}, Value: feederAddr.Bytes()}, + {Key: []byte{0x3, 0x4, 0x5, 0x6, 0x7}, Value: cdc.MustMarshal(&gogotypes.UInt64Value{Value: missCounter})}, + {Key: []byte{0x4, 0x3, 0x5, 0x7, 0x8}, Value: cdc.MustMarshal(&aggregatePrevote)}, + {Key: []byte{0x5, 0x6, 0x7, 0x8, 0x9}, Value: cdc.MustMarshal(&aggregateVote)}, + {Key: append([]byte{0x6}, []byte(pair)...), Value: []byte{}}, + {Key: []byte{0x99}, Value: []byte{0x99}}, + }, + } + + tests := []struct { + name string + expectedLog string + }{ + {"ExchangeRate", fmt.Sprintf("%v\n%v", exchangeRate, exchangeRate)}, + {"FeederDelegation", fmt.Sprintf("%v\n%v", feederAddr, feederAddr)}, + {"MissCounter", fmt.Sprintf("%v\n%v", missCounter, missCounter)}, + {"AggregatePrevote", fmt.Sprintf("%v\n%v", aggregatePrevote, aggregatePrevote)}, + {"AggregateVote", fmt.Sprintf("%v\n%v", aggregateVote, aggregateVote)}, + {"Pairs", fmt.Sprintf("%s\n%s", pair, pair)}, + {"other", ""}, + } + + for i, tt := range tests { + i, tt := i, tt + t.Run(tt.name, func(t *testing.T) { + switch i { + case len(tests) - 1: + require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name) + default: + require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name) + } + }) + } +} diff --git a/x/oracle/simulation/genesis.go b/x/oracle/simulation/genesis.go new file mode 100644 index 00000000..5db0048d --- /dev/null +++ b/x/oracle/simulation/genesis.go @@ -0,0 +1,127 @@ +package simulation + +// DONTCOVER + +import ( + "encoding/json" + "fmt" + "math/rand" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/archway-network/archway/x/oracle/types" +) + +// Simulation parameter constants +const ( + voteThresholdKey = "vote_threshold" + rewardBandKey = "reward_band" + slashFractionKey = "slash_fraction" + slashWindowKey = "slash_window" + minValidPerWindowKey = "min_valid_per_window" +) + +// GenVotePeriod randomized VotePeriod +func GenVotePeriod(r *rand.Rand) uint64 { + return uint64(1 + r.Intn(100)) +} + +// GenVoteThreshold randomized VoteThreshold +func GenVoteThreshold(r *rand.Rand) math.LegacyDec { + return math.LegacyNewDecWithPrec(333, 3).Add(math.LegacyNewDecWithPrec(int64(r.Intn(333)), 3)) +} + +// GenRewardBand randomized RewardBand +func GenRewardBand(r *rand.Rand) math.LegacyDec { + return math.LegacyZeroDec().Add(math.LegacyNewDecWithPrec(int64(r.Intn(100)), 3)) +} + +// GenRewardDistributionWindow randomized RewardDistributionWindow +func GenRewardDistributionWindow(r *rand.Rand) uint64 { + return uint64(100 + r.Intn(100000)) +} + +// GenSlashFraction randomized SlashFraction +func GenSlashFraction(r *rand.Rand) math.LegacyDec { + return math.LegacyZeroDec().Add(math.LegacyNewDecWithPrec(int64(r.Intn(100)), 3)) +} + +// GenSlashWindow randomized SlashWindow +func GenSlashWindow(r *rand.Rand) uint64 { + return uint64(100 + r.Intn(100000)) +} + +// GenMinValidPerWindow randomized MinValidPerWindow +func GenMinValidPerWindow(r *rand.Rand) math.LegacyDec { + return math.LegacyZeroDec().Add(math.LegacyNewDecWithPrec(int64(r.Intn(500)), 3)) +} + +// RandomizedGenState generates a random GenesisState for oracle +func RandomizedGenState(simState *module.SimulationState) { + var voteThreshold math.LegacyDec + simState.AppParams.GetOrGenerate( + voteThresholdKey, &voteThreshold, simState.Rand, + func(r *rand.Rand) { voteThreshold = GenVoteThreshold(r) }, + ) + + var rewardBand math.LegacyDec + simState.AppParams.GetOrGenerate( + rewardBandKey, &rewardBand, simState.Rand, + func(r *rand.Rand) { rewardBand = GenRewardBand(r) }, + ) + + var slashFraction math.LegacyDec + simState.AppParams.GetOrGenerate( + slashFractionKey, &slashFraction, simState.Rand, + func(r *rand.Rand) { slashFraction = GenSlashFraction(r) }, + ) + + var slashWindow uint64 + simState.AppParams.GetOrGenerate( + slashWindowKey, &slashWindow, simState.Rand, + func(r *rand.Rand) { slashWindow = GenSlashWindow(r) }, + ) + + var minValidPerWindow math.LegacyDec + simState.AppParams.GetOrGenerate( + minValidPerWindowKey, &minValidPerWindow, simState.Rand, + func(r *rand.Rand) { minValidPerWindow = GenMinValidPerWindow(r) }, + ) + + oracleGenesis := types.NewGenesisState( + types.Params{ + VotePeriod: uint64(10_000), + VoteThreshold: voteThreshold, + RewardBand: rewardBand, + Whitelist: []asset.Pair{ + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + asset.Registry.Pair(denoms.USDC, denoms.NUSD), + asset.Registry.Pair(denoms.BTC, denoms.NUSD), + asset.Registry.Pair(denoms.NIBI, denoms.NUSD), + }, + SlashFraction: slashFraction, + SlashWindow: slashWindow, + MinValidPerWindow: minValidPerWindow, + }, + []types.ExchangeRateTuple{ + {Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), ExchangeRate: math.LegacyNewDec(20_000)}, + }, + []types.FeederDelegation{}, + []types.MissCounter{}, + []types.AggregateExchangeRatePrevote{}, + []types.AggregateExchangeRateVote{}, + []asset.Pair{}, + []types.Rewards{}, + ) + + bz, err := json.MarshalIndent(&oracleGenesis, "", " ") + if err != nil { + panic(err) + } + fmt.Printf("Selected randomly generated oracle parameters:\n%s\n", bz) + simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(oracleGenesis) +} diff --git a/x/oracle/simulation/operations.go b/x/oracle/simulation/operations.go new file mode 100644 index 00000000..9fba067f --- /dev/null +++ b/x/oracle/simulation/operations.go @@ -0,0 +1,289 @@ +package simulation + +// DONTCOVER + +import ( + "math/rand" + "strings" + + "cosmossdk.io/math" + "github.com/CosmWasm/wasmd/app/params" + "github.com/cosmos/cosmos-sdk/types/module/testutil" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + + helpers "github.com/cosmos/cosmos-sdk/testutil/sims" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + + "github.com/archway-network/archway/x/oracle/keeper" + "github.com/archway-network/archway/x/oracle/types" +) + +// Simulation operation weights constants +const ( + OpWeightMsgAggregateExchangeRatePrevote = "op_weight_msg_exchange_rate_aggregate_prevote" + OpWeightMsgAggregateExchangeRateVote = "op_weight_msg_exchange_rate_aggregate_vote" + OpWeightMsgDelegateFeedConsent = "op_weight_msg_exchange_feed_consent" + + salt = "1234" +) + +var ( + whitelist = []asset.Pair{asset.Registry.Pair(denoms.BTC, denoms.NUSD), asset.Registry.Pair(denoms.ETH, denoms.NUSD), asset.Registry.Pair(denoms.NIBI, denoms.NUSD)} + voteHashMap map[string]string = make(map[string]string) +) + +// WeightedOperations returns all the operations from the module with their respective weights +func WeightedOperations( + appParams simtypes.AppParams, + cdc codec.JSONCodec, + ak types.AccountKeeper, + bk types.BankKeeper, + k keeper.Keeper, +) simulation.WeightedOperations { + var ( + weightMsgAggregateExchangeRatePrevote int + weightMsgAggregateExchangeRateVote int + weightMsgDelegateFeedConsent int + ) + appParams.GetOrGenerate(OpWeightMsgAggregateExchangeRatePrevote, &weightMsgAggregateExchangeRatePrevote, nil, + func(_ *rand.Rand) { + weightMsgAggregateExchangeRatePrevote = params.DefaultWeightMsgSend * 2 + }, + ) + + appParams.GetOrGenerate(OpWeightMsgAggregateExchangeRateVote, &weightMsgAggregateExchangeRateVote, nil, + func(_ *rand.Rand) { + weightMsgAggregateExchangeRateVote = params.DefaultWeightMsgSend * 2 + }, + ) + + appParams.GetOrGenerate(OpWeightMsgDelegateFeedConsent, &weightMsgDelegateFeedConsent, nil, + func(_ *rand.Rand) { + weightMsgDelegateFeedConsent = params.DefaultWeightMsgDelegate // TODO: temp fix + }, + ) + + return simulation.WeightedOperations{ + simulation.NewWeightedOperation( + weightMsgAggregateExchangeRatePrevote, + SimulateMsgAggregateExchangeRatePrevote(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgAggregateExchangeRateVote, + SimulateMsgAggregateExchangeRateVote(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgDelegateFeedConsent, + SimulateMsgDelegateFeedConsent(ak, bk, k), + ), + } +} + +// SimulateMsgAggregateExchangeRatePrevote generates a MsgAggregateExchangeRatePrevote with random values. +// nolint: funlen +func SimulateMsgAggregateExchangeRatePrevote(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + simAccount, _ := simtypes.RandomAcc(r, accs) + address := sdk.ValAddress(simAccount.Address) + + // ensure the validator exists + val, err := k.StakingKeeper.Validator(ctx, address) + if err != nil || !val.IsBonded() { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgAggregateExchangeRatePrevote, "unable to find validator"), nil, err + } + + exchangeRatesStr := "" + for _, pair := range whitelist { + price := math.LegacyNewDecWithPrec(int64(simtypes.RandIntBetween(r, 1, 10000)), int64(1)) + exchangeRatesStr += price.String() + pair.String() + "," + } + + exchangeRatesStr = strings.TrimRight(exchangeRatesStr, ",") + voteHash := types.GetAggregateVoteHash(salt, exchangeRatesStr, address) + + feederAddrBytes, err := k.FeederDelegations.Get(ctx, address) + var feederAddr sdk.AccAddress + if err == nil { + feederAddr = sdk.AccAddress(feederAddrBytes) + } else { + feederAddr = sdk.AccAddress(address) + } + feederSimAccount, _ := simtypes.FindAccount(accs, feederAddr) + + feederAccount := ak.GetAccount(ctx, feederAddr) + spendable := bk.SpendableCoins(ctx, feederAccount.GetAddress()) + + fees, err := simtypes.RandomFees(r, ctx, spendable) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgAggregateExchangeRatePrevote, "unable to generate fees"), nil, err + } + + msg := types.NewMsgAggregateExchangeRatePrevote(voteHash, feederAddr, address) + + txGen := testutil.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenSignedMockTx( + r, + txGen, + []sdk.Msg{msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{feederAccount.GetAccountNumber()}, + []uint64{feederAccount.GetSequence()}, + feederSimAccount.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + voteHashMap[address.String()] = exchangeRatesStr + + return simtypes.NewOperationMsg(msg, true, ""), nil, nil + } +} + +// SimulateMsgAggregateExchangeRateVote generates a MsgAggregateExchangeRateVote with random values. +// nolint: funlen +func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + simAccount, _ := simtypes.RandomAcc(r, accs) + address := sdk.ValAddress(simAccount.Address) + + // ensure the validator exists + val, err := k.StakingKeeper.Validator(ctx, address) + if err != nil || !val.IsBonded() { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgAggregateExchangeRateVote, "unable to find validator"), nil, err + } + + // ensure vote hash exists + exchangeRatesStr, ok := voteHashMap[address.String()] + if !ok { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgAggregateExchangeRateVote, "vote hash not exists"), nil, nil + } + + // get prevote + prevote, err := k.Prevotes.Get(ctx, address) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgAggregateExchangeRateVote, "prevote not found"), nil, nil + } + + params, _ := k.Params.Get(ctx) + if (uint64(ctx.BlockHeight())/params.VotePeriod)-(prevote.SubmitBlock/params.VotePeriod) != 1 { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgAggregateExchangeRateVote, "reveal period of submitted vote do not match with registered prevote"), nil, nil + } + + feederAddrBytes, err := k.FeederDelegations.Get(ctx, address) + var feederAddr sdk.AccAddress + if err == nil { + feederAddr = sdk.AccAddress(feederAddrBytes) + } else { + feederAddr = sdk.AccAddress(address) + } + feederSimAccount, _ := simtypes.FindAccount(accs, feederAddr) + feederAccount := ak.GetAccount(ctx, feederAddr) + spendableCoins := bk.SpendableCoins(ctx, feederAddr) + + fees, err := simtypes.RandomFees(r, ctx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgAggregateExchangeRateVote, "unable to generate fees"), nil, err + } + + msg := types.NewMsgAggregateExchangeRateVote(salt, exchangeRatesStr, feederAddr, address) + + txGen := testutil.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenSignedMockTx( + r, + txGen, + []sdk.Msg{msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{feederAccount.GetAccountNumber()}, + []uint64{feederAccount.GetSequence()}, + feederSimAccount.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, ""), nil, nil + } +} + +// SimulateMsgDelegateFeedConsent generates a MsgDelegateFeedConsent with random values. +// nolint: funlen +func SimulateMsgDelegateFeedConsent(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + simAccount, _ := simtypes.RandomAcc(r, accs) + delegateAccount, _ := simtypes.RandomAcc(r, accs) + valAddress := sdk.ValAddress(simAccount.Address) + delegateValAddress := sdk.ValAddress(delegateAccount.Address) + account := ak.GetAccount(ctx, simAccount.Address) + + // ensure the validator exists + _, err := k.StakingKeeper.Validator(ctx, valAddress) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgDelegateFeedConsent, "unable to find validator"), nil, err + } + + // ensure the target address is not a validator + _, err = k.StakingKeeper.Validator(ctx, delegateValAddress) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgDelegateFeedConsent, "unable to delegate to validator"), nil, err + } + + spendableCoins := bk.SpendableCoins(ctx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, ctx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgAggregateExchangeRateVote, "unable to generate fees"), nil, err + } + + msg := types.NewMsgDelegateFeedConsent(valAddress, delegateAccount.Address) + + txGen := testutil.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenSignedMockTx( + r, + txGen, + []sdk.Msg{msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + simAccount.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, ""), nil, nil + } +} diff --git a/x/oracle/types/ballot.go b/x/oracle/types/ballot.go new file mode 100644 index 00000000..54fa5830 --- /dev/null +++ b/x/oracle/types/ballot.go @@ -0,0 +1,220 @@ +package types + +import ( + "encoding/json" + "sort" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + archmath "github.com/archway-network/archway/types/math" + "github.com/archway-network/archway/x/oracle/asset" +) + +// NOTE: we don't need to implement proto interface on this file +// these are not used in store or rpc response + +// ExchangeRateVote is a convenience wrapper to reduce redundant lookup cost +type ExchangeRateVote struct { + Pair asset.Pair + ExchangeRate math.LegacyDec // aka price + Voter sdk.ValAddress + Power int64 // how much tendermint consensus power this vote should have +} + +// NewExchangeRateVote returns a new ExchangeRateVote instance +func NewExchangeRateVote(rate math.LegacyDec, pair asset.Pair, voter sdk.ValAddress, power int64) ExchangeRateVote { + return ExchangeRateVote{ + ExchangeRate: rate, + Pair: pair, + Voter: voter, + Power: power, + } +} + +// ExchangeRateVotes is a convenience wrapper around a ExchangeRateVote slice +type ExchangeRateVotes []ExchangeRateVote + +// ToMap return organized exchange rate map by validator +func (pb ExchangeRateVotes) ToMap() map[string]math.LegacyDec { + validatorExchangeRateMap := make(map[string]math.LegacyDec) + for _, vote := range pb { + if vote.ExchangeRate.IsPositive() { + validatorExchangeRateMap[string(vote.Voter)] = vote.ExchangeRate + } + } + + return validatorExchangeRateMap +} + +// ToCrossRate return cross_rate(base/exchange_rate) votes +func (pb ExchangeRateVotes) ToCrossRate(bases map[string]math.LegacyDec) (cb ExchangeRateVotes) { + for i := range pb { + vote := pb[i] + + if exchangeRateRT, ok := bases[string(vote.Voter)]; ok && vote.ExchangeRate.IsPositive() { + vote.ExchangeRate = exchangeRateRT.Quo(vote.ExchangeRate) + } else { + // If we can't get reference exchange rate, we just convert the vote as abstain vote + vote.ExchangeRate = math.LegacyZeroDec() + vote.Power = 0 + } + + cb = append(cb, vote) + } + + return +} + +// NumValidVoters returns the number of voters who actually voted (i.e. did not abstain from voting for a pair). +func (v ExchangeRateVotes) NumValidVoters() uint64 { + count := 0 + for _, vote := range v { + if vote.ExchangeRate.IsPositive() { + count++ + } + } + return uint64(count) +} + +// Power returns the total amount of voting power in the votes +func (v ExchangeRateVotes) Power() int64 { + totalPower := int64(0) + for _, vote := range v { + totalPower += vote.Power + } + + return totalPower +} + +// WeightedMedian returns the median weighted by the power of the ExchangeRateVote. +// CONTRACT: votes must be sorted +func (votes ExchangeRateVotes) WeightedMedian() math.LegacyDec { + totalPower := votes.Power() + if votes.Len() > 0 { + pivot := int64(0) + for _, v := range votes { + votePower := v.Power + + pivot += votePower + if pivot >= (totalPower / 2) { + return v.ExchangeRate + } + } + } + return math.LegacyZeroDec() +} + +// WeightedMedianWithAssertion returns the median weighted by the power of the ExchangeRateVote. +func (pb ExchangeRateVotes) WeightedMedianWithAssertion() math.LegacyDec { + sort.Sort(pb) + totalPower := pb.Power() + if pb.Len() > 0 { + pivot := int64(0) + for _, v := range pb { + votePower := v.Power + + pivot += votePower + if pivot >= (totalPower / 2) { + return v.ExchangeRate + } + } + } + return math.LegacyZeroDec() +} + +// StandardDeviation returns the standard deviation by the power of the ExchangeRateVote. +func (pb ExchangeRateVotes) StandardDeviation(median math.LegacyDec) (standardDeviation math.LegacyDec) { + if len(pb) == 0 { + return math.LegacyZeroDec() + } + + defer func() { + if e := recover(); e != nil { + standardDeviation = math.LegacyZeroDec() + } + }() + + sum := math.LegacyZeroDec() + n := 0 + for _, v := range pb { + // ignore abstain votes in std dev calculation + if v.ExchangeRate.IsPositive() { + deviation := v.ExchangeRate.Sub(median) + sum = sum.Add(deviation.Mul(deviation)) + n += 1 + } + } + + variance := sum.QuoInt64(int64(n)) + + standardDeviation, err := archmath.SqrtDec(variance) + if err != nil { + return math.LegacyZeroDec() + } + + return +} + +// Len implements sort.Interface +func (pb ExchangeRateVotes) Len() int { + return len(pb) +} + +// Less reports whether the element with +// index i should sort before the element with index j. +func (pb ExchangeRateVotes) Less(i, j int) bool { + return pb[i].ExchangeRate.LT(pb[j].ExchangeRate) +} + +// Swap implements sort.Interface. +func (pb ExchangeRateVotes) Swap(i, j int) { + pb[i], pb[j] = pb[j], pb[i] +} + +// ValidatorPerformance keeps track of a validator performance in the voting period. +type ValidatorPerformance struct { + // Tendermint consensus voting power + Power int64 + // RewardWeight: Weight of rewards the validator should receive in units of + // consensus power. + RewardWeight int64 + WinCount int64 // Number of valid votes for which the validator will be rewarded + AbstainCount int64 // Number of abstained votes for which there will be no reward or punishment + MissCount int64 // Number of invalid/punishable votes + ValAddress sdk.ValAddress +} + +// NewValidatorPerformance generates a ValidatorPerformance instance. +func NewValidatorPerformance(power int64, recipient sdk.ValAddress) ValidatorPerformance { + return ValidatorPerformance{ + Power: power, + RewardWeight: 0, + WinCount: 0, + AbstainCount: 0, + MissCount: 0, + ValAddress: recipient, + } +} + +type ValidatorPerformances map[string]ValidatorPerformance + +// TotalRewardWeight returns the sum of the reward weight of all the validators included in the map +func (vp ValidatorPerformances) TotalRewardWeight() int64 { + totalRewardWeight := int64(0) + for _, validator := range vp { + totalRewardWeight += validator.RewardWeight + } + + return totalRewardWeight +} + +func (vp ValidatorPerformances) String() string { + jsonBz, _ := json.MarshalIndent(vp, "", " ") + return string(jsonBz) +} + +func (vp ValidatorPerformance) String() string { + jsonBz, _ := json.MarshalIndent(vp, "", " ") + return string(jsonBz) +} diff --git a/x/oracle/types/ballot_test.go b/x/oracle/types/ballot_test.go new file mode 100644 index 00000000..288ec8d4 --- /dev/null +++ b/x/oracle/types/ballot_test.go @@ -0,0 +1,366 @@ +package types_test + +import ( + "fmt" + basicmath "math" + "sort" + "strconv" + "testing" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" + + "github.com/stretchr/testify/require" + + "github.com/cometbft/cometbft/crypto/secp256k1" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/archway-network/archway/x/oracle/types" +) + +func TestExchangeRateVotesToMap(t *testing.T) { + tests := struct { + votes []types.ExchangeRateVote + isValid []bool + }{ + []types.ExchangeRateVote{ + { + Voter: sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()), + Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), + ExchangeRate: math.LegacyNewDec(1600), + Power: 100, + }, + { + Voter: sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()), + Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), + ExchangeRate: math.LegacyZeroDec(), + Power: 100, + }, + { + Voter: sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()), + Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), + ExchangeRate: math.LegacyNewDec(1500), + Power: 100, + }, + }, + []bool{true, false, true}, + } + + pb := types.ExchangeRateVotes(tests.votes) + mapData := pb.ToMap() + for i, vote := range tests.votes { + exchangeRate, ok := mapData[string(vote.Voter)] + if tests.isValid[i] { + require.True(t, ok) + require.Equal(t, exchangeRate, vote.ExchangeRate) + } else { + require.False(t, ok) + } + } + require.NotPanics(t, func() { + types.ExchangeRateVotes(tests.votes).NumValidVoters() + }) +} + +func TestToCrossRate(t *testing.T) { + data := []struct { + base math.LegacyDec + quote math.LegacyDec + expected math.LegacyDec + }{ + { + base: math.LegacyNewDec(1600), + quote: math.LegacyNewDec(100), + expected: math.LegacyNewDec(16), + }, + { + base: math.LegacyZeroDec(), + quote: math.LegacyNewDec(100), + expected: math.LegacyNewDec(16), + }, + { + base: math.LegacyNewDec(1600), + quote: math.LegacyZeroDec(), + expected: math.LegacyNewDec(16), + }, + } + + pbBase := types.ExchangeRateVotes{} + pbQuote := types.ExchangeRateVotes{} + cb := types.ExchangeRateVotes{} + for _, data := range data { + valAddr := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()) + if !data.base.IsZero() { + pbBase = append(pbBase, types.NewExchangeRateVote(data.base, asset.Registry.Pair(denoms.BTC, denoms.NUSD), valAddr, 100)) + } + + pbQuote = append(pbQuote, types.NewExchangeRateVote(data.quote, asset.Registry.Pair(denoms.BTC, denoms.NUSD), valAddr, 100)) + + if !data.base.IsZero() && !data.quote.IsZero() { + cb = append(cb, types.NewExchangeRateVote(data.base.Quo(data.quote), asset.Registry.Pair(denoms.BTC, denoms.NUSD), valAddr, 100)) + } else { + cb = append(cb, types.NewExchangeRateVote(math.LegacyZeroDec(), asset.Registry.Pair(denoms.BTC, denoms.NUSD), valAddr, 0)) + } + } + + basePairPrices := pbBase.ToMap() + require.Equal(t, cb, pbQuote.ToCrossRate(basePairPrices)) + + sort.Sort(cb) +} + +func TestSqrt(t *testing.T) { + num := math.LegacyNewDecWithPrec(144, 4) + floatNum, err := strconv.ParseFloat(num.String(), 64) + require.NoError(t, err) + + floatNum = basicmath.Sqrt(floatNum) + num, err = math.LegacyNewDecFromStr(fmt.Sprintf("%f", floatNum)) + require.NoError(t, err) + + require.Equal(t, math.LegacyNewDecWithPrec(12, 2), num) +} + +func TestPBPower(t *testing.T) { + ctx := sdk.NewContext(nil, tmproto.Header{}, false, nil) + _, valAccAddrs, sk := types.GenerateRandomTestCase() + pb := types.ExchangeRateVotes{} + totalPower := int64(0) + + for i := 0; i < len(sk.Validators()); i++ { + val, err := sk.Validator(ctx, valAccAddrs[i]) + require.NoError(t, err) + power := val.GetConsensusPower(sdk.DefaultPowerReduction) + vote := types.NewExchangeRateVote( + math.LegacyZeroDec(), + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + valAccAddrs[i], + power, + ) + + pb = append(pb, vote) + + require.NotEqual(t, int64(0), vote.Power) + + totalPower += vote.Power + } + + require.Equal(t, totalPower, pb.Power()) + + // Mix in a fake validator, the total power should not have changed. + pubKey := secp256k1.GenPrivKey().PubKey() + faceValAddr := sdk.ValAddress(pubKey.Address()) + fakeVote := types.NewExchangeRateVote( + math.LegacyOneDec(), + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + faceValAddr, + 0, + ) + + pb = append(pb, fakeVote) + require.Equal(t, totalPower, pb.Power()) +} + +func TestPBWeightedMedian(t *testing.T) { + tests := []struct { + inputs []int64 + weights []int64 + isValidator []bool + median math.LegacyDec + }{ + { + // Supermajority one number + []int64{1, 2, 10, 100000}, + []int64{1, 1, 100, 1}, + []bool{true, true, true, true}, + math.LegacyNewDec(10), + }, + { + // Adding fake validator doesn't change outcome + []int64{1, 2, 10, 100000, 10000000000}, + []int64{1, 1, 100, 1, 10000}, + []bool{true, true, true, true, false}, + math.LegacyNewDec(10), + }, + { + // Tie votes + []int64{1, 2, 3, 4}, + []int64{1, 100, 100, 1}, + []bool{true, true, true, true}, + math.LegacyNewDec(2), + }, + { + // No votes + []int64{}, + []int64{}, + []bool{true, true, true, true}, + math.LegacyZeroDec(), + }, + { + // not sorted + []int64{2, 1, 10, 100000}, + []int64{1, 1, 100, 1}, + []bool{true, true, true, true}, + math.LegacyNewDec(10), + }, + } + + for _, tc := range tests { + pb := types.ExchangeRateVotes{} + for i, input := range tc.inputs { + valAddr := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()) + + power := tc.weights[i] + if !tc.isValidator[i] { + power = 0 + } + + vote := types.NewExchangeRateVote( + math.LegacyNewDec(int64(input)), + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + valAddr, + power, + ) + + pb = append(pb, vote) + } + + require.Equal(t, tc.median, pb.WeightedMedian()) + require.Equal(t, tc.median, pb.WeightedMedianWithAssertion()) + } +} + +func TestPBStandardDeviation(t *testing.T) { + tests := []struct { + inputs []float64 + weights []int64 + isValidator []bool + standardDeviation math.LegacyDec + }{ + { + // Supermajority one number + []float64{1.0, 2.0, 10.0, 100000.0}, + []int64{1, 1, 100, 1}, + []bool{true, true, true, true}, + math.LegacyMustNewDecFromStr("49995.000362536000000000"), + }, + { + // Adding fake validator doesn't change outcome + []float64{1.0, 2.0, 10.0, 100000.0, 10000000000}, + []int64{1, 1, 100, 1, 10000}, + []bool{true, true, true, true, false}, + math.LegacyMustNewDecFromStr("4472135950.751005519000000000"), + }, + { + // Tie votes + []float64{1.0, 2.0, 3.0, 4.0}, + []int64{1, 100, 100, 1}, + []bool{true, true, true, true}, + math.LegacyMustNewDecFromStr("1.224744871000000000"), + }, + { + // No votes + []float64{}, + []int64{}, + []bool{true, true, true, true}, + math.LegacyNewDecWithPrec(0, 0), + }, + { + // Abstain votes are ignored + []float64{1.0, 2.0, 10.0, 100000.0, -99999999999.0, 0}, + []int64{1, 1, 100, 1, 1, 1}, + []bool{true, true, true, true, true, true}, + math.LegacyMustNewDecFromStr("49995.000362536000000000"), + }, + } + + base := basicmath.Pow10(types.OracleDecPrecision) + for _, tc := range tests { + pb := types.ExchangeRateVotes{} + for i, input := range tc.inputs { + valAddr := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()) + + power := tc.weights[i] + if !tc.isValidator[i] { + power = 0 + } + + vote := types.NewExchangeRateVote( + math.LegacyNewDecWithPrec(int64(input*base), int64(types.OracleDecPrecision)), + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + valAddr, + power, + ) + + pb = append(pb, vote) + } + + require.Equal(t, tc.standardDeviation, pb.StandardDeviation(pb.WeightedMedianWithAssertion())) + } +} + +func TestPBStandardDeviationOverflow(t *testing.T) { + valAddr := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address()) + exchangeRate, err := math.LegacyNewDecFromStr("100000000000000000000000000000000000000000000000000000000.0") + require.NoError(t, err) + + pb := types.ExchangeRateVotes{types.NewExchangeRateVote( + math.LegacyZeroDec(), + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + valAddr, + 2, + ), types.NewExchangeRateVote( + exchangeRate, + asset.Registry.Pair(denoms.ETH, denoms.NUSD), + valAddr, + 1, + )} + + require.Equal(t, math.LegacyZeroDec(), pb.StandardDeviation(pb.WeightedMedianWithAssertion())) +} + +func TestNewClaim(t *testing.T) { + power := int64(10) + weight := int64(11) + winCount := int64(1) + addr := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address().Bytes()) + claim := types.ValidatorPerformance{ + Power: power, + RewardWeight: weight, + WinCount: winCount, + ValAddress: addr, + } + require.Equal(t, types.ValidatorPerformance{ + Power: power, + RewardWeight: weight, + WinCount: winCount, + ValAddress: addr, + }, claim) +} + +func TestValidatorPerformances(t *testing.T) { + power := int64(42) + valNames := []string{"val0", "val1", "val2", "val3"} + perfList := []types.ValidatorPerformance{ + types.NewValidatorPerformance(power, sdk.ValAddress([]byte(valNames[0]))), + types.NewValidatorPerformance(power, sdk.ValAddress([]byte(valNames[1]))), + types.NewValidatorPerformance(power, sdk.ValAddress([]byte(valNames[2]))), + types.NewValidatorPerformance(power, sdk.ValAddress([]byte(valNames[3]))), + } + perfs := make(types.ValidatorPerformances) + for idx, perf := range perfList { + perfs[valNames[idx]] = perf + } + + require.NotPanics(t, func() { + out := perfs.String() + require.NotEmpty(t, out) + + out = perfs[valNames[0]].String() + require.NotEmpty(t, out) + }) +} diff --git a/x/oracle/types/codec.go b/x/oracle/types/codec.go new file mode 100644 index 00000000..898a07b6 --- /dev/null +++ b/x/oracle/types/codec.go @@ -0,0 +1,46 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +// RegisterLegacyAminoCodec registers the necessary x/oracle interfaces and concrete types +// on the provided LegacyAmino codec. These types are used for Amino JSON serialization. +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgAggregateExchangeRatePrevote{}, "oracle/MsgAggregateExchangeRatePrevote", nil) + cdc.RegisterConcrete(&MsgAggregateExchangeRateVote{}, "oracle/MsgAggregateExchangeRateVote", nil) + cdc.RegisterConcrete(&MsgDelegateFeedConsent{}, "oracle/MsgDelegateFeedConsent", nil) +} + +// RegisterInterfaces registers the x/oracle interfaces types with the interface registry +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgDelegateFeedConsent{}, + &MsgAggregateExchangeRatePrevote{}, + &MsgAggregateExchangeRateVote{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + amino = codec.NewLegacyAmino() + + // ModuleCdc references the global x/oracle module codec. Note, the codec should + // ONLY be used in certain instances of tests and for JSON encoding as Amino is + // still used for that purpose. + // + // The actual codec used for serialization should be provided to x/staking and + // defined at the application level. + ModuleCdc = amino +) + +func init() { + RegisterLegacyAminoCodec(amino) + cryptocodec.RegisterCrypto(amino) + amino.Seal() +} diff --git a/x/oracle/types/core.go b/x/oracle/types/core.go new file mode 100644 index 00000000..cd013664 --- /dev/null +++ b/x/oracle/types/core.go @@ -0,0 +1,8 @@ +package types + +import sdk "github.com/cosmos/cosmos-sdk/types" + +// IsPeriodLastBlock returns true if we are at the last block of the period +func IsPeriodLastBlock(ctx sdk.Context, blocksPerPeriod uint64) bool { + return ((uint64)(ctx.BlockHeight()))%blocksPerPeriod == 0 +} diff --git a/x/oracle/types/errors.go b/x/oracle/types/errors.go new file mode 100644 index 00000000..95332e11 --- /dev/null +++ b/x/oracle/types/errors.go @@ -0,0 +1,38 @@ +package types + +import ( + "fmt" + "sync/atomic" + + "github.com/cometbft/cometbft/crypto/tmhash" + + sdkerrors "cosmossdk.io/errors" +) + +var moduleErrorCodeIdx uint32 = 1 + +// registerError: Cleaner way of using 'sdkerrors.Register' without as much time +// manually writing integers. +func registerError(msg string) *sdkerrors.Error { + // Atomic for thread safety on concurrent calls + atomic.AddUint32(&moduleErrorCodeIdx, 1) + return sdkerrors.Register(ModuleName, moduleErrorCodeIdx, msg) +} + +// Oracle Errors +var ( + ErrInvalidExchangeRate = registerError("invalid exchange rate") + ErrNoPrevote = registerError("no prevote") + ErrNoVote = registerError("no vote") + ErrNoVotingPermission = registerError("unauthorized voter") + ErrInvalidHash = registerError("invalid hash") + ErrInvalidHashLength = registerError( + fmt.Sprintf("invalid hash length; should equal %d", tmhash.TruncatedSize)) + ErrHashVerificationFailed = registerError("hash verification failed") + ErrRevealPeriodMissMatch = registerError("reveal period of submitted vote do not match with registered prevote") + ErrInvalidSaltLength = registerError("invalid salt length; should be 1~4") + ErrNoAggregatePrevote = registerError("no aggregate prevote") + ErrNoAggregateVote = registerError("no aggregate vote") + ErrUnknownPair = registerError("unknown pair") + ErrNoValidTWAP = registerError("TWA price not found") +) diff --git a/x/oracle/types/event.pb.go b/x/oracle/types/event.pb.go new file mode 100644 index 00000000..1dbfe914 --- /dev/null +++ b/x/oracle/types/event.pb.go @@ -0,0 +1,1513 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: archway/oracle/v1/event.proto + +package types + +import ( + cosmossdk_io_math "cosmossdk.io/math" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Emitted when a price is posted +type EventPriceUpdate struct { + Pair string `protobuf:"bytes,1,opt,name=pair,proto3" json:"pair,omitempty"` + Price cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=price,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"price"` + TimestampMs int64 `protobuf:"varint,3,opt,name=timestamp_ms,json=timestampMs,proto3" json:"timestamp_ms,omitempty"` +} + +func (m *EventPriceUpdate) Reset() { *m = EventPriceUpdate{} } +func (m *EventPriceUpdate) String() string { return proto.CompactTextString(m) } +func (*EventPriceUpdate) ProtoMessage() {} +func (*EventPriceUpdate) Descriptor() ([]byte, []int) { + return fileDescriptor_ab464c0117763229, []int{0} +} +func (m *EventPriceUpdate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventPriceUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventPriceUpdate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventPriceUpdate) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventPriceUpdate.Merge(m, src) +} +func (m *EventPriceUpdate) XXX_Size() int { + return m.Size() +} +func (m *EventPriceUpdate) XXX_DiscardUnknown() { + xxx_messageInfo_EventPriceUpdate.DiscardUnknown(m) +} + +var xxx_messageInfo_EventPriceUpdate proto.InternalMessageInfo + +func (m *EventPriceUpdate) GetPair() string { + if m != nil { + return m.Pair + } + return "" +} + +func (m *EventPriceUpdate) GetTimestampMs() int64 { + if m != nil { + return m.TimestampMs + } + return 0 +} + +// Emitted when a valoper delegates oracle voting rights to a feeder address. +type EventDelegateFeederConsent struct { + // Validator is the Bech32 address that is delegating voting rights. + Validator string `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator,omitempty"` + // Feeder is the delegate or representative that will be able to send + // vote and prevote transaction messages. + Feeder string `protobuf:"bytes,2,opt,name=feeder,proto3" json:"feeder,omitempty"` +} + +func (m *EventDelegateFeederConsent) Reset() { *m = EventDelegateFeederConsent{} } +func (m *EventDelegateFeederConsent) String() string { return proto.CompactTextString(m) } +func (*EventDelegateFeederConsent) ProtoMessage() {} +func (*EventDelegateFeederConsent) Descriptor() ([]byte, []int) { + return fileDescriptor_ab464c0117763229, []int{1} +} +func (m *EventDelegateFeederConsent) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventDelegateFeederConsent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventDelegateFeederConsent.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventDelegateFeederConsent) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventDelegateFeederConsent.Merge(m, src) +} +func (m *EventDelegateFeederConsent) XXX_Size() int { + return m.Size() +} +func (m *EventDelegateFeederConsent) XXX_DiscardUnknown() { + xxx_messageInfo_EventDelegateFeederConsent.DiscardUnknown(m) +} + +var xxx_messageInfo_EventDelegateFeederConsent proto.InternalMessageInfo + +func (m *EventDelegateFeederConsent) GetValidator() string { + if m != nil { + return m.Validator + } + return "" +} + +func (m *EventDelegateFeederConsent) GetFeeder() string { + if m != nil { + return m.Feeder + } + return "" +} + +// Emitted by MsgAggregateExchangeVote when an aggregate vote is added to state +type EventAggregateVote struct { + // Validator is the Bech32 address to which the vote will be credited. + Validator string `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator,omitempty"` + // Feeder is the delegate or representative that will send vote and prevote + // transaction messages on behalf of the voting validator. + Feeder string `protobuf:"bytes,2,opt,name=feeder,proto3" json:"feeder,omitempty"` + Prices ExchangeRateTuples `protobuf:"bytes,3,rep,name=prices,proto3,castrepeated=ExchangeRateTuples" json:"prices"` +} + +func (m *EventAggregateVote) Reset() { *m = EventAggregateVote{} } +func (m *EventAggregateVote) String() string { return proto.CompactTextString(m) } +func (*EventAggregateVote) ProtoMessage() {} +func (*EventAggregateVote) Descriptor() ([]byte, []int) { + return fileDescriptor_ab464c0117763229, []int{2} +} +func (m *EventAggregateVote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventAggregateVote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventAggregateVote.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventAggregateVote) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventAggregateVote.Merge(m, src) +} +func (m *EventAggregateVote) XXX_Size() int { + return m.Size() +} +func (m *EventAggregateVote) XXX_DiscardUnknown() { + xxx_messageInfo_EventAggregateVote.DiscardUnknown(m) +} + +var xxx_messageInfo_EventAggregateVote proto.InternalMessageInfo + +func (m *EventAggregateVote) GetValidator() string { + if m != nil { + return m.Validator + } + return "" +} + +func (m *EventAggregateVote) GetFeeder() string { + if m != nil { + return m.Feeder + } + return "" +} + +func (m *EventAggregateVote) GetPrices() ExchangeRateTuples { + if m != nil { + return m.Prices + } + return nil +} + +// Emitted by MsgAggregateExchangePrevote when an aggregate prevote is added +// to state +type EventAggregatePrevote struct { + // Validator is the Bech32 address to which the vote will be credited. + Validator string `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator,omitempty"` + // Feeder is the delegate or representative that will send vote and prevote + // transaction messages on behalf of the voting validator. + Feeder string `protobuf:"bytes,2,opt,name=feeder,proto3" json:"feeder,omitempty"` +} + +func (m *EventAggregatePrevote) Reset() { *m = EventAggregatePrevote{} } +func (m *EventAggregatePrevote) String() string { return proto.CompactTextString(m) } +func (*EventAggregatePrevote) ProtoMessage() {} +func (*EventAggregatePrevote) Descriptor() ([]byte, []int) { + return fileDescriptor_ab464c0117763229, []int{3} +} +func (m *EventAggregatePrevote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventAggregatePrevote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventAggregatePrevote.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventAggregatePrevote) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventAggregatePrevote.Merge(m, src) +} +func (m *EventAggregatePrevote) XXX_Size() int { + return m.Size() +} +func (m *EventAggregatePrevote) XXX_DiscardUnknown() { + xxx_messageInfo_EventAggregatePrevote.DiscardUnknown(m) +} + +var xxx_messageInfo_EventAggregatePrevote proto.InternalMessageInfo + +func (m *EventAggregatePrevote) GetValidator() string { + if m != nil { + return m.Validator + } + return "" +} + +func (m *EventAggregatePrevote) GetFeeder() string { + if m != nil { + return m.Feeder + } + return "" +} + +type EventValidatorPerformance struct { + // Validator is the Bech32 address to which the vote will be credited. + Validator string `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator,omitempty"` + // Tendermint consensus voting power + VotingPower int64 `protobuf:"varint,2,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + // RewardWeight: Weight of rewards the validator should receive in units of + // consensus power. + RewardWeight int64 `protobuf:"varint,3,opt,name=reward_weight,json=rewardWeight,proto3" json:"reward_weight,omitempty"` + // Number of valid votes for which the validator will be rewarded + WinCount int64 `protobuf:"varint,4,opt,name=win_count,json=winCount,proto3" json:"win_count,omitempty"` + // Number of abstained votes for which there will be no reward or punishment + AbstainCount int64 `protobuf:"varint,5,opt,name=abstain_count,json=abstainCount,proto3" json:"abstain_count,omitempty"` + // Number of invalid/punishable votes + MissCount int64 `protobuf:"varint,6,opt,name=miss_count,json=missCount,proto3" json:"miss_count,omitempty"` +} + +func (m *EventValidatorPerformance) Reset() { *m = EventValidatorPerformance{} } +func (m *EventValidatorPerformance) String() string { return proto.CompactTextString(m) } +func (*EventValidatorPerformance) ProtoMessage() {} +func (*EventValidatorPerformance) Descriptor() ([]byte, []int) { + return fileDescriptor_ab464c0117763229, []int{4} +} +func (m *EventValidatorPerformance) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventValidatorPerformance) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventValidatorPerformance.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventValidatorPerformance) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventValidatorPerformance.Merge(m, src) +} +func (m *EventValidatorPerformance) XXX_Size() int { + return m.Size() +} +func (m *EventValidatorPerformance) XXX_DiscardUnknown() { + xxx_messageInfo_EventValidatorPerformance.DiscardUnknown(m) +} + +var xxx_messageInfo_EventValidatorPerformance proto.InternalMessageInfo + +func (m *EventValidatorPerformance) GetValidator() string { + if m != nil { + return m.Validator + } + return "" +} + +func (m *EventValidatorPerformance) GetVotingPower() int64 { + if m != nil { + return m.VotingPower + } + return 0 +} + +func (m *EventValidatorPerformance) GetRewardWeight() int64 { + if m != nil { + return m.RewardWeight + } + return 0 +} + +func (m *EventValidatorPerformance) GetWinCount() int64 { + if m != nil { + return m.WinCount + } + return 0 +} + +func (m *EventValidatorPerformance) GetAbstainCount() int64 { + if m != nil { + return m.AbstainCount + } + return 0 +} + +func (m *EventValidatorPerformance) GetMissCount() int64 { + if m != nil { + return m.MissCount + } + return 0 +} + +func init() { + proto.RegisterType((*EventPriceUpdate)(nil), "archway.oracle.v1.EventPriceUpdate") + proto.RegisterType((*EventDelegateFeederConsent)(nil), "archway.oracle.v1.EventDelegateFeederConsent") + proto.RegisterType((*EventAggregateVote)(nil), "archway.oracle.v1.EventAggregateVote") + proto.RegisterType((*EventAggregatePrevote)(nil), "archway.oracle.v1.EventAggregatePrevote") + proto.RegisterType((*EventValidatorPerformance)(nil), "archway.oracle.v1.EventValidatorPerformance") +} + +func init() { proto.RegisterFile("archway/oracle/v1/event.proto", fileDescriptor_ab464c0117763229) } + +var fileDescriptor_ab464c0117763229 = []byte{ + // 515 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x41, 0x6f, 0xd3, 0x4c, + 0x10, 0x8d, 0xbf, 0xb4, 0xd1, 0x97, 0x4d, 0x90, 0x60, 0x05, 0x28, 0xa4, 0xad, 0xd3, 0xa6, 0x1c, + 0x72, 0xc1, 0x56, 0xe0, 0xc4, 0x91, 0xb4, 0xe5, 0x02, 0x95, 0x22, 0x0b, 0x0a, 0xe2, 0x12, 0x6d, + 0x9c, 0xe9, 0x66, 0xd5, 0x78, 0xc7, 0xda, 0xdd, 0xd8, 0xcd, 0x9d, 0x1f, 0xc0, 0x8f, 0xe0, 0xc4, + 0x2f, 0xe9, 0xb1, 0x47, 0xc4, 0xa1, 0xa0, 0xe4, 0x8f, 0x20, 0xaf, 0x37, 0x45, 0x28, 0x07, 0xa4, + 0xde, 0x66, 0xde, 0x7b, 0xf3, 0xfc, 0xbc, 0xa3, 0x21, 0x7b, 0x4c, 0xc5, 0xd3, 0x9c, 0x2d, 0x42, + 0x54, 0x2c, 0x9e, 0x41, 0x98, 0xf5, 0x43, 0xc8, 0x40, 0x9a, 0x20, 0x55, 0x68, 0x90, 0x3e, 0x70, + 0x74, 0x50, 0xd2, 0x41, 0xd6, 0x6f, 0xfb, 0x9b, 0x13, 0x8e, 0xb4, 0x23, 0xed, 0x87, 0x1c, 0x39, + 0xda, 0x32, 0x2c, 0x2a, 0x87, 0xee, 0x72, 0x44, 0x3e, 0x83, 0x90, 0xa5, 0x22, 0x64, 0x52, 0xa2, + 0x61, 0x46, 0xa0, 0xd4, 0x25, 0xdb, 0xfd, 0xec, 0x91, 0xfb, 0x27, 0xc5, 0x67, 0x87, 0x4a, 0xc4, + 0xf0, 0x3e, 0x9d, 0x30, 0x03, 0x94, 0x92, 0xad, 0x94, 0x09, 0xd5, 0xf2, 0xf6, 0xbd, 0x5e, 0x3d, + 0xb2, 0x35, 0x7d, 0x49, 0xb6, 0xd3, 0x42, 0xd2, 0xfa, 0xaf, 0x00, 0x07, 0x87, 0x57, 0x37, 0x9d, + 0xca, 0x8f, 0x9b, 0xce, 0x4e, 0x8c, 0x3a, 0x41, 0xad, 0x27, 0x17, 0x81, 0xc0, 0x30, 0x61, 0x66, + 0x1a, 0xbc, 0x05, 0xce, 0xe2, 0xc5, 0x31, 0xc4, 0x51, 0x39, 0x41, 0x0f, 0x48, 0xd3, 0x88, 0x04, + 0xb4, 0x61, 0x49, 0x3a, 0x4a, 0x74, 0xab, 0xba, 0xef, 0xf5, 0xaa, 0x51, 0xe3, 0x16, 0x3b, 0xd5, + 0xdd, 0x88, 0xb4, 0x6d, 0x8a, 0x63, 0x98, 0x01, 0x67, 0x06, 0x5e, 0x03, 0x4c, 0x40, 0x1d, 0xa1, + 0xd4, 0x20, 0x0d, 0xdd, 0x25, 0xf5, 0x8c, 0xcd, 0xc4, 0x84, 0x19, 0x5c, 0x87, 0xfa, 0x03, 0xd0, + 0xc7, 0xa4, 0x76, 0x6e, 0xe5, 0x65, 0xb4, 0xc8, 0x75, 0xdd, 0xaf, 0x1e, 0xa1, 0xd6, 0xf4, 0x15, + 0xe7, 0xca, 0xba, 0x9e, 0xa1, 0x81, 0xbb, 0x99, 0xd1, 0x8f, 0xa4, 0x66, 0x7f, 0xa6, 0x48, 0x5f, + 0xed, 0x35, 0x9e, 0x3f, 0x0d, 0x36, 0xf6, 0x13, 0x9c, 0x5c, 0xc6, 0x53, 0x26, 0x39, 0x44, 0xcc, + 0xc0, 0xbb, 0x79, 0x3a, 0x83, 0x41, 0xbb, 0x78, 0xa5, 0x6f, 0x3f, 0x3b, 0x74, 0x83, 0xd2, 0x91, + 0xf3, 0xeb, 0x9e, 0x92, 0x47, 0x7f, 0xa7, 0x1c, 0x2a, 0xc8, 0xee, 0x1c, 0xb4, 0xbb, 0xf4, 0xc8, + 0x13, 0xeb, 0x77, 0xb6, 0x96, 0x0e, 0x41, 0x9d, 0xa3, 0x4a, 0x98, 0x8c, 0xff, 0xe5, 0x79, 0x40, + 0x9a, 0x19, 0x1a, 0x21, 0xf9, 0x28, 0xc5, 0xdc, 0x39, 0x57, 0xa3, 0x46, 0x89, 0x0d, 0x0b, 0x88, + 0x1e, 0x92, 0x7b, 0x0a, 0x72, 0xa6, 0x26, 0xa3, 0x1c, 0x04, 0x9f, 0x1a, 0xb7, 0xcc, 0x66, 0x09, + 0x7e, 0xb0, 0x18, 0xdd, 0x21, 0xf5, 0x5c, 0xc8, 0x51, 0x8c, 0x73, 0x69, 0x5a, 0x5b, 0x56, 0xf0, + 0x7f, 0x2e, 0xe4, 0x51, 0xd1, 0x17, 0x0e, 0x6c, 0xac, 0x0d, 0xbb, 0x15, 0x6c, 0x97, 0x0e, 0x0e, + 0x2c, 0x45, 0x7b, 0x84, 0x24, 0x42, 0x6b, 0xa7, 0xa8, 0x59, 0x45, 0xbd, 0x40, 0x2c, 0x3d, 0x78, + 0x73, 0xb5, 0xf4, 0xbd, 0xeb, 0xa5, 0xef, 0xfd, 0x5a, 0xfa, 0xde, 0x97, 0x95, 0x5f, 0xb9, 0x5e, + 0xf9, 0x95, 0xef, 0x2b, 0xbf, 0xf2, 0xa9, 0xcf, 0x85, 0x99, 0xce, 0xc7, 0x41, 0x8c, 0x49, 0xe8, + 0x36, 0xf4, 0x4c, 0x82, 0xc9, 0x51, 0x5d, 0xac, 0xfb, 0xf0, 0x72, 0x7d, 0x40, 0x66, 0x91, 0x82, + 0x1e, 0xd7, 0xec, 0x25, 0xbc, 0xf8, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xf2, 0xff, 0xe5, 0x7e, 0x91, + 0x03, 0x00, 0x00, +} + +func (m *EventPriceUpdate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventPriceUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventPriceUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.TimestampMs != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.TimestampMs)) + i-- + dAtA[i] = 0x18 + } + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintEvent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Pair) > 0 { + i -= len(m.Pair) + copy(dAtA[i:], m.Pair) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Pair))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventDelegateFeederConsent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventDelegateFeederConsent) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventDelegateFeederConsent) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Feeder) > 0 { + i -= len(m.Feeder) + copy(dAtA[i:], m.Feeder) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Feeder))) + i-- + dAtA[i] = 0x12 + } + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventAggregateVote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventAggregateVote) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventAggregateVote) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Prices) > 0 { + for iNdEx := len(m.Prices) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Prices[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Feeder) > 0 { + i -= len(m.Feeder) + copy(dAtA[i:], m.Feeder) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Feeder))) + i-- + dAtA[i] = 0x12 + } + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventAggregatePrevote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventAggregatePrevote) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventAggregatePrevote) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Feeder) > 0 { + i -= len(m.Feeder) + copy(dAtA[i:], m.Feeder) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Feeder))) + i-- + dAtA[i] = 0x12 + } + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventValidatorPerformance) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventValidatorPerformance) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventValidatorPerformance) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MissCount != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.MissCount)) + i-- + dAtA[i] = 0x30 + } + if m.AbstainCount != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.AbstainCount)) + i-- + dAtA[i] = 0x28 + } + if m.WinCount != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.WinCount)) + i-- + dAtA[i] = 0x20 + } + if m.RewardWeight != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.RewardWeight)) + i-- + dAtA[i] = 0x18 + } + if m.VotingPower != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.VotingPower)) + i-- + dAtA[i] = 0x10 + } + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintEvent(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintEvent(dAtA []byte, offset int, v uint64) int { + offset -= sovEvent(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *EventPriceUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Pair) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + l = m.Price.Size() + n += 1 + l + sovEvent(uint64(l)) + if m.TimestampMs != 0 { + n += 1 + sovEvent(uint64(m.TimestampMs)) + } + return n +} + +func (m *EventDelegateFeederConsent) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + l = len(m.Feeder) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + return n +} + +func (m *EventAggregateVote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + l = len(m.Feeder) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + if len(m.Prices) > 0 { + for _, e := range m.Prices { + l = e.Size() + n += 1 + l + sovEvent(uint64(l)) + } + } + return n +} + +func (m *EventAggregatePrevote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + l = len(m.Feeder) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + return n +} + +func (m *EventValidatorPerformance) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + if m.VotingPower != 0 { + n += 1 + sovEvent(uint64(m.VotingPower)) + } + if m.RewardWeight != 0 { + n += 1 + sovEvent(uint64(m.RewardWeight)) + } + if m.WinCount != 0 { + n += 1 + sovEvent(uint64(m.WinCount)) + } + if m.AbstainCount != 0 { + n += 1 + sovEvent(uint64(m.AbstainCount)) + } + if m.MissCount != 0 { + n += 1 + sovEvent(uint64(m.MissCount)) + } + return n +} + +func sovEvent(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozEvent(x uint64) (n int) { + return sovEvent(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *EventPriceUpdate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventPriceUpdate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventPriceUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pair", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Pair = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimestampMs", wireType) + } + m.TimestampMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimestampMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventDelegateFeederConsent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventDelegateFeederConsent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventDelegateFeederConsent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Feeder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Feeder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventAggregateVote) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventAggregateVote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventAggregateVote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Feeder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Feeder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prices", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Prices = append(m.Prices, ExchangeRateTuple{}) + if err := m.Prices[len(m.Prices)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventAggregatePrevote) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventAggregatePrevote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventAggregatePrevote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Feeder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Feeder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventValidatorPerformance) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventValidatorPerformance: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventValidatorPerformance: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) + } + m.VotingPower = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VotingPower |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RewardWeight", wireType) + } + m.RewardWeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RewardWeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WinCount", wireType) + } + m.WinCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.WinCount |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AbstainCount", wireType) + } + m.AbstainCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AbstainCount |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MissCount", wireType) + } + m.MissCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MissCount |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipEvent(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvent + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvent + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvent + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthEvent + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupEvent + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthEvent + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthEvent = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowEvent = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupEvent = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/oracle/types/expected_keeper.go b/x/oracle/types/expected_keeper.go new file mode 100644 index 00000000..fa2a5de4 --- /dev/null +++ b/x/oracle/types/expected_keeper.go @@ -0,0 +1,51 @@ +package types + +import ( + context "context" + + corestore "cosmossdk.io/core/store" + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// StakingKeeper is expected keeper for staking module +type StakingKeeper interface { + Validator(ctx context.Context, address sdk.ValAddress) (stakingtypes.ValidatorI, error) // get validator by operator address; nil when validator not found + TotalBondedTokens(context.Context) (sdkmath.Int, error) // total bonded tokens within the validator set + Slash(context.Context, sdk.ConsAddress, int64, int64, sdkmath.LegacyDec) (sdkmath.Int, error) // slash the validator and delegators of the validator, specifying offense height, offense power, and slash fraction + Jail(context.Context, sdk.ConsAddress) error // jail a validator + ValidatorsPowerStoreIterator(ctx context.Context) (corestore.Iterator, error) + MaxValidators(context.Context) (uint32, error) // MaxValidators returns the maximum amount of bonded validators + PowerReduction(ctx context.Context) (res sdkmath.Int) +} + +type SlashingKeeper interface { + Slash(ctx context.Context, consAddr sdk.ConsAddress, fraction sdkmath.LegacyDec, power int64, height int64) error + Jail(context.Context, sdk.ConsAddress) error +} + +// DistributionKeeper is expected keeper for distribution module +type DistributionKeeper interface { + AllocateTokensToValidator(ctx context.Context, val stakingtypes.ValidatorI, tokens sdk.DecCoins) error + + // only used for simulation + GetValidatorOutstandingRewardsCoins(ctx context.Context, val sdk.ValAddress) (sdk.DecCoins, error) +} + +// AccountKeeper is expected keeper for auth module +type AccountKeeper interface { + GetModuleAddress(name string) sdk.AccAddress + GetModuleAccount(ctx context.Context, moduleName string) sdk.ModuleAccountI + GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI // only used for simulation +} + +// BankKeeper defines the expected interface needed to retrieve account balances. +type BankKeeper interface { + GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin + GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins + SendCoinsFromModuleToModule(ctx context.Context, senderModule string, recipientModule string, amt sdk.Coins) error + // only used for simulation + SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins +} diff --git a/x/oracle/types/export.go b/x/oracle/types/export.go new file mode 100644 index 00000000..fb4b6e3b --- /dev/null +++ b/x/oracle/types/export.go @@ -0,0 +1,12 @@ +package types + +import ( + grpc "google.golang.org/grpc" +) + +// GrpcQueryServiceDesc represents the query server's RPC service specification. +// This gives access to the service name and method names needed for stargate +// queries. +func GrpcQueryServiceDesc() grpc.ServiceDesc { + return _Query_serviceDesc +} diff --git a/x/oracle/types/genesis.go b/x/oracle/types/genesis.go new file mode 100644 index 00000000..e5dbedcb --- /dev/null +++ b/x/oracle/types/genesis.go @@ -0,0 +1,60 @@ +package types + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/codec" + + "github.com/archway-network/archway/x/oracle/asset" +) + +// NewGenesisState creates a new GenesisState object +func NewGenesisState( + params Params, rates []ExchangeRateTuple, + feederDelegations []FeederDelegation, missCounters []MissCounter, + aggregateExchangeRatePrevotes []AggregateExchangeRatePrevote, + aggregateExchangeRateVotes []AggregateExchangeRateVote, + pairs []asset.Pair, + rewards []Rewards, +) *GenesisState { + return &GenesisState{ + Params: params, + FeederDelegations: feederDelegations, + ExchangeRates: rates, + MissCounters: missCounters, + AggregateExchangeRatePrevotes: aggregateExchangeRatePrevotes, + AggregateExchangeRateVotes: aggregateExchangeRateVotes, + Pairs: pairs, + Rewards: rewards, + } +} + +// DefaultGenesisState - default GenesisState +func DefaultGenesisState() *GenesisState { + return NewGenesisState( + DefaultParams(), + []ExchangeRateTuple{}, + []FeederDelegation{}, + []MissCounter{}, + []AggregateExchangeRatePrevote{}, + []AggregateExchangeRateVote{}, + []asset.Pair{}, + []Rewards{}) +} + +// ValidateGenesis validates the oracle genesis state +func ValidateGenesis(data *GenesisState) error { + return data.Params.Validate() +} + +// GetGenesisStateFromAppState returns x/oracle GenesisState given raw application +// genesis state. +func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *GenesisState { + var genesisState GenesisState + + if appState[ModuleName] != nil { + cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) + } + + return &genesisState +} diff --git a/x/oracle/types/genesis.pb.go b/x/oracle/types/genesis.pb.go new file mode 100644 index 00000000..f549f629 --- /dev/null +++ b/x/oracle/types/genesis.pb.go @@ -0,0 +1,1205 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: archway/oracle/v1/genesis.proto + +package types + +import ( + fmt "fmt" + github_com_archway_network_archway_x_oracle_asset "github.com/archway-network/archway/x/oracle/asset" + _ "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the oracle module's genesis state. +type GenesisState struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + FeederDelegations []FeederDelegation `protobuf:"bytes,2,rep,name=feeder_delegations,json=feederDelegations,proto3" json:"feeder_delegations"` + ExchangeRates ExchangeRateTuples `protobuf:"bytes,3,rep,name=exchange_rates,json=exchangeRates,proto3,castrepeated=ExchangeRateTuples" json:"exchange_rates"` + MissCounters []MissCounter `protobuf:"bytes,4,rep,name=miss_counters,json=missCounters,proto3" json:"miss_counters"` + AggregateExchangeRatePrevotes []AggregateExchangeRatePrevote `protobuf:"bytes,5,rep,name=aggregate_exchange_rate_prevotes,json=aggregateExchangeRatePrevotes,proto3" json:"aggregate_exchange_rate_prevotes"` + AggregateExchangeRateVotes []AggregateExchangeRateVote `protobuf:"bytes,6,rep,name=aggregate_exchange_rate_votes,json=aggregateExchangeRateVotes,proto3" json:"aggregate_exchange_rate_votes"` + Pairs []github_com_archway_network_archway_x_oracle_asset.Pair `protobuf:"bytes,7,rep,name=pairs,proto3,customtype=github.com/archway-network/archway/x/oracle/asset.Pair" json:"pairs"` + Rewards []Rewards `protobuf:"bytes,8,rep,name=rewards,proto3" json:"rewards"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_6285e82cfd585f9b, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func (m *GenesisState) GetFeederDelegations() []FeederDelegation { + if m != nil { + return m.FeederDelegations + } + return nil +} + +func (m *GenesisState) GetExchangeRates() ExchangeRateTuples { + if m != nil { + return m.ExchangeRates + } + return nil +} + +func (m *GenesisState) GetMissCounters() []MissCounter { + if m != nil { + return m.MissCounters + } + return nil +} + +func (m *GenesisState) GetAggregateExchangeRatePrevotes() []AggregateExchangeRatePrevote { + if m != nil { + return m.AggregateExchangeRatePrevotes + } + return nil +} + +func (m *GenesisState) GetAggregateExchangeRateVotes() []AggregateExchangeRateVote { + if m != nil { + return m.AggregateExchangeRateVotes + } + return nil +} + +func (m *GenesisState) GetRewards() []Rewards { + if m != nil { + return m.Rewards + } + return nil +} + +// FeederDelegation is the address for where oracle feeder authority are +// delegated to. By default this struct is only used at genesis to feed in +// default feeder addresses. +type FeederDelegation struct { + FeederAddress string `protobuf:"bytes,1,opt,name=feeder_address,json=feederAddress,proto3" json:"feeder_address,omitempty"` + ValidatorAddress string `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` +} + +func (m *FeederDelegation) Reset() { *m = FeederDelegation{} } +func (m *FeederDelegation) String() string { return proto.CompactTextString(m) } +func (*FeederDelegation) ProtoMessage() {} +func (*FeederDelegation) Descriptor() ([]byte, []int) { + return fileDescriptor_6285e82cfd585f9b, []int{1} +} +func (m *FeederDelegation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FeederDelegation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FeederDelegation.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *FeederDelegation) XXX_Merge(src proto.Message) { + xxx_messageInfo_FeederDelegation.Merge(m, src) +} +func (m *FeederDelegation) XXX_Size() int { + return m.Size() +} +func (m *FeederDelegation) XXX_DiscardUnknown() { + xxx_messageInfo_FeederDelegation.DiscardUnknown(m) +} + +var xxx_messageInfo_FeederDelegation proto.InternalMessageInfo + +func (m *FeederDelegation) GetFeederAddress() string { + if m != nil { + return m.FeederAddress + } + return "" +} + +func (m *FeederDelegation) GetValidatorAddress() string { + if m != nil { + return m.ValidatorAddress + } + return "" +} + +// MissCounter defines an miss counter and validator address pair used in +// oracle module's genesis state +type MissCounter struct { + ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + MissCounter uint64 `protobuf:"varint,2,opt,name=miss_counter,json=missCounter,proto3" json:"miss_counter,omitempty"` +} + +func (m *MissCounter) Reset() { *m = MissCounter{} } +func (m *MissCounter) String() string { return proto.CompactTextString(m) } +func (*MissCounter) ProtoMessage() {} +func (*MissCounter) Descriptor() ([]byte, []int) { + return fileDescriptor_6285e82cfd585f9b, []int{2} +} +func (m *MissCounter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MissCounter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MissCounter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MissCounter) XXX_Merge(src proto.Message) { + xxx_messageInfo_MissCounter.Merge(m, src) +} +func (m *MissCounter) XXX_Size() int { + return m.Size() +} +func (m *MissCounter) XXX_DiscardUnknown() { + xxx_messageInfo_MissCounter.DiscardUnknown(m) +} + +var xxx_messageInfo_MissCounter proto.InternalMessageInfo + +func (m *MissCounter) GetValidatorAddress() string { + if m != nil { + return m.ValidatorAddress + } + return "" +} + +func (m *MissCounter) GetMissCounter() uint64 { + if m != nil { + return m.MissCounter + } + return 0 +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "archway.oracle.v1.GenesisState") + proto.RegisterType((*FeederDelegation)(nil), "archway.oracle.v1.FeederDelegation") + proto.RegisterType((*MissCounter)(nil), "archway.oracle.v1.MissCounter") +} + +func init() { proto.RegisterFile("archway/oracle/v1/genesis.proto", fileDescriptor_6285e82cfd585f9b) } + +var fileDescriptor_6285e82cfd585f9b = []byte{ + // 545 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x5f, 0x6f, 0x12, 0x4d, + 0x14, 0xc6, 0xd9, 0xb6, 0xd0, 0xb7, 0x03, 0x34, 0x65, 0xf2, 0x5e, 0xac, 0x24, 0x5d, 0x10, 0x35, + 0x21, 0x51, 0x77, 0x43, 0x4d, 0x34, 0xf1, 0xc2, 0xa4, 0xf8, 0x2f, 0xc6, 0x98, 0x90, 0xb5, 0x31, + 0xc6, 0xc4, 0x90, 0x61, 0xf7, 0xb0, 0x6c, 0x84, 0x9d, 0xcd, 0x9c, 0x01, 0xda, 0x1b, 0x3f, 0x83, + 0x9f, 0xc3, 0x4f, 0xd2, 0xcb, 0x5e, 0x1a, 0x2f, 0xd0, 0xc0, 0x17, 0x31, 0xbb, 0x33, 0x14, 0x2c, + 0x5b, 0xa3, 0x77, 0x70, 0xce, 0xef, 0x3c, 0xcf, 0x33, 0xe4, 0x81, 0xd4, 0x98, 0xf0, 0x06, 0x53, + 0x76, 0xe6, 0x70, 0xc1, 0xbc, 0x21, 0x38, 0x93, 0x96, 0x13, 0x40, 0x04, 0x18, 0xa2, 0x1d, 0x0b, + 0x2e, 0x39, 0xad, 0x68, 0xc0, 0x56, 0x80, 0x3d, 0x69, 0x55, 0xff, 0x0f, 0x78, 0xc0, 0xd3, 0xad, + 0x93, 0x7c, 0x52, 0x60, 0xd5, 0xda, 0x54, 0xd2, 0x27, 0x7a, 0xef, 0x71, 0x1c, 0x71, 0x74, 0x7a, + 0x0c, 0x93, 0x65, 0x0f, 0x24, 0x6b, 0x39, 0x1e, 0x0f, 0x23, 0xb5, 0x6f, 0xcc, 0xf2, 0xa4, 0xf4, + 0x52, 0x59, 0xbf, 0x95, 0x4c, 0x02, 0x7d, 0x44, 0x0a, 0x31, 0x13, 0x6c, 0x84, 0xa6, 0x51, 0x37, + 0x9a, 0xc5, 0xa3, 0x1b, 0xf6, 0x46, 0x14, 0xbb, 0x93, 0x02, 0xed, 0x9d, 0xf3, 0x59, 0x2d, 0xe7, + 0x6a, 0x9c, 0xbe, 0x27, 0xb4, 0x0f, 0xe0, 0x83, 0xe8, 0xfa, 0x30, 0x84, 0x80, 0xc9, 0x90, 0x47, + 0x68, 0x6e, 0xd5, 0xb7, 0x9b, 0xc5, 0xa3, 0x5b, 0x19, 0x22, 0x2f, 0x52, 0xf8, 0xd9, 0x25, 0xab, + 0xe5, 0x2a, 0xfd, 0x2b, 0x73, 0xa4, 0x01, 0xd9, 0x87, 0x53, 0x6f, 0xc0, 0xa2, 0x00, 0xba, 0x82, + 0x49, 0x40, 0x73, 0x3b, 0x55, 0xbd, 0x9d, 0xa1, 0xfa, 0x5c, 0x83, 0x2e, 0x93, 0x70, 0x32, 0x8e, + 0x87, 0xd0, 0xae, 0x26, 0xb2, 0x5f, 0x7f, 0xd4, 0xe8, 0xc6, 0x0a, 0xdd, 0x32, 0xac, 0xcd, 0x90, + 0xbe, 0x22, 0xe5, 0x51, 0x88, 0xd8, 0xf5, 0xf8, 0x38, 0x92, 0x20, 0xd0, 0xdc, 0x49, 0x7d, 0xac, + 0x0c, 0x9f, 0x37, 0x21, 0xe2, 0x53, 0x85, 0xe9, 0xe0, 0xa5, 0xd1, 0x6a, 0x84, 0xf4, 0x33, 0xa9, + 0xb3, 0x20, 0x10, 0xc9, 0x1b, 0xa0, 0xfb, 0x5b, 0xfa, 0x6e, 0x2c, 0x60, 0xc2, 0x93, 0x57, 0xe4, + 0x53, 0x75, 0x27, 0x43, 0xfd, 0x78, 0x79, 0xba, 0x9e, 0xb9, 0xa3, 0xee, 0xb4, 0xdd, 0x21, 0xfb, + 0x03, 0x83, 0x74, 0x4c, 0x0e, 0xaf, 0xf3, 0x57, 0xe6, 0x85, 0xd4, 0xfc, 0xde, 0xdf, 0x9a, 0xbf, + 0x5b, 0x39, 0x57, 0xd9, 0x75, 0x00, 0xd2, 0x13, 0x92, 0x8f, 0x59, 0x28, 0xd0, 0xdc, 0xad, 0x6f, + 0x37, 0xf7, 0xda, 0x4f, 0x92, 0x83, 0xef, 0xb3, 0xda, 0xc3, 0x20, 0x94, 0x83, 0x71, 0xcf, 0xf6, + 0xf8, 0xc8, 0xd1, 0x86, 0xf7, 0x23, 0x90, 0x53, 0x2e, 0x3e, 0x2d, 0xbf, 0x3b, 0xa7, 0xcb, 0x0a, + 0x33, 0x44, 0x90, 0x76, 0x87, 0x85, 0xc2, 0x55, 0x62, 0xf4, 0x31, 0xd9, 0x15, 0x30, 0x65, 0xc2, + 0x47, 0xf3, 0xbf, 0x34, 0x76, 0x35, 0x23, 0xb6, 0xab, 0x08, 0x1d, 0x72, 0x79, 0xd0, 0xe8, 0x93, + 0x83, 0xab, 0x4d, 0xa3, 0x77, 0xc8, 0xbe, 0xae, 0x2a, 0xf3, 0x7d, 0x01, 0xa8, 0xba, 0xbe, 0xe7, + 0x96, 0xd5, 0xf4, 0x58, 0x0d, 0xe9, 0x5d, 0x52, 0x99, 0xb0, 0x61, 0xe8, 0x33, 0xc9, 0x57, 0xe4, + 0x56, 0x4a, 0x1e, 0x5c, 0x2e, 0x34, 0xdc, 0xf8, 0x48, 0x8a, 0x6b, 0x9d, 0xc8, 0xbe, 0x35, 0xb2, + 0x6f, 0xe9, 0x4d, 0x52, 0x5a, 0xef, 0x5d, 0xea, 0xb1, 0xe3, 0x16, 0xd7, 0x0a, 0xd5, 0x7e, 0x7d, + 0x3e, 0xb7, 0x8c, 0x8b, 0xb9, 0x65, 0xfc, 0x9c, 0x5b, 0xc6, 0x97, 0x85, 0x95, 0xbb, 0x58, 0x58, + 0xb9, 0x6f, 0x0b, 0x2b, 0xf7, 0xa1, 0xf5, 0x2f, 0xbf, 0xad, 0x3c, 0x8b, 0x01, 0x7b, 0x85, 0xf4, + 0xbf, 0xff, 0xe0, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0xba, 0xcf, 0x8c, 0x87, 0x04, 0x00, + 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Rewards) > 0 { + for iNdEx := len(m.Rewards) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Rewards[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.Pairs) > 0 { + for iNdEx := len(m.Pairs) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.Pairs[iNdEx].Size() + i -= size + if _, err := m.Pairs[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if len(m.AggregateExchangeRateVotes) > 0 { + for iNdEx := len(m.AggregateExchangeRateVotes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AggregateExchangeRateVotes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.AggregateExchangeRatePrevotes) > 0 { + for iNdEx := len(m.AggregateExchangeRatePrevotes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AggregateExchangeRatePrevotes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.MissCounters) > 0 { + for iNdEx := len(m.MissCounters) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MissCounters[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.ExchangeRates) > 0 { + for iNdEx := len(m.ExchangeRates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ExchangeRates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.FeederDelegations) > 0 { + for iNdEx := len(m.FeederDelegations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.FeederDelegations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *FeederDelegation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FeederDelegation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FeederDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidatorAddress) > 0 { + i -= len(m.ValidatorAddress) + copy(dAtA[i:], m.ValidatorAddress) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ValidatorAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.FeederAddress) > 0 { + i -= len(m.FeederAddress) + copy(dAtA[i:], m.FeederAddress) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.FeederAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MissCounter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MissCounter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MissCounter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MissCounter != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.MissCounter)) + i-- + dAtA[i] = 0x10 + } + if len(m.ValidatorAddress) > 0 { + i -= len(m.ValidatorAddress) + copy(dAtA[i:], m.ValidatorAddress) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ValidatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.FeederDelegations) > 0 { + for _, e := range m.FeederDelegations { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.ExchangeRates) > 0 { + for _, e := range m.ExchangeRates { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.MissCounters) > 0 { + for _, e := range m.MissCounters { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.AggregateExchangeRatePrevotes) > 0 { + for _, e := range m.AggregateExchangeRatePrevotes { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.AggregateExchangeRateVotes) > 0 { + for _, e := range m.AggregateExchangeRateVotes { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Pairs) > 0 { + for _, e := range m.Pairs { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Rewards) > 0 { + for _, e := range m.Rewards { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *FeederDelegation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FeederAddress) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.ValidatorAddress) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func (m *MissCounter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ValidatorAddress) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.MissCounter != 0 { + n += 1 + sovGenesis(uint64(m.MissCounter)) + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FeederDelegations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FeederDelegations = append(m.FeederDelegations, FeederDelegation{}) + if err := m.FeederDelegations[len(m.FeederDelegations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExchangeRates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExchangeRates = append(m.ExchangeRates, ExchangeRateTuple{}) + if err := m.ExchangeRates[len(m.ExchangeRates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MissCounters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MissCounters = append(m.MissCounters, MissCounter{}) + if err := m.MissCounters[len(m.MissCounters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregateExchangeRatePrevotes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AggregateExchangeRatePrevotes = append(m.AggregateExchangeRatePrevotes, AggregateExchangeRatePrevote{}) + if err := m.AggregateExchangeRatePrevotes[len(m.AggregateExchangeRatePrevotes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregateExchangeRateVotes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AggregateExchangeRateVotes = append(m.AggregateExchangeRateVotes, AggregateExchangeRateVote{}) + if err := m.AggregateExchangeRateVotes[len(m.AggregateExchangeRateVotes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pairs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_archway_network_archway_x_oracle_asset.Pair + m.Pairs = append(m.Pairs, v) + if err := m.Pairs[len(m.Pairs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rewards", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Rewards = append(m.Rewards, Rewards{}) + if err := m.Rewards[len(m.Rewards)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FeederDelegation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FeederDelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FeederDelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FeederAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FeederAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MissCounter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MissCounter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MissCounter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MissCounter", wireType) + } + m.MissCounter = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MissCounter |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/oracle/types/genesis_test.go b/x/oracle/types/genesis_test.go new file mode 100644 index 00000000..f150ad60 --- /dev/null +++ b/x/oracle/types/genesis_test.go @@ -0,0 +1,28 @@ +package types_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/archway-network/archway/app" + "github.com/archway-network/archway/x/oracle/types" +) + +func TestGenesisValidation(t *testing.T) { + genState := types.DefaultGenesisState() + require.NoError(t, types.ValidateGenesis(genState)) + + genState.Params.VotePeriod = 0 + require.Error(t, types.ValidateGenesis(genState)) +} + +func TestGetGenesisStateFromAppState(t *testing.T) { + cdc := app.MakeEncodingConfig().Marshaler + appState := make(map[string]json.RawMessage) + + defaultGenesisState := types.DefaultGenesisState() + appState[types.ModuleName] = cdc.MustMarshalJSON(defaultGenesisState) + require.Equal(t, *defaultGenesisState, *types.GetGenesisStateFromAppState(cdc, appState)) +} diff --git a/x/oracle/types/hash.go b/x/oracle/types/hash.go new file mode 100644 index 00000000..b9d816ec --- /dev/null +++ b/x/oracle/types/hash.go @@ -0,0 +1,121 @@ +package types + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + + "gopkg.in/yaml.v2" + + "github.com/cometbft/cometbft/crypto/tmhash" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ yaml.Marshaler = AggregateVoteHash{} + +// AggregateVoteHash is hash value to hide vote exchange rates +// which is formatted as hex string in SHA256("{salt}:({pair},{exchange_rate})|...|({pair},{exchange_rate}):{voter}") +type AggregateVoteHash []byte + +// GetAggregateVoteHash computes hash value of ExchangeRateVote +// to avoid redundant DecCoins stringify operation, use string argument +// TODO(mercilex): use ExchangeRateTuples +func GetAggregateVoteHash(salt string, exchangeRatesStr string, voter sdk.ValAddress) AggregateVoteHash { + hash := tmhash.NewTruncated() + sourceStr := fmt.Sprintf("%s:%s:%s", salt, exchangeRatesStr, voter.String()) + _, err := hash.Write([]byte(sourceStr)) + if err != nil { + panic(err) + } + bz := hash.Sum(nil) + return bz +} + +// AggregateVoteHashFromHexString convert hex string to AggregateVoteHash +func AggregateVoteHashFromHexString(s string) (AggregateVoteHash, error) { + h, err := hex.DecodeString(s) + if err != nil { + return nil, err + } + + return h, nil +} + +// String implements fmt.Stringer interface +func (h AggregateVoteHash) String() string { + return hex.EncodeToString(h) +} + +// Equal does bytes equal check +func (h AggregateVoteHash) Equal(h2 AggregateVoteHash) bool { + return bytes.Equal(h, h2) +} + +// Empty check the name hash has zero length +func (h AggregateVoteHash) Empty() bool { + return len(h) == 0 +} + +// Bytes returns the raw address bytes. +func (h AggregateVoteHash) Bytes() []byte { + return h +} + +// Size returns the raw address bytes. +func (h AggregateVoteHash) Size() int { + return len(h) +} + +// Format implements the fmt.Formatter interface. +func (h AggregateVoteHash) Format(s fmt.State, verb rune) { + switch verb { + case 's': + _, _ = s.Write([]byte(h.String())) + case 'p': + _, _ = s.Write([]byte(fmt.Sprintf("%p", h))) + default: + _, _ = s.Write([]byte(fmt.Sprintf("%X", []byte(h)))) + } +} + +// Marshal returns the raw address bytes. It is needed for protobuf +// compatibility. +func (h AggregateVoteHash) Marshal() ([]byte, error) { + return h, nil +} + +// Unmarshal sets the address to the given data. It is needed for protobuf +// compatibility. +func (h *AggregateVoteHash) Unmarshal(data []byte) error { + *h = data + return nil +} + +// MarshalJSON marshals to JSON using Bech32. +func (h AggregateVoteHash) MarshalJSON() ([]byte, error) { + return json.Marshal(h.String()) +} + +// MarshalYAML marshals to YAML using Bech32. +func (h AggregateVoteHash) MarshalYAML() (interface{}, error) { + return h.String(), nil +} + +// UnmarshalJSON unmarshals from JSON assuming Bech32 encoding. +func (h *AggregateVoteHash) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + h2, err := AggregateVoteHashFromHexString(s) + if err != nil { + return err + } + + *h = h2 + return nil +} diff --git a/x/oracle/types/hash_test.go b/x/oracle/types/hash_test.go new file mode 100644 index 00000000..3b80f824 --- /dev/null +++ b/x/oracle/types/hash_test.go @@ -0,0 +1,42 @@ +package types_test + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" + + "github.com/archway-network/archway/x/oracle/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestAggregateVoteHash(t *testing.T) { + addrs := []sdk.AccAddress{ + sdk.AccAddress([]byte("addr1_______________")), + } + + aggregateVoteHash := types.GetAggregateVoteHash("salt", "(100,nibi:usd)|(200000,btc:usd)", sdk.ValAddress(addrs[0])) + hexStr := hex.EncodeToString(aggregateVoteHash) + aggregateVoteHashRes, err := types.AggregateVoteHashFromHexString(hexStr) + require.NoError(t, err) + require.Equal(t, aggregateVoteHash, aggregateVoteHashRes) + require.True(t, aggregateVoteHash.Equal(aggregateVoteHash)) + require.True(t, types.AggregateVoteHash([]byte{}).Empty()) + + got, _ := yaml.Marshal(&aggregateVoteHash) + require.Equal(t, aggregateVoteHash.String()+"\n", string(got)) + + res := types.AggregateVoteHash{} + testMarshal(t, &aggregateVoteHash, &res, aggregateVoteHash.MarshalJSON, (&res).UnmarshalJSON) + testMarshal(t, &aggregateVoteHash, &res, aggregateVoteHash.Marshal, (&res).Unmarshal) +} + +func testMarshal(t *testing.T, original interface{}, res interface{}, marshal func() ([]byte, error), unmarshal func([]byte) error) { + bz, err := marshal() + require.Nil(t, err) + err = unmarshal(bz) + require.Nil(t, err) + require.Equal(t, original, res) +} diff --git a/x/oracle/types/keys.go b/x/oracle/types/keys.go new file mode 100644 index 00000000..f27b45a8 --- /dev/null +++ b/x/oracle/types/keys.go @@ -0,0 +1,15 @@ +package types + +const ( + // ModuleName is the name of the oracle module + ModuleName = "oracle" + + // StoreKey is the string store representation + StoreKey = ModuleName + + // RouterKey is the msg router key for the oracle module + RouterKey = ModuleName + + // QuerierRoute is the query router key for the oracle module + QuerierRoute = ModuleName +) diff --git a/x/oracle/types/msgs.go b/x/oracle/types/msgs.go new file mode 100644 index 00000000..05275b81 --- /dev/null +++ b/x/oracle/types/msgs.go @@ -0,0 +1,197 @@ +package types + +import ( + "github.com/cometbft/cometbft/crypto/tmhash" + "github.com/cosmos/cosmos-sdk/types/errors" + + sdkerrors "cosmossdk.io/errors" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ensure Msg interface compliance at compile time +var ( + _ sdk.Msg = &MsgDelegateFeedConsent{} + _ sdk.Msg = &MsgAggregateExchangeRatePrevote{} + _ sdk.Msg = &MsgAggregateExchangeRateVote{} +) + +// oracle message types +const ( + TypeMsgDelegateFeedConsent = "delegate_feeder" + TypeMsgAggregateExchangeRatePrevote = "aggregate_exchange_rate_prevote" + TypeMsgAggregateExchangeRateVote = "aggregate_exchange_rate_vote" +) + +//------------------------------------------------- +//------------------------------------------------- + +// NewMsgAggregateExchangeRatePrevote returns MsgAggregateExchangeRatePrevote instance +func NewMsgAggregateExchangeRatePrevote(hash AggregateVoteHash, feeder sdk.AccAddress, validator sdk.ValAddress) *MsgAggregateExchangeRatePrevote { + return &MsgAggregateExchangeRatePrevote{ + Hash: hash.String(), + Feeder: feeder.String(), + Validator: validator.String(), + } +} + +// Route implements sdk.Msg +func (msg MsgAggregateExchangeRatePrevote) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgAggregateExchangeRatePrevote) Type() string { return TypeMsgAggregateExchangeRatePrevote } + +// GetSignBytes implements sdk.Msg +func (msg MsgAggregateExchangeRatePrevote) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgAggregateExchangeRatePrevote) GetSigners() []sdk.AccAddress { + feeder, err := sdk.AccAddressFromBech32(msg.Feeder) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{feeder} +} + +// ValidateBasic Implements sdk.Msg +func (msg MsgAggregateExchangeRatePrevote) ValidateBasic() error { + _, err := AggregateVoteHashFromHexString(msg.Hash) + if err != nil { + return sdkerrors.Wrapf(ErrInvalidHash, "Invalid vote hash (%s)", err) + } + + // HEX encoding doubles the hash length + if len(msg.Hash) != tmhash.TruncatedSize*2 { + return ErrInvalidHashLength + } + + _, err = sdk.AccAddressFromBech32(msg.Feeder) + if err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidAddress, "Invalid feeder address (%s)", err) + } + + _, err = sdk.ValAddressFromBech32(msg.Validator) + if err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidAddress, "Invalid operator address (%s)", err) + } + + return nil +} + +// NewMsgAggregateExchangeRateVote returns MsgAggregateExchangeRateVote instance +// TODO(mercilex): accept ExchangeRatesTuples +func NewMsgAggregateExchangeRateVote(salt string, exchangeRates string, feeder sdk.AccAddress, validator sdk.ValAddress) *MsgAggregateExchangeRateVote { + return &MsgAggregateExchangeRateVote{ + Salt: salt, + ExchangeRates: exchangeRates, + Feeder: feeder.String(), + Validator: validator.String(), + } +} + +// Route implements sdk.Msg +func (msg MsgAggregateExchangeRateVote) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgAggregateExchangeRateVote) Type() string { return TypeMsgAggregateExchangeRateVote } + +// GetSignBytes implements sdk.Msg +func (msg MsgAggregateExchangeRateVote) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgAggregateExchangeRateVote) GetSigners() []sdk.AccAddress { + feeder, err := sdk.AccAddressFromBech32(msg.Feeder) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{feeder} +} + +// ValidateBasic implements sdk.Msg +func (msg MsgAggregateExchangeRateVote) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Feeder) + if err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidAddress, "Invalid feeder address (%s)", err) + } + + _, err = sdk.ValAddressFromBech32(msg.Validator) + if err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidAddress, "Invalid operator address (%s)", err) + } + + if l := len(msg.ExchangeRates); l == 0 { + return sdkerrors.Wrap(errors.ErrUnknownRequest, "must provide at least one oracle exchange rate") + } else if l > 4096 { + return sdkerrors.Wrap(errors.ErrInvalidRequest, "exchange rates string can not exceed 4096 characters") + } + + exchangeRates, err := ParseExchangeRateTuples(msg.ExchangeRates) + if err != nil { + return sdkerrors.Wrap(errors.ErrInvalidCoins, "failed to parse exchange rates string cause: "+err.Error()) + } + + for _, exchangeRate := range exchangeRates { + // Check overflow bit length + if exchangeRate.ExchangeRate.BigInt().BitLen() > 255+math.LegacyDecimalPrecisionBits { + return sdkerrors.Wrap(ErrInvalidExchangeRate, "overflow") + } + } + + if len(msg.Salt) > 4 || len(msg.Salt) < 1 { + return sdkerrors.Wrap(ErrInvalidSaltLength, "salt length must be [1, 4]") + } + + return nil +} + +// ------------------------ MsgDelegateFeedConsent ------------------------ + +// NewMsgDelegateFeedConsent creates a MsgDelegateFeedConsent instance +func NewMsgDelegateFeedConsent(operatorAddress sdk.ValAddress, feederAddress sdk.AccAddress) *MsgDelegateFeedConsent { + return &MsgDelegateFeedConsent{ + Operator: operatorAddress.String(), + Delegate: feederAddress.String(), + } +} + +// Route implements sdk.Msg +func (msg MsgDelegateFeedConsent) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgDelegateFeedConsent) Type() string { return TypeMsgDelegateFeedConsent } + +// GetSignBytes implements sdk.Msg +func (msg MsgDelegateFeedConsent) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgDelegateFeedConsent) GetSigners() []sdk.AccAddress { + operator, err := sdk.ValAddressFromBech32(msg.Operator) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{sdk.AccAddress(operator)} +} + +// ValidateBasic implements sdk.Msg +func (msg MsgDelegateFeedConsent) ValidateBasic() error { + _, err := sdk.ValAddressFromBech32(msg.Operator) + if err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidAddress, "Invalid operator address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(msg.Delegate) + if err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidAddress, "Invalid delegate address (%s)", err) + } + + return nil +} diff --git a/x/oracle/types/msgs_test.go b/x/oracle/types/msgs_test.go new file mode 100644 index 00000000..9e9afd8f --- /dev/null +++ b/x/oracle/types/msgs_test.go @@ -0,0 +1,125 @@ +package types_test + +import ( + "testing" + + "cosmossdk.io/math" + + "github.com/archway-network/archway/x/oracle/denoms" + "github.com/archway-network/archway/x/oracle/types" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestMsgFeederDelegation(t *testing.T) { + addrs := []sdk.AccAddress{ + sdk.AccAddress([]byte("addr1_______________")), + sdk.AccAddress([]byte("addr2_______________")), + } + + tests := []struct { + delegator sdk.ValAddress + delegate sdk.AccAddress + expectPass bool + }{ + {sdk.ValAddress(addrs[0]), addrs[1], true}, + {sdk.ValAddress{}, addrs[1], false}, + {sdk.ValAddress(addrs[0]), sdk.AccAddress{}, false}, + {nil, nil, false}, + } + + for i, tc := range tests { + msg := types.NewMsgDelegateFeedConsent(tc.delegator, tc.delegate) + if tc.expectPass { + require.Nil(t, msg.ValidateBasic(), "test: %v", i) + } else { + require.NotNil(t, msg.ValidateBasic(), "test: %v", i) + } + } +} + +func TestMsgAggregateExchangeRatePrevote(t *testing.T) { + addrs := []sdk.AccAddress{ + sdk.AccAddress([]byte("addr1_______________")), + } + + exchangeRates := sdk.DecCoins{sdk.NewDecCoinFromDec(denoms.USDC, math.LegacyOneDec()), sdk.NewDecCoinFromDec(denoms.NUSD, math.LegacyNewDecWithPrec(32121, 1))} + bz := types.GetAggregateVoteHash("1", exchangeRates.String(), sdk.ValAddress(addrs[0])) + + tests := []struct { + hash types.AggregateVoteHash + exchangeRates sdk.DecCoins + voter sdk.AccAddress + expectPass bool + }{ + {bz, exchangeRates, addrs[0], true}, + {bz[1:], exchangeRates, addrs[0], false}, + {bz, exchangeRates, sdk.AccAddress{}, false}, + {types.AggregateVoteHash{}, exchangeRates, addrs[0], false}, + } + + for i, tc := range tests { + msg := types.NewMsgAggregateExchangeRatePrevote(tc.hash, tc.voter, sdk.ValAddress(tc.voter)) + if tc.expectPass { + require.NoError(t, msg.ValidateBasic(), "test: %v", i) + } else { + require.Error(t, msg.ValidateBasic(), "test: %v", i) + } + } +} + +func TestMsgAggregateExchangeRateVote(t *testing.T) { + addrs := []sdk.AccAddress{ + sdk.AccAddress("addr1_______________"), + } + + exchangeRates := types.ExchangeRateTuples{ + { + Pair: "FOO:USD", + ExchangeRate: math.LegacyMustNewDecFromStr("1.0"), + }, + { + Pair: "BAR:USD", + ExchangeRate: math.LegacyMustNewDecFromStr("1232.132"), + }, + } + + abstainExchangeRates := types.ExchangeRateTuples{ + { + Pair: "FOO:USD", + ExchangeRate: math.LegacyZeroDec(), + }, + { + Pair: "BAR:USD", + ExchangeRate: math.LegacyMustNewDecFromStr("1232.132"), + }, + } + + tests := []struct { + voter sdk.AccAddress + validator sdk.ValAddress + salt string + exchangeRates types.ExchangeRateTuples + expectPass bool + }{ + {addrs[0], sdk.ValAddress(addrs[0]), "123", exchangeRates, true}, + {addrs[0], sdk.ValAddress(addrs[0]), "123", abstainExchangeRates, true}, + {sdk.AccAddress{}, sdk.ValAddress(addrs[0]), "123", exchangeRates, false}, + {addrs[0], sdk.ValAddress(addrs[0]), "123", types.ExchangeRateTuples{}, false}, + {addrs[0], sdk.ValAddress{}, "123", abstainExchangeRates, false}, + {addrs[0], sdk.ValAddress(addrs[0]), "", abstainExchangeRates, false}, + } + + for i, tc := range tests { + exchangeRates, err := tc.exchangeRates.ToString() + require.NoError(t, err) + msg := types.NewMsgAggregateExchangeRateVote(tc.salt, exchangeRates, tc.voter, tc.validator) + if tc.expectPass { + require.Nil(t, msg.ValidateBasic(), "test: %v", i) + } else { + require.NotNil(t, msg.ValidateBasic(), "test: %v", i) + } + } +} diff --git a/x/oracle/types/oracle.pb.go b/x/oracle/types/oracle.pb.go new file mode 100644 index 00000000..085d4bf3 --- /dev/null +++ b/x/oracle/types/oracle.pb.go @@ -0,0 +1,2062 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: archway/oracle/v1/oracle.proto + +package types + +import ( + cosmossdk_io_math "cosmossdk.io/math" + fmt "fmt" + github_com_archway_network_archway_x_oracle_asset "github.com/archway-network/archway/x/oracle/asset" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + _ "google.golang.org/protobuf/types/known/durationpb" + io "io" + math "math" + math_bits "math/bits" + time "time" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Params defines the module parameters for the x/oracle module. +type Params struct { + // VotePeriod defines the number of blocks during which voting takes place. + VotePeriod uint64 `protobuf:"varint,1,opt,name=vote_period,json=votePeriod,proto3" json:"vote_period,omitempty" yaml:"vote_period"` + // VoteThreshold specifies the minimum proportion of votes that must be + // received for a ballot to pass. + VoteThreshold cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=vote_threshold,json=voteThreshold,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"vote_threshold" yaml:"vote_threshold"` + // RewardBand defines a maxium divergence that a price vote can have from the + // weighted median in the ballot. If a vote lies within the valid range + // defined by: + // μ := weightedMedian, + // validRange := μ ± (μ * rewardBand / 2), + // then rewards are added to the validator performance. + // Note that if the reward band is smaller than 1 standard + // deviation, the band is taken to be 1 standard deviation.a price + RewardBand cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=reward_band,json=rewardBand,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"reward_band" yaml:"reward_band"` + // The set of whitelisted markets, or asset pairs, for the module. + // Ex. '["unibi:uusd","ubtc:uusd"]' + Whitelist []github_com_archway_network_archway_x_oracle_asset.Pair `protobuf:"bytes,4,rep,name=whitelist,proto3,customtype=github.com/archway-network/archway/x/oracle/asset.Pair" json:"whitelist,omitempty" yaml:"whitelist"` + // SlashFraction returns the proportion of an oracle's stake that gets + // slashed in the event of slashing. `SlashFraction` specifies the exact + // penalty for failing a voting period. + SlashFraction cosmossdk_io_math.LegacyDec `protobuf:"bytes,5,opt,name=slash_fraction,json=slashFraction,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"slash_fraction" yaml:"slash_fraction"` + // SlashWindow returns the number of voting periods that specify a + // "slash window". After each slash window, all oracles that have missed more + // than the penalty threshold are slashed. Missing the penalty threshold is + // synonymous with submitting fewer valid votes than `MinValidPerWindow`. + SlashWindow uint64 `protobuf:"varint,6,opt,name=slash_window,json=slashWindow,proto3" json:"slash_window,omitempty" yaml:"slash_window"` + MinValidPerWindow cosmossdk_io_math.LegacyDec `protobuf:"bytes,7,opt,name=min_valid_per_window,json=minValidPerWindow,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_valid_per_window" yaml:"min_valid_per_window"` + // Amount of time to look back for TWAP calculations. + // Ex: "900.000000069s" corresponds to 900 seconds and 69 nanoseconds in JSON. + TwapLookbackWindow time.Duration `protobuf:"bytes,8,opt,name=twap_lookback_window,json=twapLookbackWindow,proto3,stdduration" json:"twap_lookback_window,omitempty" yaml:"twap_lookback_window"` + // The minimum number of voters (i.e. oracle validators) per pair for it to be + // considered a passing ballot. Recommended at least 4. + MinVoters uint64 `protobuf:"varint,9,opt,name=min_voters,json=minVoters,proto3" json:"min_voters,omitempty" yaml:"min_voters"` + // The validator fee ratio that is given to validators every epoch. + ValidatorFeeRatio cosmossdk_io_math.LegacyDec `protobuf:"bytes,10,opt,name=validator_fee_ratio,json=validatorFeeRatio,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"validator_fee_ratio" yaml:"validator_fee_ratio"` + ExpirationBlocks uint64 `protobuf:"varint,11,opt,name=expiration_blocks,json=expirationBlocks,proto3" json:"expiration_blocks,omitempty" yaml:"expiration_blocks"` +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_ceb632d7c2facf1a, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetVotePeriod() uint64 { + if m != nil { + return m.VotePeriod + } + return 0 +} + +func (m *Params) GetSlashWindow() uint64 { + if m != nil { + return m.SlashWindow + } + return 0 +} + +func (m *Params) GetTwapLookbackWindow() time.Duration { + if m != nil { + return m.TwapLookbackWindow + } + return 0 +} + +func (m *Params) GetMinVoters() uint64 { + if m != nil { + return m.MinVoters + } + return 0 +} + +func (m *Params) GetExpirationBlocks() uint64 { + if m != nil { + return m.ExpirationBlocks + } + return 0 +} + +// Struct for aggregate prevoting on the ExchangeRateVote. +// The purpose of aggregate prevote is to hide vote exchange rates with hash +// which is formatted as hex string in +// SHA256("{salt}:({pair},{exchange_rate})|...|({pair},{exchange_rate}):{voter}") +type AggregateExchangeRatePrevote struct { + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty" yaml:"hash"` + Voter string `protobuf:"bytes,2,opt,name=voter,proto3" json:"voter,omitempty" yaml:"voter"` + SubmitBlock uint64 `protobuf:"varint,3,opt,name=submit_block,json=submitBlock,proto3" json:"submit_block,omitempty" yaml:"submit_block"` +} + +func (m *AggregateExchangeRatePrevote) Reset() { *m = AggregateExchangeRatePrevote{} } +func (m *AggregateExchangeRatePrevote) String() string { return proto.CompactTextString(m) } +func (*AggregateExchangeRatePrevote) ProtoMessage() {} +func (*AggregateExchangeRatePrevote) Descriptor() ([]byte, []int) { + return fileDescriptor_ceb632d7c2facf1a, []int{1} +} +func (m *AggregateExchangeRatePrevote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AggregateExchangeRatePrevote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AggregateExchangeRatePrevote.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AggregateExchangeRatePrevote) XXX_Merge(src proto.Message) { + xxx_messageInfo_AggregateExchangeRatePrevote.Merge(m, src) +} +func (m *AggregateExchangeRatePrevote) XXX_Size() int { + return m.Size() +} +func (m *AggregateExchangeRatePrevote) XXX_DiscardUnknown() { + xxx_messageInfo_AggregateExchangeRatePrevote.DiscardUnknown(m) +} + +var xxx_messageInfo_AggregateExchangeRatePrevote proto.InternalMessageInfo + +// MsgAggregateExchangeRateVote - struct for voting on +// the exchange rates different assets. +type AggregateExchangeRateVote struct { + ExchangeRateTuples ExchangeRateTuples `protobuf:"bytes,1,rep,name=exchange_rate_tuples,json=exchangeRateTuples,proto3,castrepeated=ExchangeRateTuples" json:"exchange_rate_tuples" yaml:"exchange_rate_tuples"` + Voter string `protobuf:"bytes,2,opt,name=voter,proto3" json:"voter,omitempty" yaml:"voter"` +} + +func (m *AggregateExchangeRateVote) Reset() { *m = AggregateExchangeRateVote{} } +func (m *AggregateExchangeRateVote) String() string { return proto.CompactTextString(m) } +func (*AggregateExchangeRateVote) ProtoMessage() {} +func (*AggregateExchangeRateVote) Descriptor() ([]byte, []int) { + return fileDescriptor_ceb632d7c2facf1a, []int{2} +} +func (m *AggregateExchangeRateVote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AggregateExchangeRateVote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AggregateExchangeRateVote.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AggregateExchangeRateVote) XXX_Merge(src proto.Message) { + xxx_messageInfo_AggregateExchangeRateVote.Merge(m, src) +} +func (m *AggregateExchangeRateVote) XXX_Size() int { + return m.Size() +} +func (m *AggregateExchangeRateVote) XXX_DiscardUnknown() { + xxx_messageInfo_AggregateExchangeRateVote.DiscardUnknown(m) +} + +var xxx_messageInfo_AggregateExchangeRateVote proto.InternalMessageInfo + +// ExchangeRateTuple - struct to store interpreted exchange rates data to store +type ExchangeRateTuple struct { + Pair github_com_archway_network_archway_x_oracle_asset.Pair `protobuf:"bytes,1,opt,name=pair,proto3,customtype=github.com/archway-network/archway/x/oracle/asset.Pair" json:"pair" yaml:"pair"` + ExchangeRate cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=exchange_rate,json=exchangeRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"exchange_rate" yaml:"exchange_rate"` +} + +func (m *ExchangeRateTuple) Reset() { *m = ExchangeRateTuple{} } +func (m *ExchangeRateTuple) String() string { return proto.CompactTextString(m) } +func (*ExchangeRateTuple) ProtoMessage() {} +func (*ExchangeRateTuple) Descriptor() ([]byte, []int) { + return fileDescriptor_ceb632d7c2facf1a, []int{3} +} +func (m *ExchangeRateTuple) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ExchangeRateTuple) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ExchangeRateTuple.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ExchangeRateTuple) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExchangeRateTuple.Merge(m, src) +} +func (m *ExchangeRateTuple) XXX_Size() int { + return m.Size() +} +func (m *ExchangeRateTuple) XXX_DiscardUnknown() { + xxx_messageInfo_ExchangeRateTuple.DiscardUnknown(m) +} + +var xxx_messageInfo_ExchangeRateTuple proto.InternalMessageInfo + +type DatedPrice struct { + ExchangeRate cosmossdk_io_math.LegacyDec `protobuf:"bytes,1,opt,name=exchange_rate,json=exchangeRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"exchange_rate" yaml:"exchange_rate"` + // creation_height defines the block height when price record was created + CreationHeight int64 `protobuf:"varint,2,opt,name=creation_height,json=creationHeight,proto3" json:"creation_height,omitempty" yaml:"creation_height"` + // creation_time_unix_ms defines the block time in milliseconds since unix epoch, + // when price record was created + CreationTimeUnixMs uint64 `protobuf:"varint,3,opt,name=creation_time_unix_ms,json=creationTimeUnixMs,proto3" json:"creation_time_unix_ms,omitempty" yaml:"creation_time_unix_ms"` +} + +func (m *DatedPrice) Reset() { *m = DatedPrice{} } +func (m *DatedPrice) String() string { return proto.CompactTextString(m) } +func (*DatedPrice) ProtoMessage() {} +func (*DatedPrice) Descriptor() ([]byte, []int) { + return fileDescriptor_ceb632d7c2facf1a, []int{4} +} +func (m *DatedPrice) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DatedPrice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DatedPrice.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DatedPrice) XXX_Merge(src proto.Message) { + xxx_messageInfo_DatedPrice.Merge(m, src) +} +func (m *DatedPrice) XXX_Size() int { + return m.Size() +} +func (m *DatedPrice) XXX_DiscardUnknown() { + xxx_messageInfo_DatedPrice.DiscardUnknown(m) +} + +var xxx_messageInfo_DatedPrice proto.InternalMessageInfo + +func (m *DatedPrice) GetCreationHeight() int64 { + if m != nil { + return m.CreationHeight + } + return 0 +} + +func (m *DatedPrice) GetCreationTimeUnixMs() uint64 { + if m != nil { + return m.CreationTimeUnixMs + } + return 0 +} + +// Rewards defines a credit object towards validators +// which provide prices faithfully for different pairs. +type Rewards struct { + // id uniquely identifies the rewards instance of the pair + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // vote_periods defines the vote periods left in which rewards will be + // distributed. + VotePeriods uint64 `protobuf:"varint,2,opt,name=vote_periods,json=votePeriods,proto3" json:"vote_periods,omitempty"` + // Coins defines the amount of coins to distribute in a single vote period. + Coins []types.Coin `protobuf:"bytes,3,rep,name=coins,proto3" json:"coins"` +} + +func (m *Rewards) Reset() { *m = Rewards{} } +func (m *Rewards) String() string { return proto.CompactTextString(m) } +func (*Rewards) ProtoMessage() {} +func (*Rewards) Descriptor() ([]byte, []int) { + return fileDescriptor_ceb632d7c2facf1a, []int{5} +} +func (m *Rewards) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Rewards) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Rewards.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Rewards) XXX_Merge(src proto.Message) { + xxx_messageInfo_Rewards.Merge(m, src) +} +func (m *Rewards) XXX_Size() int { + return m.Size() +} +func (m *Rewards) XXX_DiscardUnknown() { + xxx_messageInfo_Rewards.DiscardUnknown(m) +} + +var xxx_messageInfo_Rewards proto.InternalMessageInfo + +func (m *Rewards) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Rewards) GetVotePeriods() uint64 { + if m != nil { + return m.VotePeriods + } + return 0 +} + +func (m *Rewards) GetCoins() []types.Coin { + if m != nil { + return m.Coins + } + return nil +} + +func init() { + proto.RegisterType((*Params)(nil), "archway.oracle.v1.Params") + proto.RegisterType((*AggregateExchangeRatePrevote)(nil), "archway.oracle.v1.AggregateExchangeRatePrevote") + proto.RegisterType((*AggregateExchangeRateVote)(nil), "archway.oracle.v1.AggregateExchangeRateVote") + proto.RegisterType((*ExchangeRateTuple)(nil), "archway.oracle.v1.ExchangeRateTuple") + proto.RegisterType((*DatedPrice)(nil), "archway.oracle.v1.DatedPrice") + proto.RegisterType((*Rewards)(nil), "archway.oracle.v1.Rewards") +} + +func init() { proto.RegisterFile("archway/oracle/v1/oracle.proto", fileDescriptor_ceb632d7c2facf1a) } + +var fileDescriptor_ceb632d7c2facf1a = []byte{ + // 1011 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4d, 0x73, 0xdb, 0x44, + 0x18, 0xb6, 0x12, 0x27, 0x8d, 0xd7, 0x49, 0x1a, 0x6f, 0x93, 0xe2, 0xa6, 0x19, 0xcb, 0x2c, 0x0c, + 0x93, 0x03, 0xc8, 0x93, 0xf2, 0x35, 0x04, 0x2e, 0x55, 0x43, 0x87, 0x0e, 0x2d, 0xe3, 0x59, 0x02, + 0xcc, 0xf4, 0x22, 0xd6, 0xd2, 0x46, 0xda, 0x89, 0xa4, 0x35, 0xda, 0x75, 0x9c, 0xfc, 0x83, 0x1e, + 0xe1, 0xc2, 0xc0, 0x2d, 0x67, 0x6e, 0xfc, 0x8b, 0x1e, 0x7b, 0x64, 0x7a, 0x50, 0x21, 0xb9, 0x74, + 0x38, 0xfa, 0x17, 0x30, 0xbb, 0x5a, 0xc7, 0x4a, 0xed, 0x43, 0xe8, 0xf4, 0xa6, 0xf7, 0x63, 0x9f, + 0xf7, 0x79, 0x3f, 0xf6, 0x5d, 0x81, 0x16, 0xc9, 0xfc, 0x68, 0x48, 0x4e, 0x3a, 0x3c, 0x23, 0x7e, + 0x4c, 0x3b, 0x47, 0x3b, 0xe6, 0xcb, 0xe9, 0x67, 0x5c, 0x72, 0xd8, 0x30, 0x76, 0xc7, 0x68, 0x8f, + 0x76, 0x36, 0xd7, 0x43, 0x1e, 0x72, 0x6d, 0xed, 0xa8, 0xaf, 0xc2, 0x71, 0xb3, 0x15, 0x72, 0x1e, + 0xc6, 0xb4, 0xa3, 0xa5, 0xde, 0xe0, 0xa0, 0x13, 0x0c, 0x32, 0x22, 0x19, 0x4f, 0xc7, 0x76, 0x9f, + 0x8b, 0x84, 0x8b, 0x4e, 0x8f, 0x08, 0x15, 0xa5, 0x47, 0x25, 0xd9, 0xe9, 0xf8, 0x9c, 0x19, 0x3b, + 0xfa, 0x7d, 0x09, 0x2c, 0x76, 0x49, 0x46, 0x12, 0x01, 0x3f, 0x05, 0xf5, 0x23, 0x2e, 0xa9, 0xd7, + 0xa7, 0x19, 0xe3, 0x41, 0xd3, 0x6a, 0x5b, 0xdb, 0x55, 0xf7, 0xe6, 0x28, 0xb7, 0xe1, 0x09, 0x49, + 0xe2, 0x5d, 0x54, 0x32, 0x22, 0x0c, 0x94, 0xd4, 0xd5, 0x02, 0xf4, 0xc1, 0xaa, 0xb6, 0xc9, 0x28, + 0xa3, 0x22, 0xe2, 0x71, 0xd0, 0x9c, 0x6b, 0x5b, 0xdb, 0x35, 0xf7, 0x8b, 0xa7, 0xb9, 0x5d, 0x79, + 0x9e, 0xdb, 0xb7, 0x0b, 0x0e, 0x22, 0x38, 0x74, 0x18, 0xef, 0x24, 0x44, 0x46, 0xce, 0x43, 0x1a, + 0x12, 0xff, 0x64, 0x8f, 0xfa, 0xa3, 0xdc, 0xde, 0x28, 0xc1, 0x5f, 0x40, 0x20, 0xbc, 0xa2, 0x14, + 0xfb, 0x63, 0x19, 0x3e, 0x06, 0xf5, 0x8c, 0x0e, 0x49, 0x16, 0x78, 0x3d, 0x92, 0x06, 0xcd, 0x79, + 0x1d, 0xe1, 0xb3, 0xab, 0x45, 0x30, 0x09, 0x94, 0xce, 0x23, 0x0c, 0x0a, 0xc9, 0x25, 0x69, 0x00, + 0x63, 0x50, 0x1b, 0x46, 0x4c, 0xd2, 0x98, 0x09, 0xd9, 0xac, 0xb6, 0xe7, 0xb7, 0x6b, 0xee, 0x37, + 0xcf, 0x73, 0xfb, 0x93, 0x90, 0xc9, 0x68, 0xd0, 0x73, 0x7c, 0x9e, 0x74, 0x4c, 0x3f, 0x3e, 0x48, + 0xa9, 0x1c, 0xf2, 0xec, 0x70, 0x2c, 0x77, 0x8e, 0xc7, 0x1d, 0x24, 0x42, 0x50, 0xe9, 0x74, 0x09, + 0xcb, 0x46, 0xb9, 0xbd, 0x56, 0x04, 0xbc, 0x00, 0x45, 0x78, 0x12, 0x40, 0x95, 0x4b, 0xc4, 0x44, + 0x44, 0xde, 0x41, 0x46, 0x7c, 0xd5, 0xaa, 0xe6, 0xc2, 0x6b, 0x94, 0xeb, 0x32, 0x04, 0xc2, 0x2b, + 0x5a, 0x71, 0xdf, 0xc8, 0x70, 0x17, 0x2c, 0x17, 0x1e, 0x43, 0x96, 0x06, 0x7c, 0xd8, 0x5c, 0xd4, + 0xdd, 0x7c, 0x6b, 0x94, 0xdb, 0x37, 0xca, 0xe7, 0x0b, 0x2b, 0xc2, 0x75, 0x2d, 0xfe, 0xa0, 0x25, + 0x28, 0xc0, 0x7a, 0xc2, 0x52, 0xef, 0x88, 0xc4, 0x2c, 0x50, 0x0d, 0x1f, 0x63, 0x5c, 0xd3, 0x34, + 0xdd, 0xab, 0xd1, 0xbc, 0x5d, 0x84, 0x99, 0x05, 0x84, 0x70, 0x23, 0x61, 0xe9, 0xf7, 0x4a, 0xdb, + 0xa5, 0x99, 0x09, 0xfa, 0xab, 0x05, 0xd6, 0xe5, 0x90, 0xf4, 0xbd, 0x98, 0xf3, 0xc3, 0x1e, 0xf1, + 0x0f, 0xc7, 0x51, 0x97, 0xda, 0xd6, 0x76, 0xfd, 0xce, 0x2d, 0xa7, 0x18, 0x74, 0x67, 0x3c, 0xe8, + 0xce, 0x9e, 0x19, 0x74, 0xf7, 0x81, 0x22, 0xf4, 0x6f, 0x6e, 0xb7, 0x66, 0x1d, 0x7f, 0x9f, 0x27, + 0x4c, 0xd2, 0xa4, 0x2f, 0x4f, 0x26, 0x9c, 0x66, 0xf9, 0xa1, 0xdf, 0x5e, 0xd8, 0x16, 0x86, 0xca, + 0xf4, 0xd0, 0x58, 0x0c, 0xb1, 0x8f, 0x00, 0xd0, 0x49, 0x70, 0x49, 0x33, 0xd1, 0xac, 0xe9, 0x3a, + 0x6e, 0x8c, 0x72, 0xbb, 0x51, 0x4a, 0x50, 0xdb, 0x10, 0xae, 0xa9, 0xb4, 0xf4, 0x37, 0xfc, 0x09, + 0xdc, 0xd0, 0x69, 0x13, 0xc9, 0x33, 0xef, 0x80, 0x52, 0x4f, 0x93, 0x6d, 0x02, 0x5d, 0xc2, 0xbb, + 0x57, 0x2b, 0xe1, 0xa6, 0xb9, 0x18, 0xd3, 0x38, 0x08, 0x37, 0x2e, 0xb4, 0xf7, 0x29, 0xc5, 0x4a, + 0x07, 0x1f, 0x80, 0x06, 0x3d, 0xee, 0xb3, 0xa2, 0x2a, 0x5e, 0x2f, 0xe6, 0xfe, 0xa1, 0x68, 0xd6, + 0x35, 0xdf, 0xad, 0x51, 0x6e, 0x37, 0x0b, 0xb4, 0x29, 0x17, 0x84, 0xd7, 0x26, 0x3a, 0x57, 0xab, + 0x76, 0xab, 0x2f, 0x4f, 0x6d, 0x0b, 0xfd, 0x69, 0x81, 0xad, 0xbb, 0x61, 0x98, 0xd1, 0x90, 0x48, + 0xfa, 0xe5, 0xb1, 0x1f, 0x91, 0x34, 0x54, 0xb1, 0x68, 0x37, 0xa3, 0x2a, 0x65, 0xf8, 0x0e, 0xa8, + 0x46, 0x44, 0x44, 0x7a, 0x55, 0xd4, 0xdc, 0xeb, 0xa3, 0xdc, 0xae, 0x17, 0x41, 0x94, 0x16, 0x61, + 0x6d, 0x84, 0xef, 0x81, 0x05, 0x5d, 0x1f, 0xb3, 0x14, 0xd6, 0x46, 0xb9, 0xbd, 0x3c, 0xb9, 0xf1, + 0x19, 0xc2, 0x85, 0x59, 0x4f, 0xec, 0xa0, 0x97, 0x30, 0x59, 0xf0, 0xd2, 0x37, 0xfc, 0xf2, 0xc4, + 0x96, 0xac, 0x6a, 0x62, 0xb5, 0xa8, 0x09, 0xef, 0x2e, 0x3d, 0x39, 0xb5, 0x2b, 0x2f, 0x4f, 0xed, + 0x0a, 0xfa, 0xc7, 0x02, 0xb7, 0x66, 0x72, 0x56, 0x7d, 0x81, 0xbf, 0x58, 0x60, 0x9d, 0x1a, 0xa5, + 0xaa, 0x24, 0xf5, 0xe4, 0xa0, 0x1f, 0x53, 0xd1, 0xb4, 0xda, 0xf3, 0xdb, 0xf5, 0x3b, 0xef, 0x3a, + 0x53, 0x6b, 0xd7, 0x29, 0x63, 0xec, 0x2b, 0xe7, 0x62, 0xe9, 0x4c, 0xa6, 0x69, 0x16, 0x1e, 0xfa, + 0xe3, 0x85, 0x0d, 0xa7, 0x4e, 0x0a, 0x0c, 0xe9, 0x94, 0xee, 0xaa, 0xf5, 0x29, 0xe5, 0x78, 0x66, + 0x81, 0xc6, 0x14, 0x38, 0x24, 0xa0, 0xda, 0x27, 0x2c, 0x33, 0xcd, 0x78, 0x64, 0x46, 0xec, 0xf5, + 0x77, 0x98, 0x69, 0xa5, 0xc2, 0x44, 0x58, 0x43, 0xc3, 0x1f, 0xc1, 0xca, 0xa5, 0x6c, 0x0d, 0xe5, + 0xcf, 0xaf, 0x36, 0xce, 0xeb, 0x33, 0xea, 0x85, 0xf0, 0x72, 0xb9, 0x24, 0xa5, 0x24, 0x9f, 0xcc, + 0x01, 0xb0, 0x47, 0x24, 0x0d, 0xba, 0x19, 0xf3, 0xe9, 0x74, 0x68, 0xeb, 0x0d, 0x87, 0x86, 0xf7, + 0xc0, 0x75, 0x3f, 0xa3, 0xc5, 0xcd, 0x88, 0x28, 0x0b, 0x23, 0xa9, 0xd3, 0x9b, 0x77, 0x37, 0x47, + 0xb9, 0x7d, 0xb3, 0x00, 0x78, 0xc5, 0x01, 0xe1, 0xd5, 0xb1, 0xe6, 0x2b, 0xad, 0x80, 0xdf, 0x82, + 0x8d, 0x0b, 0x1f, 0xc9, 0x12, 0xea, 0x0d, 0x52, 0x76, 0xec, 0x25, 0xc2, 0x4c, 0x73, 0x7b, 0x94, + 0xdb, 0x5b, 0xaf, 0x40, 0x95, 0xdd, 0x10, 0x86, 0x63, 0xfd, 0x3e, 0x4b, 0xe8, 0x77, 0x29, 0x3b, + 0x7e, 0x24, 0x90, 0x00, 0xd7, 0xb0, 0x7e, 0xac, 0x04, 0x5c, 0x05, 0x73, 0xcc, 0x3c, 0xcd, 0x78, + 0x8e, 0x05, 0xf0, 0x6d, 0xb0, 0x5c, 0x7a, 0x96, 0x85, 0x66, 0x5c, 0xc5, 0xf5, 0xc9, 0xe3, 0x2c, + 0xe0, 0xc7, 0x60, 0x41, 0xbd, 0xf7, 0x8a, 0xc2, 0xbc, 0x5e, 0xa4, 0x45, 0xa9, 0x1c, 0xf5, 0x47, + 0xe0, 0x98, 0x3f, 0x02, 0xe7, 0x1e, 0x67, 0xa9, 0x5b, 0x55, 0xc5, 0xc4, 0x85, 0xb7, 0xfb, 0xf5, + 0xd3, 0xb3, 0x96, 0xf5, 0xec, 0xac, 0x65, 0xfd, 0x7d, 0xd6, 0xb2, 0x7e, 0x3e, 0x6f, 0x55, 0x9e, + 0x9d, 0xb7, 0x2a, 0x7f, 0x9d, 0xb7, 0x2a, 0x8f, 0x77, 0xfe, 0xcf, 0x48, 0xc9, 0x93, 0x3e, 0x15, + 0xbd, 0x45, 0xbd, 0xb5, 0x3f, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x27, 0x88, 0xf6, 0xf7, + 0x08, 0x00, 0x00, +} + +func (this *Params) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Params) + if !ok { + that2, ok := that.(Params) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.VotePeriod != that1.VotePeriod { + return false + } + if !this.VoteThreshold.Equal(that1.VoteThreshold) { + return false + } + if !this.RewardBand.Equal(that1.RewardBand) { + return false + } + if len(this.Whitelist) != len(that1.Whitelist) { + return false + } + for i := range this.Whitelist { + if !this.Whitelist[i].Equal(that1.Whitelist[i]) { + return false + } + } + if !this.SlashFraction.Equal(that1.SlashFraction) { + return false + } + if this.SlashWindow != that1.SlashWindow { + return false + } + if !this.MinValidPerWindow.Equal(that1.MinValidPerWindow) { + return false + } + if this.TwapLookbackWindow != that1.TwapLookbackWindow { + return false + } + if this.MinVoters != that1.MinVoters { + return false + } + if !this.ValidatorFeeRatio.Equal(that1.ValidatorFeeRatio) { + return false + } + if this.ExpirationBlocks != that1.ExpirationBlocks { + return false + } + return true +} +func (m *Params) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ExpirationBlocks != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.ExpirationBlocks)) + i-- + dAtA[i] = 0x58 + } + { + size := m.ValidatorFeeRatio.Size() + i -= size + if _, err := m.ValidatorFeeRatio.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 + if m.MinVoters != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.MinVoters)) + i-- + dAtA[i] = 0x48 + } + n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.TwapLookbackWindow, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TwapLookbackWindow):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintOracle(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x42 + { + size := m.MinValidPerWindow.Size() + i -= size + if _, err := m.MinValidPerWindow.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + if m.SlashWindow != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.SlashWindow)) + i-- + dAtA[i] = 0x30 + } + { + size := m.SlashFraction.Size() + i -= size + if _, err := m.SlashFraction.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if len(m.Whitelist) > 0 { + for iNdEx := len(m.Whitelist) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.Whitelist[iNdEx].Size() + i -= size + if _, err := m.Whitelist[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + { + size := m.RewardBand.Size() + i -= size + if _, err := m.RewardBand.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size := m.VoteThreshold.Size() + i -= size + if _, err := m.VoteThreshold.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.VotePeriod != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.VotePeriod)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *AggregateExchangeRatePrevote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AggregateExchangeRatePrevote) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AggregateExchangeRatePrevote) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SubmitBlock != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.SubmitBlock)) + i-- + dAtA[i] = 0x18 + } + if len(m.Voter) > 0 { + i -= len(m.Voter) + copy(dAtA[i:], m.Voter) + i = encodeVarintOracle(dAtA, i, uint64(len(m.Voter))) + i-- + dAtA[i] = 0x12 + } + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintOracle(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AggregateExchangeRateVote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AggregateExchangeRateVote) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AggregateExchangeRateVote) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Voter) > 0 { + i -= len(m.Voter) + copy(dAtA[i:], m.Voter) + i = encodeVarintOracle(dAtA, i, uint64(len(m.Voter))) + i-- + dAtA[i] = 0x12 + } + if len(m.ExchangeRateTuples) > 0 { + for iNdEx := len(m.ExchangeRateTuples) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ExchangeRateTuples[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ExchangeRateTuple) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExchangeRateTuple) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ExchangeRateTuple) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.ExchangeRate.Size() + i -= size + if _, err := m.ExchangeRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size := m.Pair.Size() + i -= size + if _, err := m.Pair.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *DatedPrice) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DatedPrice) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DatedPrice) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CreationTimeUnixMs != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.CreationTimeUnixMs)) + i-- + dAtA[i] = 0x18 + } + if m.CreationHeight != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.CreationHeight)) + i-- + dAtA[i] = 0x10 + } + { + size := m.ExchangeRate.Size() + i -= size + if _, err := m.ExchangeRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *Rewards) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Rewards) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Rewards) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Coins) > 0 { + for iNdEx := len(m.Coins) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Coins[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintOracle(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.VotePeriods != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.VotePeriods)) + i-- + dAtA[i] = 0x10 + } + if m.Id != 0 { + i = encodeVarintOracle(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintOracle(dAtA []byte, offset int, v uint64) int { + offset -= sovOracle(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.VotePeriod != 0 { + n += 1 + sovOracle(uint64(m.VotePeriod)) + } + l = m.VoteThreshold.Size() + n += 1 + l + sovOracle(uint64(l)) + l = m.RewardBand.Size() + n += 1 + l + sovOracle(uint64(l)) + if len(m.Whitelist) > 0 { + for _, e := range m.Whitelist { + l = e.Size() + n += 1 + l + sovOracle(uint64(l)) + } + } + l = m.SlashFraction.Size() + n += 1 + l + sovOracle(uint64(l)) + if m.SlashWindow != 0 { + n += 1 + sovOracle(uint64(m.SlashWindow)) + } + l = m.MinValidPerWindow.Size() + n += 1 + l + sovOracle(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TwapLookbackWindow) + n += 1 + l + sovOracle(uint64(l)) + if m.MinVoters != 0 { + n += 1 + sovOracle(uint64(m.MinVoters)) + } + l = m.ValidatorFeeRatio.Size() + n += 1 + l + sovOracle(uint64(l)) + if m.ExpirationBlocks != 0 { + n += 1 + sovOracle(uint64(m.ExpirationBlocks)) + } + return n +} + +func (m *AggregateExchangeRatePrevote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovOracle(uint64(l)) + } + l = len(m.Voter) + if l > 0 { + n += 1 + l + sovOracle(uint64(l)) + } + if m.SubmitBlock != 0 { + n += 1 + sovOracle(uint64(m.SubmitBlock)) + } + return n +} + +func (m *AggregateExchangeRateVote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ExchangeRateTuples) > 0 { + for _, e := range m.ExchangeRateTuples { + l = e.Size() + n += 1 + l + sovOracle(uint64(l)) + } + } + l = len(m.Voter) + if l > 0 { + n += 1 + l + sovOracle(uint64(l)) + } + return n +} + +func (m *ExchangeRateTuple) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Pair.Size() + n += 1 + l + sovOracle(uint64(l)) + l = m.ExchangeRate.Size() + n += 1 + l + sovOracle(uint64(l)) + return n +} + +func (m *DatedPrice) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ExchangeRate.Size() + n += 1 + l + sovOracle(uint64(l)) + if m.CreationHeight != 0 { + n += 1 + sovOracle(uint64(m.CreationHeight)) + } + if m.CreationTimeUnixMs != 0 { + n += 1 + sovOracle(uint64(m.CreationTimeUnixMs)) + } + return n +} + +func (m *Rewards) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovOracle(uint64(m.Id)) + } + if m.VotePeriods != 0 { + n += 1 + sovOracle(uint64(m.VotePeriods)) + } + if len(m.Coins) > 0 { + for _, e := range m.Coins { + l = e.Size() + n += 1 + l + sovOracle(uint64(l)) + } + } + return n +} + +func sovOracle(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozOracle(x uint64) (n int) { + return sovOracle(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VotePeriod", wireType) + } + m.VotePeriod = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VotePeriod |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VoteThreshold", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.VoteThreshold.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RewardBand", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.RewardBand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Whitelist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_archway_network_archway_x_oracle_asset.Pair + m.Whitelist = append(m.Whitelist, v) + if err := m.Whitelist[len(m.Whitelist)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashFraction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SlashFraction.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashWindow", wireType) + } + m.SlashWindow = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SlashWindow |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinValidPerWindow", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MinValidPerWindow.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TwapLookbackWindow", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.TwapLookbackWindow, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinVoters", wireType) + } + m.MinVoters = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinVoters |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorFeeRatio", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ValidatorFeeRatio.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpirationBlocks", wireType) + } + m.ExpirationBlocks = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExpirationBlocks |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipOracle(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOracle + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AggregateExchangeRatePrevote) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AggregateExchangeRatePrevote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AggregateExchangeRatePrevote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Voter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Voter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubmitBlock", wireType) + } + m.SubmitBlock = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubmitBlock |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipOracle(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOracle + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AggregateExchangeRateVote) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AggregateExchangeRateVote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AggregateExchangeRateVote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExchangeRateTuples", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExchangeRateTuples = append(m.ExchangeRateTuples, ExchangeRateTuple{}) + if err := m.ExchangeRateTuples[len(m.ExchangeRateTuples)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Voter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Voter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipOracle(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOracle + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ExchangeRateTuple) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExchangeRateTuple: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExchangeRateTuple: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pair", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Pair.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExchangeRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ExchangeRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipOracle(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOracle + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DatedPrice) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DatedPrice: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DatedPrice: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExchangeRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ExchangeRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CreationHeight", wireType) + } + m.CreationHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CreationHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CreationTimeUnixMs", wireType) + } + m.CreationTimeUnixMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CreationTimeUnixMs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipOracle(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOracle + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Rewards) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Rewards: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Rewards: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VotePeriods", wireType) + } + m.VotePeriods = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VotePeriods |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Coins", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOracle + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthOracle + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthOracle + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Coins = append(m.Coins, types.Coin{}) + if err := m.Coins[len(m.Coins)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipOracle(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOracle + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipOracle(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowOracle + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowOracle + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowOracle + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthOracle + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupOracle + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthOracle + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthOracle = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowOracle = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupOracle = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/oracle/types/params.go b/x/oracle/types/params.go new file mode 100644 index 00000000..7e523d49 --- /dev/null +++ b/x/oracle/types/params.go @@ -0,0 +1,116 @@ +package types + +import ( + "fmt" + time "time" + + "cosmossdk.io/math" + + "github.com/archway-network/archway/x/oracle/asset" + "github.com/archway-network/archway/x/oracle/denoms" +) + +// Parameter keys +var ( + KeyVotePeriod = []byte("VotePeriod") + KeyVoteThreshold = []byte("VoteThreshold") + KeyMinVoters = []byte("MinVoters") + KeyRewardBand = []byte("RewardBand") + KeyWhitelist = []byte("Whitelist") + KeySlashFraction = []byte("SlashFraction") + KeySlashWindow = []byte("SlashWindow") + KeyMinValidPerWindow = []byte("MinValidPerWindow") + KeyTwapLookbackWindow = []byte("TwapLookbackWindow") + KeyValidatorFeeRatio = []byte("ValidatorFeeRatio") +) + +// Default parameter values +// Assumes block times are 6s +const ( + DefaultVotePeriod = 10 // vote every 1 minute + DefaultSlashWindow = 1200 // 2 hours + DefaultMinVoters = 4 // minimum of 4 voters for a pair to become valid + DefaultExpirationBlocks = 300 // 30 minutes +) + +// Default parameter values +var ( + DefaultVoteThreshold = math.LegacyOneDec().Quo(math.LegacyNewDec(3)) // 33.33% + DefaultRewardBand = math.LegacyNewDecWithPrec(2, 2) // 2% (-1, 1) + DefaultWhitelist = []asset.Pair{ + // paired against the US fiat dollar + asset.Registry.Pair(denoms.BTC, denoms.USD), + asset.Registry.Pair(denoms.ETH, denoms.USD), + asset.Registry.Pair(denoms.ATOM, denoms.USD), + asset.Registry.Pair(denoms.BNB, denoms.USD), + asset.Registry.Pair(denoms.USDC, denoms.USD), + asset.Registry.Pair(denoms.USDT, denoms.USD), + // asset.Registry.Pair(denoms.OSMO, denoms.USD), + // asset.Registry.Pair(denoms.AVAX, denoms.USD), + // asset.Registry.Pair(denoms.SOL, denoms.USD), + // asset.Registry.Pair(denoms.ADA, denoms.USD), + } + DefaultSlashFraction = math.LegacyNewDecWithPrec(5, 3) // 0.5% + DefaultMinValidPerWindow = math.LegacyNewDecWithPrec(69, 2) // 69% + DefaultTwapLookbackWindow = time.Duration(15 * time.Minute) // 15 minutes + DefaultValidatorFeeRatio = math.LegacyNewDecWithPrec(5, 2) // 0.05% +) + +// DefaultParams creates default oracle module parameters +func DefaultParams() Params { + return Params{ + VotePeriod: DefaultVotePeriod, + VoteThreshold: DefaultVoteThreshold, + MinVoters: DefaultMinVoters, + ExpirationBlocks: DefaultExpirationBlocks, + RewardBand: DefaultRewardBand, + Whitelist: DefaultWhitelist, + SlashFraction: DefaultSlashFraction, + SlashWindow: DefaultSlashWindow, + MinValidPerWindow: DefaultMinValidPerWindow, + TwapLookbackWindow: DefaultTwapLookbackWindow, + ValidatorFeeRatio: DefaultValidatorFeeRatio, + } +} + +// Validate performs basic validation on oracle parameters. +func (p Params) Validate() error { + if p.VotePeriod == 0 { + return fmt.Errorf("oracle parameter VotePeriod must be > 0, is %d", p.VotePeriod) + } + + if p.VoteThreshold.LTE(math.LegacyNewDecWithPrec(33, 2)) { + return fmt.Errorf("oracle parameter VoteThreshold must be greater than 33 percent") + } + + if p.MinVoters <= 0 { + return fmt.Errorf("oracle parameter MinVoters must be greater than 0") + } + + if p.RewardBand.GT(math.LegacyOneDec()) || p.RewardBand.IsNegative() { + return fmt.Errorf("oracle parameter RewardBand must be between [0, 1]") + } + + if p.SlashFraction.GT(math.LegacyOneDec()) || p.SlashFraction.IsNegative() { + return fmt.Errorf("oracle parameter SlashFraction must be between [0, 1]") + } + + if p.SlashWindow < p.VotePeriod { + return fmt.Errorf("oracle parameter SlashWindow must be greater than or equal with VotePeriod") + } + + if p.MinValidPerWindow.GT(math.LegacyOneDec()) || p.MinValidPerWindow.IsNegative() { + return fmt.Errorf("oracle parameter MinValidPerWindow must be between [0, 1]") + } + + if p.ValidatorFeeRatio.GT(math.LegacyOneDec()) || p.ValidatorFeeRatio.IsNegative() { + return fmt.Errorf("oracle parameter ValidatorFeeRatio must be between [0, 1]") + } + + for _, pair := range p.Whitelist { + if err := pair.Validate(); err != nil { + return fmt.Errorf("oracle parameter Whitelist Pair invalid format: %w", err) + } + } + return nil +} diff --git a/x/oracle/types/params_test.go b/x/oracle/types/params_test.go new file mode 100644 index 00000000..884307a9 --- /dev/null +++ b/x/oracle/types/params_test.go @@ -0,0 +1,76 @@ +package types_test + +import ( + "testing" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + "github.com/archway-network/archway/x/oracle/types" +) + +func TestParamsEqual(t *testing.T) { + p1 := types.DefaultParams() + err := p1.Validate() + require.NoError(t, err) + + // minus vote period + p1.VotePeriod = 0 + err = p1.Validate() + require.Error(t, err) + + p1.MinVoters = 0 + err = p1.Validate() + require.Error(t, err) + + // small vote threshold + p2 := types.DefaultParams() + p2.VoteThreshold = math.LegacyZeroDec() + err = p2.Validate() + require.Error(t, err) + + // negative reward band + p3 := types.DefaultParams() + p3.RewardBand = math.LegacyNewDecWithPrec(-1, 2) + err = p3.Validate() + require.Error(t, err) + + // negative slash fraction + p4 := types.DefaultParams() + p4.SlashFraction = math.LegacyNewDec(-1) + err = p4.Validate() + require.Error(t, err) + + // negative min valid per window + p5 := types.DefaultParams() + p5.MinValidPerWindow = math.LegacyNewDec(-1) + err = p5.Validate() + require.Error(t, err) + + // small slash window + p6 := types.DefaultParams() + p6.SlashWindow = 0 + err = p6.Validate() + require.Error(t, err) + + // empty name + p10 := types.DefaultParams() + p10.Whitelist[0] = "" + err = p10.Validate() + require.Error(t, err) + + // oracle fee ratio > 1 + p12 := types.DefaultParams() + p12.ValidatorFeeRatio = math.LegacyNewDec(2) + err = p12.Validate() + require.Error(t, err) + + // oracle fee ratio < 0 + p13 := types.DefaultParams() + p13.ValidatorFeeRatio = math.LegacyNewDec(-1) + err = p13.Validate() + require.Error(t, err) + + p11 := types.DefaultParams() + require.NotNil(t, p11.String()) +} diff --git a/x/oracle/types/query.pb.go b/x/oracle/types/query.pb.go new file mode 100644 index 00000000..8008f921 --- /dev/null +++ b/x/oracle/types/query.pb.go @@ -0,0 +1,4210 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: archway/oracle/v1/query.proto + +package types + +import ( + context "context" + cosmossdk_io_math "cosmossdk.io/math" + fmt "fmt" + github_com_archway_network_archway_x_oracle_asset "github.com/archway-network/archway/x/oracle/asset" + _ "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// QueryExchangeRateRequest is the request type for the Query/ExchangeRate RPC +// method. +type QueryExchangeRateRequest struct { + // pair defines the pair to query for. + Pair github_com_archway_network_archway_x_oracle_asset.Pair `protobuf:"bytes,1,opt,name=pair,proto3,customtype=github.com/archway-network/archway/x/oracle/asset.Pair" json:"pair"` +} + +func (m *QueryExchangeRateRequest) Reset() { *m = QueryExchangeRateRequest{} } +func (m *QueryExchangeRateRequest) String() string { return proto.CompactTextString(m) } +func (*QueryExchangeRateRequest) ProtoMessage() {} +func (*QueryExchangeRateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{0} +} +func (m *QueryExchangeRateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryExchangeRateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryExchangeRateRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryExchangeRateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryExchangeRateRequest.Merge(m, src) +} +func (m *QueryExchangeRateRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryExchangeRateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryExchangeRateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryExchangeRateRequest proto.InternalMessageInfo + +// QueryExchangeRateResponse is response type for the +// Query/ExchangeRate RPC method. +type QueryExchangeRateResponse struct { + // exchange_rate defines the exchange rate of assets voted by validators + ExchangeRate cosmossdk_io_math.LegacyDec `protobuf:"bytes,1,opt,name=exchange_rate,json=exchangeRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"exchange_rate"` +} + +func (m *QueryExchangeRateResponse) Reset() { *m = QueryExchangeRateResponse{} } +func (m *QueryExchangeRateResponse) String() string { return proto.CompactTextString(m) } +func (*QueryExchangeRateResponse) ProtoMessage() {} +func (*QueryExchangeRateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{1} +} +func (m *QueryExchangeRateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryExchangeRateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryExchangeRateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryExchangeRateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryExchangeRateResponse.Merge(m, src) +} +func (m *QueryExchangeRateResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryExchangeRateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryExchangeRateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryExchangeRateResponse proto.InternalMessageInfo + +// QueryExchangeRatesRequest is the request type for the Query/ExchangeRates RPC +// method. +type QueryExchangeRatesRequest struct { +} + +func (m *QueryExchangeRatesRequest) Reset() { *m = QueryExchangeRatesRequest{} } +func (m *QueryExchangeRatesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryExchangeRatesRequest) ProtoMessage() {} +func (*QueryExchangeRatesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{2} +} +func (m *QueryExchangeRatesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryExchangeRatesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryExchangeRatesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryExchangeRatesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryExchangeRatesRequest.Merge(m, src) +} +func (m *QueryExchangeRatesRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryExchangeRatesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryExchangeRatesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryExchangeRatesRequest proto.InternalMessageInfo + +// QueryExchangeRatesResponse is response type for the +// Query/ExchangeRates RPC method. +type QueryExchangeRatesResponse struct { + // exchange_rates defines a list of the exchange rate for all whitelisted + // pairs. + ExchangeRates ExchangeRateTuples `protobuf:"bytes,1,rep,name=exchange_rates,json=exchangeRates,proto3,castrepeated=ExchangeRateTuples" json:"exchange_rates"` +} + +func (m *QueryExchangeRatesResponse) Reset() { *m = QueryExchangeRatesResponse{} } +func (m *QueryExchangeRatesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryExchangeRatesResponse) ProtoMessage() {} +func (*QueryExchangeRatesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{3} +} +func (m *QueryExchangeRatesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryExchangeRatesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryExchangeRatesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryExchangeRatesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryExchangeRatesResponse.Merge(m, src) +} +func (m *QueryExchangeRatesResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryExchangeRatesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryExchangeRatesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryExchangeRatesResponse proto.InternalMessageInfo + +func (m *QueryExchangeRatesResponse) GetExchangeRates() ExchangeRateTuples { + if m != nil { + return m.ExchangeRates + } + return nil +} + +// QueryActivesRequest is the request type for the Query/Actives RPC method. +type QueryActivesRequest struct { +} + +func (m *QueryActivesRequest) Reset() { *m = QueryActivesRequest{} } +func (m *QueryActivesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryActivesRequest) ProtoMessage() {} +func (*QueryActivesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{4} +} +func (m *QueryActivesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryActivesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryActivesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryActivesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryActivesRequest.Merge(m, src) +} +func (m *QueryActivesRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryActivesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryActivesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryActivesRequest proto.InternalMessageInfo + +// QueryActivesResponse is response type for the +// Query/Actives RPC method. +type QueryActivesResponse struct { + // actives defines a list of the pair which oracle prices agreed upon. + Actives []github_com_archway_network_archway_x_oracle_asset.Pair `protobuf:"bytes,1,rep,name=actives,proto3,customtype=github.com/archway-network/archway/x/oracle/asset.Pair" json:"actives"` +} + +func (m *QueryActivesResponse) Reset() { *m = QueryActivesResponse{} } +func (m *QueryActivesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryActivesResponse) ProtoMessage() {} +func (*QueryActivesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{5} +} +func (m *QueryActivesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryActivesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryActivesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryActivesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryActivesResponse.Merge(m, src) +} +func (m *QueryActivesResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryActivesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryActivesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryActivesResponse proto.InternalMessageInfo + +// QueryVoteTargetsRequest is the request type for the Query/VoteTargets RPC +// method. +type QueryVoteTargetsRequest struct { +} + +func (m *QueryVoteTargetsRequest) Reset() { *m = QueryVoteTargetsRequest{} } +func (m *QueryVoteTargetsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryVoteTargetsRequest) ProtoMessage() {} +func (*QueryVoteTargetsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{6} +} +func (m *QueryVoteTargetsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryVoteTargetsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryVoteTargetsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryVoteTargetsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryVoteTargetsRequest.Merge(m, src) +} +func (m *QueryVoteTargetsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryVoteTargetsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryVoteTargetsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryVoteTargetsRequest proto.InternalMessageInfo + +// QueryVoteTargetsResponse is response type for the +// Query/VoteTargets RPC method. +type QueryVoteTargetsResponse struct { + // vote_targets defines a list of the pairs in which everyone + // should vote in the current vote period. + VoteTargets []github_com_archway_network_archway_x_oracle_asset.Pair `protobuf:"bytes,1,rep,name=vote_targets,json=voteTargets,proto3,customtype=github.com/archway-network/archway/x/oracle/asset.Pair" json:"vote_targets"` +} + +func (m *QueryVoteTargetsResponse) Reset() { *m = QueryVoteTargetsResponse{} } +func (m *QueryVoteTargetsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryVoteTargetsResponse) ProtoMessage() {} +func (*QueryVoteTargetsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{7} +} +func (m *QueryVoteTargetsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryVoteTargetsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryVoteTargetsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryVoteTargetsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryVoteTargetsResponse.Merge(m, src) +} +func (m *QueryVoteTargetsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryVoteTargetsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryVoteTargetsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryVoteTargetsResponse proto.InternalMessageInfo + +// QueryFeederDelegationRequest is the request type for the +// Query/FeederDelegation RPC method. +type QueryFeederDelegationRequest struct { + // validator defines the validator address to query for. + ValidatorAddr string `protobuf:"bytes,1,opt,name=validator_addr,json=validatorAddr,proto3" json:"validator_addr,omitempty"` +} + +func (m *QueryFeederDelegationRequest) Reset() { *m = QueryFeederDelegationRequest{} } +func (m *QueryFeederDelegationRequest) String() string { return proto.CompactTextString(m) } +func (*QueryFeederDelegationRequest) ProtoMessage() {} +func (*QueryFeederDelegationRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{8} +} +func (m *QueryFeederDelegationRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryFeederDelegationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryFeederDelegationRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryFeederDelegationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryFeederDelegationRequest.Merge(m, src) +} +func (m *QueryFeederDelegationRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryFeederDelegationRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryFeederDelegationRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryFeederDelegationRequest proto.InternalMessageInfo + +// QueryFeederDelegationResponse is response type for the +// Query/FeederDelegation RPC method. +type QueryFeederDelegationResponse struct { + // feeder_addr defines the feeder delegation of a validator + FeederAddr string `protobuf:"bytes,1,opt,name=feeder_addr,json=feederAddr,proto3" json:"feeder_addr,omitempty"` +} + +func (m *QueryFeederDelegationResponse) Reset() { *m = QueryFeederDelegationResponse{} } +func (m *QueryFeederDelegationResponse) String() string { return proto.CompactTextString(m) } +func (*QueryFeederDelegationResponse) ProtoMessage() {} +func (*QueryFeederDelegationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{9} +} +func (m *QueryFeederDelegationResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryFeederDelegationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryFeederDelegationResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryFeederDelegationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryFeederDelegationResponse.Merge(m, src) +} +func (m *QueryFeederDelegationResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryFeederDelegationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryFeederDelegationResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryFeederDelegationResponse proto.InternalMessageInfo + +func (m *QueryFeederDelegationResponse) GetFeederAddr() string { + if m != nil { + return m.FeederAddr + } + return "" +} + +// QueryMissCounterRequest is the request type for the Query/MissCounter RPC +// method. +type QueryMissCounterRequest struct { + // validator defines the validator address to query for. + ValidatorAddr string `protobuf:"bytes,1,opt,name=validator_addr,json=validatorAddr,proto3" json:"validator_addr,omitempty"` +} + +func (m *QueryMissCounterRequest) Reset() { *m = QueryMissCounterRequest{} } +func (m *QueryMissCounterRequest) String() string { return proto.CompactTextString(m) } +func (*QueryMissCounterRequest) ProtoMessage() {} +func (*QueryMissCounterRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{10} +} +func (m *QueryMissCounterRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryMissCounterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryMissCounterRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryMissCounterRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryMissCounterRequest.Merge(m, src) +} +func (m *QueryMissCounterRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryMissCounterRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryMissCounterRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryMissCounterRequest proto.InternalMessageInfo + +// QueryMissCounterResponse is response type for the +// Query/MissCounter RPC method. +type QueryMissCounterResponse struct { + // miss_counter defines the oracle miss counter of a validator + MissCounter uint64 `protobuf:"varint,1,opt,name=miss_counter,json=missCounter,proto3" json:"miss_counter,omitempty"` +} + +func (m *QueryMissCounterResponse) Reset() { *m = QueryMissCounterResponse{} } +func (m *QueryMissCounterResponse) String() string { return proto.CompactTextString(m) } +func (*QueryMissCounterResponse) ProtoMessage() {} +func (*QueryMissCounterResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{11} +} +func (m *QueryMissCounterResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryMissCounterResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryMissCounterResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryMissCounterResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryMissCounterResponse.Merge(m, src) +} +func (m *QueryMissCounterResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryMissCounterResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryMissCounterResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryMissCounterResponse proto.InternalMessageInfo + +func (m *QueryMissCounterResponse) GetMissCounter() uint64 { + if m != nil { + return m.MissCounter + } + return 0 +} + +// QueryAggregatePrevoteRequest is the request type for the +// Query/AggregatePrevote RPC method. +type QueryAggregatePrevoteRequest struct { + // validator defines the validator address to query for. + ValidatorAddr string `protobuf:"bytes,1,opt,name=validator_addr,json=validatorAddr,proto3" json:"validator_addr,omitempty"` +} + +func (m *QueryAggregatePrevoteRequest) Reset() { *m = QueryAggregatePrevoteRequest{} } +func (m *QueryAggregatePrevoteRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAggregatePrevoteRequest) ProtoMessage() {} +func (*QueryAggregatePrevoteRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{12} +} +func (m *QueryAggregatePrevoteRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAggregatePrevoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAggregatePrevoteRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAggregatePrevoteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAggregatePrevoteRequest.Merge(m, src) +} +func (m *QueryAggregatePrevoteRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAggregatePrevoteRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAggregatePrevoteRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAggregatePrevoteRequest proto.InternalMessageInfo + +// QueryAggregatePrevoteResponse is response type for the +// Query/AggregatePrevote RPC method. +type QueryAggregatePrevoteResponse struct { + // aggregate_prevote defines oracle aggregate prevote submitted by a validator + // in the current vote period + AggregatePrevote AggregateExchangeRatePrevote `protobuf:"bytes,1,opt,name=aggregate_prevote,json=aggregatePrevote,proto3" json:"aggregate_prevote"` +} + +func (m *QueryAggregatePrevoteResponse) Reset() { *m = QueryAggregatePrevoteResponse{} } +func (m *QueryAggregatePrevoteResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAggregatePrevoteResponse) ProtoMessage() {} +func (*QueryAggregatePrevoteResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{13} +} +func (m *QueryAggregatePrevoteResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAggregatePrevoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAggregatePrevoteResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAggregatePrevoteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAggregatePrevoteResponse.Merge(m, src) +} +func (m *QueryAggregatePrevoteResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAggregatePrevoteResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAggregatePrevoteResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAggregatePrevoteResponse proto.InternalMessageInfo + +func (m *QueryAggregatePrevoteResponse) GetAggregatePrevote() AggregateExchangeRatePrevote { + if m != nil { + return m.AggregatePrevote + } + return AggregateExchangeRatePrevote{} +} + +// QueryAggregatePrevotesRequest is the request type for the +// Query/AggregatePrevotes RPC method. +type QueryAggregatePrevotesRequest struct { +} + +func (m *QueryAggregatePrevotesRequest) Reset() { *m = QueryAggregatePrevotesRequest{} } +func (m *QueryAggregatePrevotesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAggregatePrevotesRequest) ProtoMessage() {} +func (*QueryAggregatePrevotesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{14} +} +func (m *QueryAggregatePrevotesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAggregatePrevotesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAggregatePrevotesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAggregatePrevotesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAggregatePrevotesRequest.Merge(m, src) +} +func (m *QueryAggregatePrevotesRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAggregatePrevotesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAggregatePrevotesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAggregatePrevotesRequest proto.InternalMessageInfo + +// QueryAggregatePrevotesResponse is response type for the +// Query/AggregatePrevotes RPC method. +type QueryAggregatePrevotesResponse struct { + // aggregate_prevotes defines all oracle aggregate prevotes submitted in the + // current vote period + AggregatePrevotes []AggregateExchangeRatePrevote `protobuf:"bytes,1,rep,name=aggregate_prevotes,json=aggregatePrevotes,proto3" json:"aggregate_prevotes"` +} + +func (m *QueryAggregatePrevotesResponse) Reset() { *m = QueryAggregatePrevotesResponse{} } +func (m *QueryAggregatePrevotesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAggregatePrevotesResponse) ProtoMessage() {} +func (*QueryAggregatePrevotesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{15} +} +func (m *QueryAggregatePrevotesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAggregatePrevotesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAggregatePrevotesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAggregatePrevotesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAggregatePrevotesResponse.Merge(m, src) +} +func (m *QueryAggregatePrevotesResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAggregatePrevotesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAggregatePrevotesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAggregatePrevotesResponse proto.InternalMessageInfo + +func (m *QueryAggregatePrevotesResponse) GetAggregatePrevotes() []AggregateExchangeRatePrevote { + if m != nil { + return m.AggregatePrevotes + } + return nil +} + +// QueryAggregateVoteRequest is the request type for the Query/AggregateVote RPC +// method. +type QueryAggregateVoteRequest struct { + // validator defines the validator address to query for. + ValidatorAddr string `protobuf:"bytes,1,opt,name=validator_addr,json=validatorAddr,proto3" json:"validator_addr,omitempty"` +} + +func (m *QueryAggregateVoteRequest) Reset() { *m = QueryAggregateVoteRequest{} } +func (m *QueryAggregateVoteRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAggregateVoteRequest) ProtoMessage() {} +func (*QueryAggregateVoteRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{16} +} +func (m *QueryAggregateVoteRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAggregateVoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAggregateVoteRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAggregateVoteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAggregateVoteRequest.Merge(m, src) +} +func (m *QueryAggregateVoteRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAggregateVoteRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAggregateVoteRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAggregateVoteRequest proto.InternalMessageInfo + +// QueryAggregateVoteResponse is response type for the +// Query/AggregateVote RPC method. +type QueryAggregateVoteResponse struct { + // aggregate_vote defines oracle aggregate vote submitted by a validator in + // the current vote period + AggregateVote AggregateExchangeRateVote `protobuf:"bytes,1,opt,name=aggregate_vote,json=aggregateVote,proto3" json:"aggregate_vote"` +} + +func (m *QueryAggregateVoteResponse) Reset() { *m = QueryAggregateVoteResponse{} } +func (m *QueryAggregateVoteResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAggregateVoteResponse) ProtoMessage() {} +func (*QueryAggregateVoteResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{17} +} +func (m *QueryAggregateVoteResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAggregateVoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAggregateVoteResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAggregateVoteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAggregateVoteResponse.Merge(m, src) +} +func (m *QueryAggregateVoteResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAggregateVoteResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAggregateVoteResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAggregateVoteResponse proto.InternalMessageInfo + +func (m *QueryAggregateVoteResponse) GetAggregateVote() AggregateExchangeRateVote { + if m != nil { + return m.AggregateVote + } + return AggregateExchangeRateVote{} +} + +// QueryAggregateVotesRequest is the request type for the Query/AggregateVotes +// RPC method. +type QueryAggregateVotesRequest struct { +} + +func (m *QueryAggregateVotesRequest) Reset() { *m = QueryAggregateVotesRequest{} } +func (m *QueryAggregateVotesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAggregateVotesRequest) ProtoMessage() {} +func (*QueryAggregateVotesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{18} +} +func (m *QueryAggregateVotesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAggregateVotesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAggregateVotesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAggregateVotesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAggregateVotesRequest.Merge(m, src) +} +func (m *QueryAggregateVotesRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAggregateVotesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAggregateVotesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAggregateVotesRequest proto.InternalMessageInfo + +// QueryAggregateVotesResponse is response type for the +// Query/AggregateVotes RPC method. +type QueryAggregateVotesResponse struct { + // aggregate_votes defines all oracle aggregate votes submitted in the current + // vote period + AggregateVotes []AggregateExchangeRateVote `protobuf:"bytes,1,rep,name=aggregate_votes,json=aggregateVotes,proto3" json:"aggregate_votes"` +} + +func (m *QueryAggregateVotesResponse) Reset() { *m = QueryAggregateVotesResponse{} } +func (m *QueryAggregateVotesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAggregateVotesResponse) ProtoMessage() {} +func (*QueryAggregateVotesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{19} +} +func (m *QueryAggregateVotesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAggregateVotesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAggregateVotesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAggregateVotesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAggregateVotesResponse.Merge(m, src) +} +func (m *QueryAggregateVotesResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAggregateVotesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAggregateVotesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAggregateVotesResponse proto.InternalMessageInfo + +func (m *QueryAggregateVotesResponse) GetAggregateVotes() []AggregateExchangeRateVote { + if m != nil { + return m.AggregateVotes + } + return nil +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{20} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + // params defines the parameters of the module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ba0ccf1ab668bdde, []int{21} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func init() { + proto.RegisterType((*QueryExchangeRateRequest)(nil), "archway.oracle.v1.QueryExchangeRateRequest") + proto.RegisterType((*QueryExchangeRateResponse)(nil), "archway.oracle.v1.QueryExchangeRateResponse") + proto.RegisterType((*QueryExchangeRatesRequest)(nil), "archway.oracle.v1.QueryExchangeRatesRequest") + proto.RegisterType((*QueryExchangeRatesResponse)(nil), "archway.oracle.v1.QueryExchangeRatesResponse") + proto.RegisterType((*QueryActivesRequest)(nil), "archway.oracle.v1.QueryActivesRequest") + proto.RegisterType((*QueryActivesResponse)(nil), "archway.oracle.v1.QueryActivesResponse") + proto.RegisterType((*QueryVoteTargetsRequest)(nil), "archway.oracle.v1.QueryVoteTargetsRequest") + proto.RegisterType((*QueryVoteTargetsResponse)(nil), "archway.oracle.v1.QueryVoteTargetsResponse") + proto.RegisterType((*QueryFeederDelegationRequest)(nil), "archway.oracle.v1.QueryFeederDelegationRequest") + proto.RegisterType((*QueryFeederDelegationResponse)(nil), "archway.oracle.v1.QueryFeederDelegationResponse") + proto.RegisterType((*QueryMissCounterRequest)(nil), "archway.oracle.v1.QueryMissCounterRequest") + proto.RegisterType((*QueryMissCounterResponse)(nil), "archway.oracle.v1.QueryMissCounterResponse") + proto.RegisterType((*QueryAggregatePrevoteRequest)(nil), "archway.oracle.v1.QueryAggregatePrevoteRequest") + proto.RegisterType((*QueryAggregatePrevoteResponse)(nil), "archway.oracle.v1.QueryAggregatePrevoteResponse") + proto.RegisterType((*QueryAggregatePrevotesRequest)(nil), "archway.oracle.v1.QueryAggregatePrevotesRequest") + proto.RegisterType((*QueryAggregatePrevotesResponse)(nil), "archway.oracle.v1.QueryAggregatePrevotesResponse") + proto.RegisterType((*QueryAggregateVoteRequest)(nil), "archway.oracle.v1.QueryAggregateVoteRequest") + proto.RegisterType((*QueryAggregateVoteResponse)(nil), "archway.oracle.v1.QueryAggregateVoteResponse") + proto.RegisterType((*QueryAggregateVotesRequest)(nil), "archway.oracle.v1.QueryAggregateVotesRequest") + proto.RegisterType((*QueryAggregateVotesResponse)(nil), "archway.oracle.v1.QueryAggregateVotesResponse") + proto.RegisterType((*QueryParamsRequest)(nil), "archway.oracle.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "archway.oracle.v1.QueryParamsResponse") +} + +func init() { proto.RegisterFile("archway/oracle/v1/query.proto", fileDescriptor_ba0ccf1ab668bdde) } + +var fileDescriptor_ba0ccf1ab668bdde = []byte{ + // 1111 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x97, 0x4f, 0x6f, 0x1b, 0xc5, + 0x1b, 0xc7, 0x3d, 0xbf, 0x5f, 0x48, 0x61, 0x1c, 0xbb, 0xc9, 0x10, 0x44, 0xb2, 0x49, 0xed, 0xb0, + 0x90, 0xb4, 0x6a, 0x93, 0x5d, 0x6c, 0x0a, 0x45, 0x11, 0x45, 0x8d, 0x49, 0x01, 0x95, 0x16, 0x82, + 0x55, 0x45, 0xfc, 0x39, 0x58, 0xe3, 0xf5, 0xb0, 0x59, 0xd5, 0xf6, 0x6c, 0x77, 0xc6, 0x4e, 0x02, + 0xaa, 0x90, 0x40, 0x20, 0xb8, 0x21, 0x71, 0x41, 0x9c, 0x0a, 0x27, 0x04, 0x2f, 0x00, 0xb8, 0x73, + 0xe8, 0xb1, 0x12, 0x17, 0xc4, 0xa1, 0xa0, 0x04, 0x21, 0x5e, 0x06, 0xda, 0xd9, 0xf1, 0x7a, 0xd7, + 0xbb, 0x43, 0x36, 0x2e, 0xdc, 0x92, 0x79, 0x9e, 0x7d, 0x9e, 0xcf, 0xf3, 0x9d, 0xd9, 0xf9, 0x7a, + 0xe1, 0x29, 0xec, 0x59, 0x3b, 0xbb, 0x78, 0xdf, 0xa4, 0x1e, 0xb6, 0xda, 0xc4, 0xec, 0x57, 0xcc, + 0x9b, 0x3d, 0xe2, 0xed, 0x1b, 0xae, 0x47, 0x39, 0x45, 0x33, 0x32, 0x6c, 0x04, 0x61, 0xa3, 0x5f, + 0xd1, 0x66, 0x6d, 0x6a, 0x53, 0x11, 0x35, 0xfd, 0xbf, 0x82, 0x44, 0x6d, 0xd1, 0xa6, 0xd4, 0x6e, + 0x13, 0x13, 0xbb, 0x8e, 0x89, 0xbb, 0x5d, 0xca, 0x31, 0x77, 0x68, 0x97, 0xc9, 0x68, 0x29, 0xd9, + 0x45, 0x16, 0x94, 0x71, 0x8b, 0xb2, 0x0e, 0x65, 0x66, 0x13, 0x33, 0x3f, 0xd8, 0x24, 0x1c, 0x57, + 0x4c, 0x8b, 0x3a, 0xdd, 0x20, 0xae, 0xef, 0xc1, 0xb9, 0xd7, 0x7d, 0xaa, 0xcb, 0x7b, 0xd6, 0x0e, + 0xee, 0xda, 0xa4, 0x8e, 0x39, 0xa9, 0x93, 0x9b, 0x3d, 0xc2, 0x38, 0xaa, 0xc3, 0x09, 0x17, 0x3b, + 0xde, 0x1c, 0x58, 0x02, 0x67, 0x1e, 0xaa, 0x3d, 0x7f, 0xe7, 0x5e, 0x39, 0xf7, 0xeb, 0xbd, 0xf2, + 0x33, 0xb6, 0xc3, 0x77, 0x7a, 0x4d, 0xc3, 0xa2, 0x1d, 0x53, 0x36, 0x5f, 0xeb, 0x12, 0xbe, 0x4b, + 0xbd, 0x1b, 0x83, 0xff, 0xcd, 0xbd, 0x01, 0x0e, 0x66, 0x8c, 0x70, 0x63, 0x0b, 0x3b, 0x5e, 0x5d, + 0xd4, 0x5a, 0x7f, 0xf0, 0x93, 0xdb, 0xe5, 0xdc, 0x5f, 0xb7, 0xcb, 0x39, 0x9d, 0xc0, 0xf9, 0x94, + 0xce, 0xcc, 0xa5, 0x5d, 0x46, 0xd0, 0xcb, 0xb0, 0x40, 0xe4, 0x7a, 0xc3, 0xc3, 0x9c, 0x48, 0x86, + 0xc7, 0x25, 0xc3, 0x42, 0x30, 0x15, 0x6b, 0xdd, 0x30, 0x1c, 0x6a, 0x76, 0x30, 0xdf, 0x31, 0xae, + 0x12, 0x1b, 0x5b, 0xfb, 0x9b, 0xc4, 0xaa, 0x4f, 0x91, 0x48, 0x45, 0x7d, 0x21, 0xa5, 0x0d, 0x93, + 0x13, 0xea, 0x1f, 0x01, 0xa8, 0xa5, 0x45, 0x25, 0x85, 0x0d, 0x8b, 0x31, 0x0a, 0x36, 0x07, 0x96, + 0xfe, 0x7f, 0x26, 0x5f, 0x7d, 0xc2, 0x48, 0x6c, 0x9e, 0x11, 0xad, 0x70, 0xbd, 0xe7, 0xb6, 0x49, + 0x4d, 0xf3, 0x61, 0xbf, 0xfd, 0xad, 0x8c, 0x12, 0x21, 0x56, 0x2f, 0x44, 0x19, 0x99, 0xfe, 0x08, + 0x7c, 0x58, 0x60, 0x6c, 0x58, 0xdc, 0xe9, 0x0f, 0xf1, 0x5c, 0x38, 0x1b, 0x5f, 0x96, 0x5c, 0x6f, + 0xc0, 0x13, 0x38, 0x58, 0x12, 0x40, 0xf7, 0xbf, 0x37, 0x83, 0x72, 0xfa, 0x3c, 0x7c, 0x54, 0x74, + 0xdc, 0xa6, 0x9c, 0x5c, 0xc7, 0x9e, 0x4d, 0x78, 0x08, 0x73, 0x4b, 0x9e, 0x94, 0x58, 0x48, 0x02, + 0x61, 0x38, 0xd5, 0xa7, 0x9c, 0x34, 0x78, 0xb0, 0xfe, 0x2f, 0x51, 0xe5, 0xfb, 0xc3, 0x56, 0xfa, + 0x6b, 0x70, 0x51, 0xb4, 0x7f, 0x91, 0x90, 0x16, 0xf1, 0x36, 0x49, 0x9b, 0xd8, 0xe2, 0x45, 0x18, + 0x1c, 0xd6, 0x65, 0x58, 0xec, 0xe3, 0xb6, 0xd3, 0xc2, 0x9c, 0x7a, 0x0d, 0xdc, 0x6a, 0xc9, 0x63, + 0x5b, 0x2f, 0x84, 0xab, 0x1b, 0xad, 0x56, 0xf4, 0xfc, 0x5d, 0x82, 0xa7, 0x14, 0x05, 0xe5, 0x50, + 0x65, 0x98, 0x7f, 0x47, 0xc4, 0xa2, 0xe5, 0x60, 0xb0, 0xe4, 0xd7, 0xd2, 0xaf, 0x48, 0xb1, 0xae, + 0x39, 0x8c, 0xbd, 0x40, 0x7b, 0x5d, 0x4e, 0xbc, 0xb1, 0x69, 0x2e, 0x4a, 0x75, 0x63, 0xb5, 0x24, + 0xc8, 0x63, 0x70, 0xaa, 0xe3, 0x30, 0xd6, 0xb0, 0x82, 0x75, 0x51, 0x6a, 0xa2, 0x9e, 0xef, 0x0c, + 0x53, 0x43, 0x75, 0x36, 0x6c, 0xdb, 0xf3, 0xe7, 0x20, 0x5b, 0x1e, 0xf1, 0xd5, 0x1b, 0x9b, 0xe7, + 0x43, 0x20, 0xe5, 0x49, 0x56, 0x94, 0x54, 0x4d, 0x38, 0x83, 0x07, 0xb1, 0x86, 0x1b, 0x04, 0x45, + 0xd5, 0x7c, 0xd5, 0x4c, 0x79, 0x3f, 0xc2, 0x3a, 0xd1, 0xb7, 0x41, 0xd6, 0xac, 0x4d, 0xf8, 0x27, + 0xa5, 0x3e, 0x8d, 0x47, 0x7a, 0xe9, 0x65, 0x05, 0x44, 0x78, 0x28, 0x3f, 0x06, 0xb0, 0xa4, 0xca, + 0x90, 0x9c, 0x2d, 0x88, 0x12, 0x9c, 0x83, 0x17, 0x79, 0x4c, 0xd0, 0x99, 0x51, 0x50, 0xa6, 0x5f, + 0x95, 0xd7, 0x4c, 0xf8, 0xf4, 0xf6, 0xfd, 0xa8, 0xbf, 0x2b, 0xaf, 0xa5, 0x91, 0x6a, 0x72, 0xa2, + 0x37, 0x61, 0x71, 0x38, 0x51, 0x44, 0xf6, 0xd5, 0xac, 0xd3, 0x6c, 0x0f, 0x47, 0x29, 0xe0, 0x68, + 0x0b, 0x7d, 0x31, 0xad, 0x71, 0xa8, 0xf6, 0xbb, 0x70, 0x21, 0x35, 0x2a, 0xb9, 0xde, 0x86, 0x27, + 0xe3, 0x5c, 0x03, 0x99, 0xc7, 0x01, 0x2b, 0xc6, 0xc0, 0x98, 0x3e, 0x0b, 0x91, 0xe8, 0xbd, 0x85, + 0x3d, 0xdc, 0x09, 0x89, 0x5e, 0x95, 0x17, 0xe7, 0x60, 0x55, 0x92, 0x5c, 0x80, 0x93, 0xae, 0x58, + 0x91, 0xca, 0xcc, 0xa7, 0x00, 0x04, 0x8f, 0xc8, 0x6e, 0x32, 0xbd, 0xfa, 0xe7, 0x49, 0xf8, 0x80, + 0x28, 0x88, 0xbe, 0x00, 0x70, 0x2a, 0x8a, 0x86, 0xce, 0xa5, 0xd4, 0x50, 0x59, 0xa7, 0xb6, 0x9a, + 0x2d, 0x39, 0xc0, 0xd5, 0xd7, 0x3e, 0xf8, 0xf9, 0x8f, 0xcf, 0xff, 0x77, 0x1a, 0x2d, 0x9b, 0x09, + 0x37, 0x0f, 0x0c, 0x3b, 0xe6, 0x42, 0xe8, 0x2b, 0x00, 0xa7, 0x63, 0x9e, 0xb2, 0x8b, 0xdd, 0xff, + 0x12, 0xaf, 0x2a, 0xf0, 0x56, 0xd1, 0xd9, 0x4c, 0x78, 0x0d, 0xee, 0xe3, 0x7c, 0x0d, 0x60, 0x21, + 0x66, 0xaa, 0x28, 0x53, 0xcf, 0xc1, 0xc6, 0x6a, 0x6b, 0x19, 0xb3, 0x25, 0xe2, 0x79, 0x81, 0x68, + 0xa0, 0x55, 0x15, 0xa2, 0xff, 0xe3, 0x83, 0xc5, 0x41, 0x19, 0xfa, 0x14, 0xc0, 0x13, 0xd2, 0x5b, + 0xd1, 0x8a, 0xaa, 0x61, 0xdc, 0x93, 0xb5, 0xd3, 0x47, 0xe6, 0x65, 0xdd, 0xd4, 0x00, 0x49, 0x3a, + 0x2f, 0xfa, 0x12, 0xc0, 0x7c, 0xc4, 0x5a, 0xd1, 0x59, 0x55, 0x9f, 0xa4, 0x35, 0x6b, 0xe7, 0x32, + 0xe5, 0x66, 0xdd, 0xcd, 0x80, 0x2b, 0xea, 0xe7, 0xe8, 0x47, 0x00, 0xa7, 0x47, 0x7d, 0x12, 0x99, + 0xaa, 0xae, 0x0a, 0x8b, 0xd6, 0x9e, 0xcc, 0xfe, 0x80, 0x64, 0xad, 0x09, 0xd6, 0xe7, 0xd0, 0xba, + 0x8a, 0x35, 0xbc, 0x40, 0x99, 0xf9, 0x5e, 0xfc, 0x8a, 0xbd, 0x65, 0x06, 0x4e, 0x8d, 0xbe, 0x01, + 0x30, 0x1f, 0x71, 0x55, 0xb5, 0xb0, 0x49, 0x1b, 0x57, 0x0b, 0x9b, 0x62, 0xd3, 0xfa, 0x25, 0x01, + 0xbb, 0x8e, 0x9e, 0x1d, 0x07, 0xd6, 0x37, 0x73, 0xf4, 0x13, 0x80, 0xd3, 0xa3, 0x46, 0xa6, 0x96, + 0x59, 0xe1, 0xf5, 0x6a, 0x99, 0x55, 0x56, 0xae, 0x5f, 0x13, 0xe4, 0x2f, 0xa1, 0xcb, 0xe3, 0x90, + 0x27, 0xcc, 0x15, 0x7d, 0x0f, 0xe0, 0x4c, 0xc2, 0x8f, 0x51, 0x66, 0xac, 0xf0, 0x58, 0x57, 0x8e, + 0xf1, 0x84, 0x9c, 0xe4, 0xa2, 0x98, 0xe4, 0x02, 0x7a, 0x3a, 0xc3, 0x24, 0xc9, 0x5f, 0x05, 0xe8, + 0x07, 0x00, 0x0b, 0x31, 0x73, 0x53, 0xdf, 0x5a, 0x69, 0x46, 0xaf, 0xbe, 0xb5, 0x52, 0x8d, 0x5c, + 0xbf, 0x22, 0x68, 0x37, 0x51, 0xed, 0x1f, 0x68, 0x5b, 0xce, 0x91, 0xba, 0x0b, 0xd1, 0xbf, 0x03, + 0xb0, 0x18, 0xf7, 0x65, 0x94, 0x8d, 0x26, 0x94, 0xdb, 0xc8, 0x9a, 0x2e, 0xe9, 0xd7, 0x05, 0xfd, + 0x79, 0x54, 0x3d, 0x96, 0xd6, 0x81, 0xd0, 0xef, 0xc3, 0xc9, 0xc0, 0x7f, 0xd1, 0xb2, 0xaa, 0x6b, + 0xcc, 0xe8, 0xb5, 0x95, 0xa3, 0xd2, 0x24, 0xd4, 0x8a, 0x80, 0x5a, 0x42, 0x25, 0xf5, 0xed, 0x26, + 0x6c, 0xff, 0x95, 0x3b, 0x07, 0x25, 0x70, 0xf7, 0xa0, 0x04, 0x7e, 0x3f, 0x28, 0x81, 0xcf, 0x0e, + 0x4b, 0xb9, 0xbb, 0x87, 0xa5, 0xdc, 0x2f, 0x87, 0xa5, 0xdc, 0x5b, 0x95, 0xe3, 0x7c, 0xad, 0xf0, + 0x7d, 0x97, 0xb0, 0xe6, 0xa4, 0xf8, 0x96, 0x7e, 0xea, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7d, + 0x3e, 0x75, 0x84, 0xf3, 0x0f, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // ExchangeRate returns exchange rate of a pair + ExchangeRate(ctx context.Context, in *QueryExchangeRateRequest, opts ...grpc.CallOption) (*QueryExchangeRateResponse, error) + // ExchangeRateTwap returns twap exchange rate of a pair + ExchangeRateTwap(ctx context.Context, in *QueryExchangeRateRequest, opts ...grpc.CallOption) (*QueryExchangeRateResponse, error) + // ExchangeRates returns exchange rates of all pairs + ExchangeRates(ctx context.Context, in *QueryExchangeRatesRequest, opts ...grpc.CallOption) (*QueryExchangeRatesResponse, error) + // Actives returns all active pairs + Actives(ctx context.Context, in *QueryActivesRequest, opts ...grpc.CallOption) (*QueryActivesResponse, error) + // VoteTargets returns all vote target for pairs + VoteTargets(ctx context.Context, in *QueryVoteTargetsRequest, opts ...grpc.CallOption) (*QueryVoteTargetsResponse, error) + // FeederDelegation returns feeder delegation of a validator + FeederDelegation(ctx context.Context, in *QueryFeederDelegationRequest, opts ...grpc.CallOption) (*QueryFeederDelegationResponse, error) + // MissCounter returns oracle miss counter of a validator + MissCounter(ctx context.Context, in *QueryMissCounterRequest, opts ...grpc.CallOption) (*QueryMissCounterResponse, error) + // AggregatePrevote returns an aggregate prevote of a validator + AggregatePrevote(ctx context.Context, in *QueryAggregatePrevoteRequest, opts ...grpc.CallOption) (*QueryAggregatePrevoteResponse, error) + // AggregatePrevotes returns aggregate prevotes of all validators + AggregatePrevotes(ctx context.Context, in *QueryAggregatePrevotesRequest, opts ...grpc.CallOption) (*QueryAggregatePrevotesResponse, error) + // AggregateVote returns an aggregate vote of a validator + AggregateVote(ctx context.Context, in *QueryAggregateVoteRequest, opts ...grpc.CallOption) (*QueryAggregateVoteResponse, error) + // AggregateVotes returns aggregate votes of all validators + AggregateVotes(ctx context.Context, in *QueryAggregateVotesRequest, opts ...grpc.CallOption) (*QueryAggregateVotesResponse, error) + // Params queries all parameters. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) ExchangeRate(ctx context.Context, in *QueryExchangeRateRequest, opts ...grpc.CallOption) (*QueryExchangeRateResponse, error) { + out := new(QueryExchangeRateResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/ExchangeRate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ExchangeRateTwap(ctx context.Context, in *QueryExchangeRateRequest, opts ...grpc.CallOption) (*QueryExchangeRateResponse, error) { + out := new(QueryExchangeRateResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/ExchangeRateTwap", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ExchangeRates(ctx context.Context, in *QueryExchangeRatesRequest, opts ...grpc.CallOption) (*QueryExchangeRatesResponse, error) { + out := new(QueryExchangeRatesResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/ExchangeRates", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Actives(ctx context.Context, in *QueryActivesRequest, opts ...grpc.CallOption) (*QueryActivesResponse, error) { + out := new(QueryActivesResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/Actives", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) VoteTargets(ctx context.Context, in *QueryVoteTargetsRequest, opts ...grpc.CallOption) (*QueryVoteTargetsResponse, error) { + out := new(QueryVoteTargetsResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/VoteTargets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) FeederDelegation(ctx context.Context, in *QueryFeederDelegationRequest, opts ...grpc.CallOption) (*QueryFeederDelegationResponse, error) { + out := new(QueryFeederDelegationResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/FeederDelegation", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) MissCounter(ctx context.Context, in *QueryMissCounterRequest, opts ...grpc.CallOption) (*QueryMissCounterResponse, error) { + out := new(QueryMissCounterResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/MissCounter", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AggregatePrevote(ctx context.Context, in *QueryAggregatePrevoteRequest, opts ...grpc.CallOption) (*QueryAggregatePrevoteResponse, error) { + out := new(QueryAggregatePrevoteResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/AggregatePrevote", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AggregatePrevotes(ctx context.Context, in *QueryAggregatePrevotesRequest, opts ...grpc.CallOption) (*QueryAggregatePrevotesResponse, error) { + out := new(QueryAggregatePrevotesResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/AggregatePrevotes", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AggregateVote(ctx context.Context, in *QueryAggregateVoteRequest, opts ...grpc.CallOption) (*QueryAggregateVoteResponse, error) { + out := new(QueryAggregateVoteResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/AggregateVote", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AggregateVotes(ctx context.Context, in *QueryAggregateVotesRequest, opts ...grpc.CallOption) (*QueryAggregateVotesResponse, error) { + out := new(QueryAggregateVotesResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/AggregateVotes", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // ExchangeRate returns exchange rate of a pair + ExchangeRate(context.Context, *QueryExchangeRateRequest) (*QueryExchangeRateResponse, error) + // ExchangeRateTwap returns twap exchange rate of a pair + ExchangeRateTwap(context.Context, *QueryExchangeRateRequest) (*QueryExchangeRateResponse, error) + // ExchangeRates returns exchange rates of all pairs + ExchangeRates(context.Context, *QueryExchangeRatesRequest) (*QueryExchangeRatesResponse, error) + // Actives returns all active pairs + Actives(context.Context, *QueryActivesRequest) (*QueryActivesResponse, error) + // VoteTargets returns all vote target for pairs + VoteTargets(context.Context, *QueryVoteTargetsRequest) (*QueryVoteTargetsResponse, error) + // FeederDelegation returns feeder delegation of a validator + FeederDelegation(context.Context, *QueryFeederDelegationRequest) (*QueryFeederDelegationResponse, error) + // MissCounter returns oracle miss counter of a validator + MissCounter(context.Context, *QueryMissCounterRequest) (*QueryMissCounterResponse, error) + // AggregatePrevote returns an aggregate prevote of a validator + AggregatePrevote(context.Context, *QueryAggregatePrevoteRequest) (*QueryAggregatePrevoteResponse, error) + // AggregatePrevotes returns aggregate prevotes of all validators + AggregatePrevotes(context.Context, *QueryAggregatePrevotesRequest) (*QueryAggregatePrevotesResponse, error) + // AggregateVote returns an aggregate vote of a validator + AggregateVote(context.Context, *QueryAggregateVoteRequest) (*QueryAggregateVoteResponse, error) + // AggregateVotes returns aggregate votes of all validators + AggregateVotes(context.Context, *QueryAggregateVotesRequest) (*QueryAggregateVotesResponse, error) + // Params queries all parameters. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) ExchangeRate(ctx context.Context, req *QueryExchangeRateRequest) (*QueryExchangeRateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExchangeRate not implemented") +} +func (*UnimplementedQueryServer) ExchangeRateTwap(ctx context.Context, req *QueryExchangeRateRequest) (*QueryExchangeRateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExchangeRateTwap not implemented") +} +func (*UnimplementedQueryServer) ExchangeRates(ctx context.Context, req *QueryExchangeRatesRequest) (*QueryExchangeRatesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExchangeRates not implemented") +} +func (*UnimplementedQueryServer) Actives(ctx context.Context, req *QueryActivesRequest) (*QueryActivesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Actives not implemented") +} +func (*UnimplementedQueryServer) VoteTargets(ctx context.Context, req *QueryVoteTargetsRequest) (*QueryVoteTargetsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VoteTargets not implemented") +} +func (*UnimplementedQueryServer) FeederDelegation(ctx context.Context, req *QueryFeederDelegationRequest) (*QueryFeederDelegationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FeederDelegation not implemented") +} +func (*UnimplementedQueryServer) MissCounter(ctx context.Context, req *QueryMissCounterRequest) (*QueryMissCounterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MissCounter not implemented") +} +func (*UnimplementedQueryServer) AggregatePrevote(ctx context.Context, req *QueryAggregatePrevoteRequest) (*QueryAggregatePrevoteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AggregatePrevote not implemented") +} +func (*UnimplementedQueryServer) AggregatePrevotes(ctx context.Context, req *QueryAggregatePrevotesRequest) (*QueryAggregatePrevotesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AggregatePrevotes not implemented") +} +func (*UnimplementedQueryServer) AggregateVote(ctx context.Context, req *QueryAggregateVoteRequest) (*QueryAggregateVoteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AggregateVote not implemented") +} +func (*UnimplementedQueryServer) AggregateVotes(ctx context.Context, req *QueryAggregateVotesRequest) (*QueryAggregateVotesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AggregateVotes not implemented") +} +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_ExchangeRate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryExchangeRateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ExchangeRate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/ExchangeRate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ExchangeRate(ctx, req.(*QueryExchangeRateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ExchangeRateTwap_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryExchangeRateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ExchangeRateTwap(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/ExchangeRateTwap", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ExchangeRateTwap(ctx, req.(*QueryExchangeRateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ExchangeRates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryExchangeRatesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ExchangeRates(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/ExchangeRates", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ExchangeRates(ctx, req.(*QueryExchangeRatesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Actives_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryActivesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Actives(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/Actives", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Actives(ctx, req.(*QueryActivesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_VoteTargets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryVoteTargetsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).VoteTargets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/VoteTargets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).VoteTargets(ctx, req.(*QueryVoteTargetsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_FeederDelegation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryFeederDelegationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).FeederDelegation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/FeederDelegation", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).FeederDelegation(ctx, req.(*QueryFeederDelegationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_MissCounter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryMissCounterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).MissCounter(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/MissCounter", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).MissCounter(ctx, req.(*QueryMissCounterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AggregatePrevote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAggregatePrevoteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AggregatePrevote(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/AggregatePrevote", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AggregatePrevote(ctx, req.(*QueryAggregatePrevoteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AggregatePrevotes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAggregatePrevotesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AggregatePrevotes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/AggregatePrevotes", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AggregatePrevotes(ctx, req.(*QueryAggregatePrevotesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AggregateVote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAggregateVoteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AggregateVote(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/AggregateVote", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AggregateVote(ctx, req.(*QueryAggregateVoteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AggregateVotes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAggregateVotesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AggregateVotes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/AggregateVotes", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AggregateVotes(ctx, req.(*QueryAggregateVotesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "archway.oracle.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ExchangeRate", + Handler: _Query_ExchangeRate_Handler, + }, + { + MethodName: "ExchangeRateTwap", + Handler: _Query_ExchangeRateTwap_Handler, + }, + { + MethodName: "ExchangeRates", + Handler: _Query_ExchangeRates_Handler, + }, + { + MethodName: "Actives", + Handler: _Query_Actives_Handler, + }, + { + MethodName: "VoteTargets", + Handler: _Query_VoteTargets_Handler, + }, + { + MethodName: "FeederDelegation", + Handler: _Query_FeederDelegation_Handler, + }, + { + MethodName: "MissCounter", + Handler: _Query_MissCounter_Handler, + }, + { + MethodName: "AggregatePrevote", + Handler: _Query_AggregatePrevote_Handler, + }, + { + MethodName: "AggregatePrevotes", + Handler: _Query_AggregatePrevotes_Handler, + }, + { + MethodName: "AggregateVote", + Handler: _Query_AggregateVote_Handler, + }, + { + MethodName: "AggregateVotes", + Handler: _Query_AggregateVotes_Handler, + }, + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "archway/oracle/v1/query.proto", +} + +func (m *QueryExchangeRateRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryExchangeRateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryExchangeRateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.Pair.Size() + i -= size + if _, err := m.Pair.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryExchangeRateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryExchangeRateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryExchangeRateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.ExchangeRate.Size() + i -= size + if _, err := m.ExchangeRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryExchangeRatesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryExchangeRatesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryExchangeRatesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryExchangeRatesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryExchangeRatesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryExchangeRatesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ExchangeRates) > 0 { + for iNdEx := len(m.ExchangeRates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ExchangeRates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryActivesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryActivesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryActivesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryActivesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryActivesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryActivesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Actives) > 0 { + for iNdEx := len(m.Actives) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.Actives[iNdEx].Size() + i -= size + if _, err := m.Actives[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryVoteTargetsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryVoteTargetsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryVoteTargetsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryVoteTargetsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryVoteTargetsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryVoteTargetsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.VoteTargets) > 0 { + for iNdEx := len(m.VoteTargets) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.VoteTargets[iNdEx].Size() + i -= size + if _, err := m.VoteTargets[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryFeederDelegationRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryFeederDelegationRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryFeederDelegationRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidatorAddr) > 0 { + i -= len(m.ValidatorAddr) + copy(dAtA[i:], m.ValidatorAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryFeederDelegationResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryFeederDelegationResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryFeederDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.FeederAddr) > 0 { + i -= len(m.FeederAddr) + copy(dAtA[i:], m.FeederAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.FeederAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryMissCounterRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryMissCounterRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryMissCounterRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidatorAddr) > 0 { + i -= len(m.ValidatorAddr) + copy(dAtA[i:], m.ValidatorAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryMissCounterResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryMissCounterResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryMissCounterResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MissCounter != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.MissCounter)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryAggregatePrevoteRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAggregatePrevoteRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAggregatePrevoteRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidatorAddr) > 0 { + i -= len(m.ValidatorAddr) + copy(dAtA[i:], m.ValidatorAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAggregatePrevoteResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAggregatePrevoteResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAggregatePrevoteResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.AggregatePrevote.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryAggregatePrevotesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAggregatePrevotesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAggregatePrevotesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryAggregatePrevotesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAggregatePrevotesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAggregatePrevotesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AggregatePrevotes) > 0 { + for iNdEx := len(m.AggregatePrevotes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AggregatePrevotes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryAggregateVoteRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAggregateVoteRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAggregateVoteRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidatorAddr) > 0 { + i -= len(m.ValidatorAddr) + copy(dAtA[i:], m.ValidatorAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAggregateVoteResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAggregateVoteResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAggregateVoteResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.AggregateVote.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryAggregateVotesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAggregateVotesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAggregateVotesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryAggregateVotesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAggregateVotesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAggregateVotesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AggregateVotes) > 0 { + for iNdEx := len(m.AggregateVotes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AggregateVotes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryExchangeRateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Pair.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryExchangeRateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ExchangeRate.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryExchangeRatesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryExchangeRatesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ExchangeRates) > 0 { + for _, e := range m.ExchangeRates { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryActivesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryActivesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Actives) > 0 { + for _, e := range m.Actives { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryVoteTargetsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryVoteTargetsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.VoteTargets) > 0 { + for _, e := range m.VoteTargets { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryFeederDelegationRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ValidatorAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryFeederDelegationResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FeederAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryMissCounterRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ValidatorAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryMissCounterResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MissCounter != 0 { + n += 1 + sovQuery(uint64(m.MissCounter)) + } + return n +} + +func (m *QueryAggregatePrevoteRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ValidatorAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAggregatePrevoteResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.AggregatePrevote.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryAggregatePrevotesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryAggregatePrevotesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.AggregatePrevotes) > 0 { + for _, e := range m.AggregatePrevotes { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryAggregateVoteRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ValidatorAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAggregateVoteResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.AggregateVote.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryAggregateVotesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryAggregateVotesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.AggregateVotes) > 0 { + for _, e := range m.AggregateVotes { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryExchangeRateRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryExchangeRateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryExchangeRateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pair", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Pair.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryExchangeRateResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryExchangeRateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryExchangeRateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExchangeRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ExchangeRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryExchangeRatesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryExchangeRatesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryExchangeRatesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryExchangeRatesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryExchangeRatesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryExchangeRatesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExchangeRates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExchangeRates = append(m.ExchangeRates, ExchangeRateTuple{}) + if err := m.ExchangeRates[len(m.ExchangeRates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryActivesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryActivesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryActivesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryActivesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryActivesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryActivesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Actives", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_archway_network_archway_x_oracle_asset.Pair + m.Actives = append(m.Actives, v) + if err := m.Actives[len(m.Actives)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryVoteTargetsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryVoteTargetsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryVoteTargetsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryVoteTargetsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryVoteTargetsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryVoteTargetsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VoteTargets", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_archway_network_archway_x_oracle_asset.Pair + m.VoteTargets = append(m.VoteTargets, v) + if err := m.VoteTargets[len(m.VoteTargets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryFeederDelegationRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryFeederDelegationRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryFeederDelegationRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryFeederDelegationResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryFeederDelegationResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryFeederDelegationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FeederAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FeederAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryMissCounterRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryMissCounterRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryMissCounterRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryMissCounterResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryMissCounterResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryMissCounterResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MissCounter", wireType) + } + m.MissCounter = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MissCounter |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAggregatePrevoteRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAggregatePrevoteRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAggregatePrevoteRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAggregatePrevoteResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAggregatePrevoteResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAggregatePrevoteResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregatePrevote", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AggregatePrevote.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAggregatePrevotesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAggregatePrevotesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAggregatePrevotesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAggregatePrevotesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAggregatePrevotesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAggregatePrevotesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregatePrevotes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AggregatePrevotes = append(m.AggregatePrevotes, AggregateExchangeRatePrevote{}) + if err := m.AggregatePrevotes[len(m.AggregatePrevotes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAggregateVoteRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAggregateVoteRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAggregateVoteRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAggregateVoteResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAggregateVoteResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAggregateVoteResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregateVote", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AggregateVote.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAggregateVotesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAggregateVotesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAggregateVotesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAggregateVotesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAggregateVotesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAggregateVotesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregateVotes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AggregateVotes = append(m.AggregateVotes, AggregateExchangeRateVote{}) + if err := m.AggregateVotes[len(m.AggregateVotes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/oracle/types/query.pb.gw.go b/x/oracle/types/query.pb.gw.go new file mode 100644 index 00000000..bfa0d6d9 --- /dev/null +++ b/x/oracle/types/query.pb.gw.go @@ -0,0 +1,1048 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: archway/oracle/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +var ( + filter_Query_ExchangeRate_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_ExchangeRate_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryExchangeRateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ExchangeRate_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ExchangeRate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ExchangeRate_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryExchangeRateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ExchangeRate_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ExchangeRate(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_ExchangeRateTwap_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_ExchangeRateTwap_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryExchangeRateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ExchangeRateTwap_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ExchangeRateTwap(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ExchangeRateTwap_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryExchangeRateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ExchangeRateTwap_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ExchangeRateTwap(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_ExchangeRates_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryExchangeRatesRequest + var metadata runtime.ServerMetadata + + msg, err := client.ExchangeRates(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ExchangeRates_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryExchangeRatesRequest + var metadata runtime.ServerMetadata + + msg, err := server.ExchangeRates(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_Actives_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryActivesRequest + var metadata runtime.ServerMetadata + + msg, err := client.Actives(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Actives_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryActivesRequest + var metadata runtime.ServerMetadata + + msg, err := server.Actives(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_VoteTargets_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryVoteTargetsRequest + var metadata runtime.ServerMetadata + + msg, err := client.VoteTargets(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_VoteTargets_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryVoteTargetsRequest + var metadata runtime.ServerMetadata + + msg, err := server.VoteTargets(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_FeederDelegation_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryFeederDelegationRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["validator_addr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_addr") + } + + protoReq.ValidatorAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_addr", err) + } + + msg, err := client.FeederDelegation(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_FeederDelegation_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryFeederDelegationRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["validator_addr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_addr") + } + + protoReq.ValidatorAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_addr", err) + } + + msg, err := server.FeederDelegation(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_MissCounter_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryMissCounterRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["validator_addr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_addr") + } + + protoReq.ValidatorAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_addr", err) + } + + msg, err := client.MissCounter(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_MissCounter_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryMissCounterRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["validator_addr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_addr") + } + + protoReq.ValidatorAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_addr", err) + } + + msg, err := server.MissCounter(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_AggregatePrevote_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAggregatePrevoteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["validator_addr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_addr") + } + + protoReq.ValidatorAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_addr", err) + } + + msg, err := client.AggregatePrevote(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AggregatePrevote_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAggregatePrevoteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["validator_addr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_addr") + } + + protoReq.ValidatorAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_addr", err) + } + + msg, err := server.AggregatePrevote(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_AggregatePrevotes_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAggregatePrevotesRequest + var metadata runtime.ServerMetadata + + msg, err := client.AggregatePrevotes(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AggregatePrevotes_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAggregatePrevotesRequest + var metadata runtime.ServerMetadata + + msg, err := server.AggregatePrevotes(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_AggregateVote_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAggregateVoteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["validator_addr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_addr") + } + + protoReq.ValidatorAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_addr", err) + } + + msg, err := client.AggregateVote(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AggregateVote_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAggregateVoteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["validator_addr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_addr") + } + + protoReq.ValidatorAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_addr", err) + } + + msg, err := server.AggregateVote(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_AggregateVotes_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAggregateVotesRequest + var metadata runtime.ServerMetadata + + msg, err := client.AggregateVotes(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AggregateVotes_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAggregateVotesRequest + var metadata runtime.ServerMetadata + + msg, err := server.AggregateVotes(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_ExchangeRate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ExchangeRate_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ExchangeRate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ExchangeRateTwap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ExchangeRateTwap_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ExchangeRateTwap_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ExchangeRates_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ExchangeRates_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ExchangeRates_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Actives_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Actives_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Actives_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_VoteTargets_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_VoteTargets_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_VoteTargets_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_FeederDelegation_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_FeederDelegation_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_FeederDelegation_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_MissCounter_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_MissCounter_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_MissCounter_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AggregatePrevote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AggregatePrevote_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AggregatePrevote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AggregatePrevotes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AggregatePrevotes_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AggregatePrevotes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AggregateVote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AggregateVote_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AggregateVote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AggregateVotes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AggregateVotes_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AggregateVotes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_ExchangeRate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ExchangeRate_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ExchangeRate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ExchangeRateTwap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ExchangeRateTwap_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ExchangeRateTwap_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ExchangeRates_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ExchangeRates_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ExchangeRates_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Actives_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Actives_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Actives_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_VoteTargets_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_VoteTargets_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_VoteTargets_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_FeederDelegation_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_FeederDelegation_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_FeederDelegation_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_MissCounter_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_MissCounter_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_MissCounter_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AggregatePrevote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AggregatePrevote_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AggregatePrevote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AggregatePrevotes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AggregatePrevotes_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AggregatePrevotes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AggregateVote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AggregateVote_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AggregateVote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AggregateVotes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AggregateVotes_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AggregateVotes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_ExchangeRate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"archway", "oracle", "v1beta1", "exchange_rate"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_ExchangeRateTwap_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"archway", "oracle", "v1beta1", "exchange_rate_twap"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_ExchangeRates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"archway", "oracle", "v1beta1", "pairs", "exchange_rates"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Actives_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"archway", "oracle", "v1beta1", "pairs", "actives"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_VoteTargets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"archway", "oracle", "v1beta1", "pairs", "vote_targets"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_FeederDelegation_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"archway", "oracle", "v1beta1", "validators", "validator_addr", "feeder"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_MissCounter_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"archway", "oracle", "v1beta1", "validators", "validator_addr", "miss"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_AggregatePrevote_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"archway", "oracle", "v1beta1", "validators", "validator_addr", "aggregate_prevote"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_AggregatePrevotes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"archway", "oracle", "v1beta1", "validators", "aggregate_prevotes"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_AggregateVote_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"archway", "oracle", "v1beta1", "valdiators", "validator_addr", "aggregate_vote"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_AggregateVotes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"archway", "oracle", "v1beta1", "validators", "aggregate_votes"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"archway", "oracle", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_ExchangeRate_0 = runtime.ForwardResponseMessage + + forward_Query_ExchangeRateTwap_0 = runtime.ForwardResponseMessage + + forward_Query_ExchangeRates_0 = runtime.ForwardResponseMessage + + forward_Query_Actives_0 = runtime.ForwardResponseMessage + + forward_Query_VoteTargets_0 = runtime.ForwardResponseMessage + + forward_Query_FeederDelegation_0 = runtime.ForwardResponseMessage + + forward_Query_MissCounter_0 = runtime.ForwardResponseMessage + + forward_Query_AggregatePrevote_0 = runtime.ForwardResponseMessage + + forward_Query_AggregatePrevotes_0 = runtime.ForwardResponseMessage + + forward_Query_AggregateVote_0 = runtime.ForwardResponseMessage + + forward_Query_AggregateVotes_0 = runtime.ForwardResponseMessage + + forward_Query_Params_0 = runtime.ForwardResponseMessage +) diff --git a/x/oracle/types/state.pb.go b/x/oracle/types/state.pb.go new file mode 100644 index 00000000..48a25786 --- /dev/null +++ b/x/oracle/types/state.pb.go @@ -0,0 +1,410 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: archway/oracle/v1/state.proto + +package types + +import ( + cosmossdk_io_math "cosmossdk.io/math" + fmt "fmt" + github_com_archway_network_archway_x_oracle_asset "github.com/archway-network/archway/x/oracle/asset" + _ "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// a snapshot of the prices at a given point in time +type PriceSnapshot struct { + Pair github_com_archway_network_archway_x_oracle_asset.Pair `protobuf:"bytes,1,opt,name=pair,proto3,customtype=github.com/archway-network/archway/x/oracle/asset.Pair" json:"pair" yaml:"pair"` + Price cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=price,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"price"` + // milliseconds since unix epoch + TimestampMs int64 `protobuf:"varint,3,opt,name=timestamp_ms,json=timestampMs,proto3" json:"timestamp_ms,omitempty"` +} + +func (m *PriceSnapshot) Reset() { *m = PriceSnapshot{} } +func (m *PriceSnapshot) String() string { return proto.CompactTextString(m) } +func (*PriceSnapshot) ProtoMessage() {} +func (*PriceSnapshot) Descriptor() ([]byte, []int) { + return fileDescriptor_f86ab5cb19be0ee7, []int{0} +} +func (m *PriceSnapshot) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PriceSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PriceSnapshot.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PriceSnapshot) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriceSnapshot.Merge(m, src) +} +func (m *PriceSnapshot) XXX_Size() int { + return m.Size() +} +func (m *PriceSnapshot) XXX_DiscardUnknown() { + xxx_messageInfo_PriceSnapshot.DiscardUnknown(m) +} + +var xxx_messageInfo_PriceSnapshot proto.InternalMessageInfo + +func (m *PriceSnapshot) GetTimestampMs() int64 { + if m != nil { + return m.TimestampMs + } + return 0 +} + +func init() { + proto.RegisterType((*PriceSnapshot)(nil), "archway.oracle.v1.PriceSnapshot") +} + +func init() { proto.RegisterFile("archway/oracle/v1/state.proto", fileDescriptor_f86ab5cb19be0ee7) } + +var fileDescriptor_f86ab5cb19be0ee7 = []byte{ + // 327 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x90, 0xbd, 0x4e, 0xf3, 0x30, + 0x14, 0x86, 0x93, 0xaf, 0x1f, 0x48, 0xa4, 0x30, 0x10, 0x31, 0x54, 0x05, 0xd2, 0x52, 0x96, 0x2e, + 0xc4, 0x8a, 0x90, 0x90, 0x60, 0xac, 0xd8, 0xa0, 0x52, 0x55, 0x36, 0x16, 0x74, 0x62, 0xac, 0xc4, + 0x6a, 0x9d, 0x63, 0xd9, 0x87, 0x96, 0xdc, 0x05, 0x97, 0xd5, 0xb1, 0x23, 0x62, 0xa8, 0x50, 0x7b, + 0x07, 0x5c, 0x01, 0xca, 0x4f, 0x59, 0x98, 0xd8, 0x6c, 0x3f, 0xf6, 0xfb, 0xbc, 0x3e, 0xde, 0x29, + 0x18, 0x9e, 0xce, 0x21, 0x67, 0x68, 0x80, 0x4f, 0x05, 0x9b, 0x45, 0xcc, 0x12, 0x90, 0x08, 0xb5, + 0x41, 0x42, 0xff, 0xb0, 0xc6, 0x61, 0x85, 0xc3, 0x59, 0xd4, 0x3e, 0x4a, 0x30, 0xc1, 0x92, 0xb2, + 0x62, 0x55, 0x5d, 0x6c, 0x9f, 0x24, 0x88, 0xc9, 0x54, 0x30, 0xd0, 0x92, 0x41, 0x96, 0x21, 0x01, + 0x49, 0xcc, 0x6c, 0x4d, 0x83, 0xdf, 0x96, 0x3a, 0xb0, 0xe6, 0x1c, 0xad, 0x42, 0xcb, 0x62, 0xb0, + 0x05, 0x8c, 0x05, 0x41, 0xc4, 0x38, 0xca, 0xac, 0xe2, 0xbd, 0xa5, 0xeb, 0x1d, 0x8c, 0x8c, 0xe4, + 0xe2, 0x21, 0x03, 0x6d, 0x53, 0x24, 0x1f, 0xbc, 0xff, 0x1a, 0xa4, 0x69, 0xb9, 0x5d, 0xb7, 0xbf, + 0x37, 0x18, 0x2e, 0x56, 0x1d, 0xe7, 0x63, 0xd5, 0xb9, 0x4a, 0x24, 0xa5, 0x2f, 0x71, 0xc8, 0x51, + 0xb1, 0x5a, 0x79, 0x91, 0x09, 0x9a, 0xa3, 0x99, 0x6c, 0xf7, 0xec, 0x75, 0x5b, 0x02, 0xac, 0x15, + 0x14, 0x8e, 0x40, 0x9a, 0xaf, 0x55, 0xa7, 0x99, 0x83, 0x9a, 0xde, 0xf4, 0x8a, 0xcc, 0xde, 0xb8, + 0x8c, 0xf6, 0xaf, 0xbd, 0x1d, 0x5d, 0x38, 0x5b, 0xff, 0x4a, 0xc7, 0x79, 0xed, 0x38, 0xae, 0xba, + 0xda, 0xe7, 0x49, 0x28, 0x91, 0x29, 0xa0, 0x34, 0xbc, 0x17, 0x09, 0xf0, 0xfc, 0x56, 0xf0, 0x71, + 0xf5, 0xc2, 0x3f, 0xf3, 0xf6, 0x49, 0x2a, 0x61, 0x09, 0x94, 0x7e, 0x52, 0xb6, 0xd5, 0xe8, 0xba, + 0xfd, 0xc6, 0xb8, 0xf9, 0x73, 0x36, 0xb4, 0x83, 0xbb, 0xc5, 0x3a, 0x70, 0x97, 0xeb, 0xc0, 0xfd, + 0x5c, 0x07, 0xee, 0xdb, 0x26, 0x70, 0x96, 0x9b, 0xc0, 0x79, 0xdf, 0x04, 0xce, 0x63, 0xf4, 0x97, + 0x4f, 0x50, 0xae, 0x85, 0x8d, 0x77, 0xcb, 0x31, 0x5d, 0x7e, 0x07, 0x00, 0x00, 0xff, 0xff, 0x3c, + 0x7a, 0xa3, 0xe3, 0xce, 0x01, 0x00, 0x00, +} + +func (m *PriceSnapshot) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PriceSnapshot) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PriceSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.TimestampMs != 0 { + i = encodeVarintState(dAtA, i, uint64(m.TimestampMs)) + i-- + dAtA[i] = 0x18 + } + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintState(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size := m.Pair.Size() + i -= size + if _, err := m.Pair.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintState(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintState(dAtA []byte, offset int, v uint64) int { + offset -= sovState(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *PriceSnapshot) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Pair.Size() + n += 1 + l + sovState(uint64(l)) + l = m.Price.Size() + n += 1 + l + sovState(uint64(l)) + if m.TimestampMs != 0 { + n += 1 + sovState(uint64(m.TimestampMs)) + } + return n +} + +func sovState(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozState(x uint64) (n int) { + return sovState(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PriceSnapshot) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PriceSnapshot: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriceSnapshot: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pair", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Pair.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimestampMs", wireType) + } + m.TimestampMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimestampMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipState(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipState(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowState + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowState + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowState + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthState + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupState + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthState + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthState = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowState = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupState = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/oracle/types/test_utils.go b/x/oracle/types/test_utils.go new file mode 100644 index 00000000..7204342f --- /dev/null +++ b/x/oracle/types/test_utils.go @@ -0,0 +1,181 @@ +// nolint +package types + +import ( + "context" + "errors" + "math" + "math/rand" + "time" + + sdkmath "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/cometbft/cometbft/crypto/secp256k1" + cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" +) + +// OracleDecPrecision nolint +const OracleDecPrecision = 8 + +// GenerateRandomTestCase nolint +func GenerateRandomTestCase() (rates []float64, valAddrs []sdk.ValAddress, stakingKeeper DummyStakingKeeper) { + valAddrs = []sdk.ValAddress{} + mockValidators := []MockValidator{} + + base := math.Pow10(OracleDecPrecision) + + rand.Seed(int64(time.Now().Nanosecond())) + numInputs := 10 + (rand.Int() % 100) + for i := 0; i < numInputs; i++ { + rate := float64(int64(rand.Float64()*base)) / base + rates = append(rates, rate) + + pubKey := secp256k1.GenPrivKey().PubKey() + valAddr := sdk.ValAddress(pubKey.Address()) + valAddrs = append(valAddrs, valAddr) + + power := rand.Int63()%1000 + 1 + mockValidator := NewMockValidator(valAddr, power) + mockValidators = append(mockValidators, mockValidator) + } + + stakingKeeper = NewDummyStakingKeeper(mockValidators) + + return +} + +var _ StakingKeeper = DummyStakingKeeper{} + +// DummyStakingKeeper dummy staking keeper to test votes +type DummyStakingKeeper struct { + validators []MockValidator +} + +// NewDummyStakingKeeper returns new DummyStakingKeeper instance +func NewDummyStakingKeeper(validators []MockValidator) DummyStakingKeeper { + return DummyStakingKeeper{ + validators: validators, + } +} + +// Validators nolint +func (sk DummyStakingKeeper) Validators() []MockValidator { + return sk.validators +} + +// Validator nolint +func (sk DummyStakingKeeper) Validator(ctx context.Context, address sdk.ValAddress) (stakingtypes.ValidatorI, error) { + for _, validator := range sk.validators { + op, err := sdk.ValAddressFromBech32(validator.GetOperator()) + if err != nil { + return nil, err + } + if op.Equals(address) { + return validator, nil + } + } + + return nil, errors.New("Validator not found") +} + +// TotalBondedTokens nolint +func (DummyStakingKeeper) TotalBondedTokens(_ context.Context) (sdkmath.Int, error) { + return sdkmath.ZeroInt(), nil +} + +// Slash nolint +func (DummyStakingKeeper) Slash(context.Context, sdk.ConsAddress, int64, int64, sdkmath.LegacyDec) (sdkmath.Int, error) { + return sdkmath.ZeroInt(), nil +} + +// ValidatorsPowerStoreIterator nolint +func (DummyStakingKeeper) ValidatorsPowerStoreIterator(ctx context.Context) (storetypes.Iterator, error) { + return storetypes.KVStoreReversePrefixIterator(nil, nil), nil +} + +// Jail nolint +func (DummyStakingKeeper) Jail(context.Context, sdk.ConsAddress) error { + return nil +} + +// GetLastValidatorPower nolint +func (sk DummyStakingKeeper) GetLastValidatorPower(ctx context.Context, operator sdk.ValAddress) (power int64) { + validator, err := sk.Validator(ctx, operator) + if err != nil { + panic(err) + } + + return validator.GetConsensusPower(sdk.DefaultPowerReduction) +} + +// MaxValidators returns the maximum amount of bonded validators +func (DummyStakingKeeper) MaxValidators(context.Context) (uint32, error) { + return 100, nil +} + +// PowerReduction - is the amount of staking tokens required for 1 unit of consensus-engine power +func (DummyStakingKeeper) PowerReduction(ctx context.Context) (res sdkmath.Int) { + res = sdk.DefaultPowerReduction + return +} + +// MockValidator nolint +type MockValidator struct { + power int64 + valOperAddr sdk.ValAddress +} + +var _ stakingtypes.ValidatorI = MockValidator{} + +func (MockValidator) IsJailed() bool { return false } +func (MockValidator) GetMoniker() string { return "" } +func (MockValidator) GetStatus() stakingtypes.BondStatus { return stakingtypes.Bonded } +func (MockValidator) IsBonded() bool { return true } +func (MockValidator) IsUnbonded() bool { return false } +func (MockValidator) IsUnbonding() bool { return false } +func (v MockValidator) GetOperator() string { return v.valOperAddr.String() } +func (MockValidator) ConsPubKey() (cryptotypes.PubKey, error) { return nil, nil } +func (MockValidator) TmConsPublicKey() (cmtprotocrypto.PublicKey, error) { + return cmtprotocrypto.PublicKey{}, nil +} +func (MockValidator) GetConsAddr() ([]byte, error) { return nil, nil } +func (v MockValidator) GetTokens() sdkmath.Int { + return sdk.TokensFromConsensusPower(v.power, sdk.DefaultPowerReduction) +} + +func (v MockValidator) GetBondedTokens() sdkmath.Int { + return sdk.TokensFromConsensusPower(v.power, sdk.DefaultPowerReduction) +} +func (v MockValidator) GetConsensusPower(powerReduction sdkmath.Int) int64 { return v.power } +func (v *MockValidator) SetConsensusPower(power int64) { v.power = power } +func (v MockValidator) GetCommission() sdkmath.LegacyDec { return sdkmath.LegacyZeroDec() } +func (v MockValidator) GetMinSelfDelegation() sdkmath.Int { return sdkmath.OneInt() } +func (v MockValidator) GetDelegatorShares() sdkmath.LegacyDec { return sdkmath.LegacyNewDec(v.power) } +func (v MockValidator) TokensFromShares(sdkmath.LegacyDec) sdkmath.LegacyDec { + return sdkmath.LegacyZeroDec() +} +func (v MockValidator) TokensFromSharesTruncated(sdkmath.LegacyDec) sdkmath.LegacyDec { + return sdkmath.LegacyZeroDec() +} +func (v MockValidator) TokensFromSharesRoundUp(sdkmath.LegacyDec) sdkmath.LegacyDec { + return sdkmath.LegacyZeroDec() +} +func (v MockValidator) SharesFromTokens(amt sdkmath.Int) (sdkmath.LegacyDec, error) { + return sdkmath.LegacyZeroDec(), nil +} + +func (v MockValidator) SharesFromTokensTruncated(amt sdkmath.Int) (sdkmath.LegacyDec, error) { + return sdkmath.LegacyZeroDec(), nil +} + +func NewMockValidator(valAddr sdk.ValAddress, power int64) MockValidator { + return MockValidator{ + power: power, + valOperAddr: valAddr, + } +} diff --git a/x/oracle/types/tx.pb.go b/x/oracle/types/tx.pb.go new file mode 100644 index 00000000..76d0ffa5 --- /dev/null +++ b/x/oracle/types/tx.pb.go @@ -0,0 +1,1478 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: archway/oracle/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgAggregateExchangeRatePrevote represents a message to submit +// aggregate exchange rate prevote. +type MsgAggregateExchangeRatePrevote struct { + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty" yaml:"hash"` + // Feeder is the Bech32 address of the price feeder. A validator may + // specify multiple price feeders by delegating them consent. The validator + // address is also a valid feeder by default. + Feeder string `protobuf:"bytes,2,opt,name=feeder,proto3" json:"feeder,omitempty" yaml:"feeder"` + // Validator is the Bech32 address to which the prevote will be credited. + Validator string `protobuf:"bytes,3,opt,name=validator,proto3" json:"validator,omitempty" yaml:"validator"` +} + +func (m *MsgAggregateExchangeRatePrevote) Reset() { *m = MsgAggregateExchangeRatePrevote{} } +func (m *MsgAggregateExchangeRatePrevote) String() string { return proto.CompactTextString(m) } +func (*MsgAggregateExchangeRatePrevote) ProtoMessage() {} +func (*MsgAggregateExchangeRatePrevote) Descriptor() ([]byte, []int) { + return fileDescriptor_13ab59b50571d74b, []int{0} +} +func (m *MsgAggregateExchangeRatePrevote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAggregateExchangeRatePrevote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAggregateExchangeRatePrevote.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAggregateExchangeRatePrevote) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAggregateExchangeRatePrevote.Merge(m, src) +} +func (m *MsgAggregateExchangeRatePrevote) XXX_Size() int { + return m.Size() +} +func (m *MsgAggregateExchangeRatePrevote) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAggregateExchangeRatePrevote.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAggregateExchangeRatePrevote proto.InternalMessageInfo + +// MsgAggregateExchangeRatePrevoteResponse defines the +// Msg/AggregateExchangeRatePrevote response type. +type MsgAggregateExchangeRatePrevoteResponse struct { +} + +func (m *MsgAggregateExchangeRatePrevoteResponse) Reset() { + *m = MsgAggregateExchangeRatePrevoteResponse{} +} +func (m *MsgAggregateExchangeRatePrevoteResponse) String() string { return proto.CompactTextString(m) } +func (*MsgAggregateExchangeRatePrevoteResponse) ProtoMessage() {} +func (*MsgAggregateExchangeRatePrevoteResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_13ab59b50571d74b, []int{1} +} +func (m *MsgAggregateExchangeRatePrevoteResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAggregateExchangeRatePrevoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAggregateExchangeRatePrevoteResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAggregateExchangeRatePrevoteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAggregateExchangeRatePrevoteResponse.Merge(m, src) +} +func (m *MsgAggregateExchangeRatePrevoteResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgAggregateExchangeRatePrevoteResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAggregateExchangeRatePrevoteResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAggregateExchangeRatePrevoteResponse proto.InternalMessageInfo + +// MsgAggregateExchangeRateVote represents a message to submit +// aggregate exchange rate vote. +type MsgAggregateExchangeRateVote struct { + Salt string `protobuf:"bytes,1,opt,name=salt,proto3" json:"salt,omitempty" yaml:"salt"` + ExchangeRates string `protobuf:"bytes,2,opt,name=exchange_rates,json=exchangeRates,proto3" json:"exchange_rates,omitempty" yaml:"exchange_rates"` + // Feeder is the Bech32 address of the price feeder. A validator may + // specify multiple price feeders by delegating them consent. The validator + // address is also a valid feeder by default. + Feeder string `protobuf:"bytes,3,opt,name=feeder,proto3" json:"feeder,omitempty" yaml:"feeder"` + // Validator is the Bech32 address to which the vote will be credited. + Validator string `protobuf:"bytes,4,opt,name=validator,proto3" json:"validator,omitempty" yaml:"validator"` +} + +func (m *MsgAggregateExchangeRateVote) Reset() { *m = MsgAggregateExchangeRateVote{} } +func (m *MsgAggregateExchangeRateVote) String() string { return proto.CompactTextString(m) } +func (*MsgAggregateExchangeRateVote) ProtoMessage() {} +func (*MsgAggregateExchangeRateVote) Descriptor() ([]byte, []int) { + return fileDescriptor_13ab59b50571d74b, []int{2} +} +func (m *MsgAggregateExchangeRateVote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAggregateExchangeRateVote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAggregateExchangeRateVote.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAggregateExchangeRateVote) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAggregateExchangeRateVote.Merge(m, src) +} +func (m *MsgAggregateExchangeRateVote) XXX_Size() int { + return m.Size() +} +func (m *MsgAggregateExchangeRateVote) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAggregateExchangeRateVote.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAggregateExchangeRateVote proto.InternalMessageInfo + +// MsgAggregateExchangeRateVoteResponse defines the +// Msg/AggregateExchangeRateVote response type. +type MsgAggregateExchangeRateVoteResponse struct { +} + +func (m *MsgAggregateExchangeRateVoteResponse) Reset() { *m = MsgAggregateExchangeRateVoteResponse{} } +func (m *MsgAggregateExchangeRateVoteResponse) String() string { return proto.CompactTextString(m) } +func (*MsgAggregateExchangeRateVoteResponse) ProtoMessage() {} +func (*MsgAggregateExchangeRateVoteResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_13ab59b50571d74b, []int{3} +} +func (m *MsgAggregateExchangeRateVoteResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAggregateExchangeRateVoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAggregateExchangeRateVoteResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAggregateExchangeRateVoteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAggregateExchangeRateVoteResponse.Merge(m, src) +} +func (m *MsgAggregateExchangeRateVoteResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgAggregateExchangeRateVoteResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAggregateExchangeRateVoteResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAggregateExchangeRateVoteResponse proto.InternalMessageInfo + +// MsgDelegateFeedConsent represents a message to delegate oracle voting rights +// to another address. +type MsgDelegateFeedConsent struct { + Operator string `protobuf:"bytes,1,opt,name=operator,proto3" json:"operator,omitempty" yaml:"operator"` + Delegate string `protobuf:"bytes,2,opt,name=delegate,proto3" json:"delegate,omitempty" yaml:"delegate"` +} + +func (m *MsgDelegateFeedConsent) Reset() { *m = MsgDelegateFeedConsent{} } +func (m *MsgDelegateFeedConsent) String() string { return proto.CompactTextString(m) } +func (*MsgDelegateFeedConsent) ProtoMessage() {} +func (*MsgDelegateFeedConsent) Descriptor() ([]byte, []int) { + return fileDescriptor_13ab59b50571d74b, []int{4} +} +func (m *MsgDelegateFeedConsent) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDelegateFeedConsent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDelegateFeedConsent.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgDelegateFeedConsent) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDelegateFeedConsent.Merge(m, src) +} +func (m *MsgDelegateFeedConsent) XXX_Size() int { + return m.Size() +} +func (m *MsgDelegateFeedConsent) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDelegateFeedConsent.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDelegateFeedConsent proto.InternalMessageInfo + +// MsgDelegateFeedConsentResponse defines the Msg/DelegateFeedConsent response +// type. +type MsgDelegateFeedConsentResponse struct { +} + +func (m *MsgDelegateFeedConsentResponse) Reset() { *m = MsgDelegateFeedConsentResponse{} } +func (m *MsgDelegateFeedConsentResponse) String() string { return proto.CompactTextString(m) } +func (*MsgDelegateFeedConsentResponse) ProtoMessage() {} +func (*MsgDelegateFeedConsentResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_13ab59b50571d74b, []int{5} +} +func (m *MsgDelegateFeedConsentResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDelegateFeedConsentResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDelegateFeedConsentResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgDelegateFeedConsentResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDelegateFeedConsentResponse.Merge(m, src) +} +func (m *MsgDelegateFeedConsentResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgDelegateFeedConsentResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDelegateFeedConsentResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDelegateFeedConsentResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgAggregateExchangeRatePrevote)(nil), "archway.oracle.v1.MsgAggregateExchangeRatePrevote") + proto.RegisterType((*MsgAggregateExchangeRatePrevoteResponse)(nil), "archway.oracle.v1.MsgAggregateExchangeRatePrevoteResponse") + proto.RegisterType((*MsgAggregateExchangeRateVote)(nil), "archway.oracle.v1.MsgAggregateExchangeRateVote") + proto.RegisterType((*MsgAggregateExchangeRateVoteResponse)(nil), "archway.oracle.v1.MsgAggregateExchangeRateVoteResponse") + proto.RegisterType((*MsgDelegateFeedConsent)(nil), "archway.oracle.v1.MsgDelegateFeedConsent") + proto.RegisterType((*MsgDelegateFeedConsentResponse)(nil), "archway.oracle.v1.MsgDelegateFeedConsentResponse") +} + +func init() { proto.RegisterFile("archway/oracle/v1/tx.proto", fileDescriptor_13ab59b50571d74b) } + +var fileDescriptor_13ab59b50571d74b = []byte{ + // 593 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0x3f, 0x6f, 0x13, 0x41, + 0x10, 0xc5, 0xbd, 0xb1, 0x89, 0x92, 0x45, 0x21, 0xe4, 0x6c, 0x12, 0xfb, 0x64, 0xdd, 0x85, 0x05, + 0x11, 0x1c, 0x29, 0x77, 0xb2, 0x29, 0x90, 0x5c, 0x41, 0xf8, 0xd3, 0x20, 0x4b, 0xe8, 0x0a, 0x0a, + 0x1a, 0xb4, 0xb1, 0x87, 0xb5, 0xc5, 0xf9, 0xf6, 0x74, 0xbb, 0x38, 0x76, 0x87, 0x02, 0x05, 0x25, + 0x12, 0x2d, 0x45, 0x24, 0x3e, 0x00, 0xa9, 0xf9, 0x04, 0x94, 0x91, 0x68, 0xa8, 0x2c, 0x64, 0x23, + 0x85, 0xda, 0x1d, 0x1d, 0xba, 0xbf, 0x18, 0xdb, 0x49, 0xb0, 0xe8, 0xac, 0x7d, 0x6f, 0x66, 0x7e, + 0xf3, 0x34, 0x67, 0xac, 0x52, 0xaf, 0xde, 0xdc, 0xa7, 0x3d, 0x93, 0x7b, 0xb4, 0x6e, 0x83, 0xd9, + 0x29, 0x9b, 0xb2, 0x6b, 0xb8, 0x1e, 0x97, 0x5c, 0x59, 0x8b, 0x34, 0x23, 0xd4, 0x8c, 0x4e, 0x59, + 0xcd, 0x31, 0xce, 0x78, 0xa0, 0x9a, 0xfe, 0xaf, 0xd0, 0xa8, 0x16, 0x19, 0xe7, 0xcc, 0x06, 0x93, + 0xba, 0x2d, 0x93, 0x3a, 0x0e, 0x97, 0x54, 0xb6, 0xb8, 0x23, 0x22, 0x55, 0x9b, 0x1e, 0x11, 0x35, + 0x0c, 0xf5, 0x8d, 0x3a, 0x17, 0x6d, 0x2e, 0xcc, 0xb6, 0x60, 0xbe, 0xd6, 0x16, 0x2c, 0x14, 0xc8, + 0x67, 0x84, 0xf5, 0x9a, 0x60, 0x77, 0x19, 0xf3, 0x80, 0x51, 0x09, 0x0f, 0xba, 0xf5, 0x26, 0x75, + 0x18, 0x58, 0x54, 0xc2, 0x63, 0x0f, 0x3a, 0x5c, 0x82, 0x72, 0x0d, 0x67, 0x9a, 0x54, 0x34, 0xf3, + 0x68, 0x13, 0xdd, 0x5c, 0xde, 0x5d, 0x1d, 0xf5, 0xf5, 0x8b, 0x3d, 0xda, 0xb6, 0xab, 0xc4, 0x7f, + 0x25, 0x56, 0x20, 0x2a, 0x25, 0xbc, 0xf8, 0x1c, 0xa0, 0x01, 0x5e, 0x7e, 0x21, 0xb0, 0xad, 0x8d, + 0xfa, 0xfa, 0x4a, 0x68, 0x0b, 0xdf, 0x89, 0x15, 0x19, 0x94, 0x0a, 0x5e, 0xee, 0x50, 0xbb, 0xd5, + 0xa0, 0x92, 0x7b, 0xf9, 0x74, 0xe0, 0xce, 0x8d, 0xfa, 0xfa, 0xe5, 0xd0, 0x9d, 0x48, 0xc4, 0xfa, + 0x63, 0xab, 0x66, 0xdf, 0x1e, 0xea, 0xa9, 0x9f, 0x87, 0x7a, 0xea, 0xe0, 0xe4, 0x68, 0x3b, 0x6a, + 0x44, 0x4a, 0x78, 0xeb, 0x1c, 0x76, 0x0b, 0x84, 0xcb, 0x1d, 0x01, 0xe4, 0x17, 0xc2, 0xc5, 0xd3, + 0xbc, 0x4f, 0xa2, 0x25, 0x05, 0xb5, 0xe5, 0xf4, 0x92, 0xfe, 0x2b, 0xb1, 0x02, 0x51, 0xb9, 0x83, + 0x2f, 0x41, 0x54, 0xf8, 0xcc, 0xa3, 0x12, 0x44, 0xb4, 0x6c, 0x61, 0xd4, 0xd7, 0xaf, 0x84, 0xf6, + 0xbf, 0x75, 0x62, 0xad, 0xc0, 0xd8, 0x24, 0x31, 0x16, 0x53, 0x7a, 0xae, 0x98, 0x32, 0xff, 0x11, + 0xd3, 0x0d, 0x7c, 0xfd, 0xac, 0xd5, 0x93, 0x8c, 0xde, 0x20, 0xbc, 0x5e, 0x13, 0xec, 0x3e, 0xd8, + 0x81, 0xef, 0x21, 0x40, 0xe3, 0x9e, 0x2f, 0x38, 0x52, 0x31, 0xf1, 0x12, 0x77, 0xc1, 0x0b, 0x50, + 0xc2, 0x84, 0xb2, 0xa3, 0xbe, 0xbe, 0x1a, 0xa2, 0xc4, 0x0a, 0xb1, 0x12, 0x93, 0x5f, 0xd0, 0x88, + 0xfa, 0x44, 0x19, 0x8d, 0x15, 0xc4, 0x0a, 0xb1, 0x12, 0x53, 0x75, 0x29, 0x26, 0x27, 0x9b, 0x58, + 0x9b, 0x4d, 0x11, 0x83, 0x56, 0x5e, 0x67, 0x70, 0xba, 0x26, 0x98, 0xf2, 0x09, 0xe1, 0xe2, 0x99, + 0x97, 0x5b, 0x31, 0xa6, 0x3e, 0x2f, 0xe3, 0x9c, 0x8b, 0x51, 0xab, 0xf3, 0xd7, 0x24, 0x09, 0xea, + 0x07, 0x5f, 0x7f, 0xbc, 0x5f, 0x28, 0x90, 0x0d, 0x73, 0xe2, 0x7b, 0x74, 0x23, 0xa0, 0x8f, 0x08, + 0x17, 0x4e, 0xbf, 0x41, 0x73, 0x8e, 0xd1, 0x7e, 0x81, 0x7a, 0x7b, 0xce, 0x82, 0x04, 0xb4, 0x18, + 0x80, 0xae, 0x93, 0xdc, 0x24, 0x68, 0x40, 0xf9, 0x01, 0xe1, 0xec, 0xac, 0x2b, 0x28, 0xcd, 0x1e, + 0x37, 0xc3, 0xaa, 0x96, 0xff, 0xd9, 0x9a, 0x30, 0x6d, 0x05, 0x4c, 0x57, 0x89, 0x3e, 0xc9, 0x14, + 0x9e, 0xf1, 0x4e, 0x7c, 0x2a, 0xea, 0x85, 0x57, 0x27, 0x47, 0xdb, 0x68, 0xf7, 0xd1, 0x97, 0x81, + 0x86, 0x8e, 0x07, 0x1a, 0xfa, 0x3e, 0xd0, 0xd0, 0xbb, 0xa1, 0x96, 0x3a, 0x1e, 0x6a, 0xa9, 0x6f, + 0x43, 0x2d, 0xf5, 0xb4, 0xcc, 0x5a, 0xb2, 0xf9, 0x72, 0xcf, 0xa8, 0xf3, 0x76, 0xdc, 0x6b, 0xc7, + 0x01, 0xb9, 0xcf, 0xbd, 0x17, 0x49, 0xef, 0x6e, 0xdc, 0x5d, 0xf6, 0x5c, 0x10, 0x7b, 0x8b, 0xc1, + 0xdf, 0xe1, 0xad, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x07, 0x7a, 0x33, 0xf2, 0xac, 0x05, 0x00, + 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // AggregateExchangeRatePrevote defines a method for submitting + // aggregate exchange rate prevote + AggregateExchangeRatePrevote(ctx context.Context, in *MsgAggregateExchangeRatePrevote, opts ...grpc.CallOption) (*MsgAggregateExchangeRatePrevoteResponse, error) + // AggregateExchangeRateVote defines a method for submitting + // aggregate exchange rate vote + AggregateExchangeRateVote(ctx context.Context, in *MsgAggregateExchangeRateVote, opts ...grpc.CallOption) (*MsgAggregateExchangeRateVoteResponse, error) + // DelegateFeedConsent defines a method for delegating oracle voting rights + // to another address known as a price feeder. + // See https://github.com/NibiruChain/pricefeeder. + DelegateFeedConsent(ctx context.Context, in *MsgDelegateFeedConsent, opts ...grpc.CallOption) (*MsgDelegateFeedConsentResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) AggregateExchangeRatePrevote(ctx context.Context, in *MsgAggregateExchangeRatePrevote, opts ...grpc.CallOption) (*MsgAggregateExchangeRatePrevoteResponse, error) { + out := new(MsgAggregateExchangeRatePrevoteResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Msg/AggregateExchangeRatePrevote", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) AggregateExchangeRateVote(ctx context.Context, in *MsgAggregateExchangeRateVote, opts ...grpc.CallOption) (*MsgAggregateExchangeRateVoteResponse, error) { + out := new(MsgAggregateExchangeRateVoteResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Msg/AggregateExchangeRateVote", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) DelegateFeedConsent(ctx context.Context, in *MsgDelegateFeedConsent, opts ...grpc.CallOption) (*MsgDelegateFeedConsentResponse, error) { + out := new(MsgDelegateFeedConsentResponse) + err := c.cc.Invoke(ctx, "/archway.oracle.v1.Msg/DelegateFeedConsent", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // AggregateExchangeRatePrevote defines a method for submitting + // aggregate exchange rate prevote + AggregateExchangeRatePrevote(context.Context, *MsgAggregateExchangeRatePrevote) (*MsgAggregateExchangeRatePrevoteResponse, error) + // AggregateExchangeRateVote defines a method for submitting + // aggregate exchange rate vote + AggregateExchangeRateVote(context.Context, *MsgAggregateExchangeRateVote) (*MsgAggregateExchangeRateVoteResponse, error) + // DelegateFeedConsent defines a method for delegating oracle voting rights + // to another address known as a price feeder. + // See https://github.com/NibiruChain/pricefeeder. + DelegateFeedConsent(context.Context, *MsgDelegateFeedConsent) (*MsgDelegateFeedConsentResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) AggregateExchangeRatePrevote(ctx context.Context, req *MsgAggregateExchangeRatePrevote) (*MsgAggregateExchangeRatePrevoteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AggregateExchangeRatePrevote not implemented") +} +func (*UnimplementedMsgServer) AggregateExchangeRateVote(ctx context.Context, req *MsgAggregateExchangeRateVote) (*MsgAggregateExchangeRateVoteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AggregateExchangeRateVote not implemented") +} +func (*UnimplementedMsgServer) DelegateFeedConsent(ctx context.Context, req *MsgDelegateFeedConsent) (*MsgDelegateFeedConsentResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DelegateFeedConsent not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_AggregateExchangeRatePrevote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgAggregateExchangeRatePrevote) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).AggregateExchangeRatePrevote(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Msg/AggregateExchangeRatePrevote", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).AggregateExchangeRatePrevote(ctx, req.(*MsgAggregateExchangeRatePrevote)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_AggregateExchangeRateVote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgAggregateExchangeRateVote) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).AggregateExchangeRateVote(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Msg/AggregateExchangeRateVote", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).AggregateExchangeRateVote(ctx, req.(*MsgAggregateExchangeRateVote)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_DelegateFeedConsent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgDelegateFeedConsent) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).DelegateFeedConsent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/archway.oracle.v1.Msg/DelegateFeedConsent", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).DelegateFeedConsent(ctx, req.(*MsgDelegateFeedConsent)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "archway.oracle.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AggregateExchangeRatePrevote", + Handler: _Msg_AggregateExchangeRatePrevote_Handler, + }, + { + MethodName: "AggregateExchangeRateVote", + Handler: _Msg_AggregateExchangeRateVote_Handler, + }, + { + MethodName: "DelegateFeedConsent", + Handler: _Msg_DelegateFeedConsent_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "archway/oracle/v1/tx.proto", +} + +func (m *MsgAggregateExchangeRatePrevote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAggregateExchangeRatePrevote) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAggregateExchangeRatePrevote) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0x1a + } + if len(m.Feeder) > 0 { + i -= len(m.Feeder) + copy(dAtA[i:], m.Feeder) + i = encodeVarintTx(dAtA, i, uint64(len(m.Feeder))) + i-- + dAtA[i] = 0x12 + } + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintTx(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgAggregateExchangeRatePrevoteResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAggregateExchangeRatePrevoteResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAggregateExchangeRatePrevoteResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgAggregateExchangeRateVote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAggregateExchangeRateVote) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAggregateExchangeRateVote) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0x22 + } + if len(m.Feeder) > 0 { + i -= len(m.Feeder) + copy(dAtA[i:], m.Feeder) + i = encodeVarintTx(dAtA, i, uint64(len(m.Feeder))) + i-- + dAtA[i] = 0x1a + } + if len(m.ExchangeRates) > 0 { + i -= len(m.ExchangeRates) + copy(dAtA[i:], m.ExchangeRates) + i = encodeVarintTx(dAtA, i, uint64(len(m.ExchangeRates))) + i-- + dAtA[i] = 0x12 + } + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintTx(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgAggregateExchangeRateVoteResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAggregateExchangeRateVoteResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAggregateExchangeRateVoteResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgDelegateFeedConsent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDelegateFeedConsent) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDelegateFeedConsent) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Delegate) > 0 { + i -= len(m.Delegate) + copy(dAtA[i:], m.Delegate) + i = encodeVarintTx(dAtA, i, uint64(len(m.Delegate))) + i-- + dAtA[i] = 0x12 + } + if len(m.Operator) > 0 { + i -= len(m.Operator) + copy(dAtA[i:], m.Operator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Operator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgDelegateFeedConsentResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDelegateFeedConsentResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDelegateFeedConsentResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgAggregateExchangeRatePrevote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Feeder) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgAggregateExchangeRatePrevoteResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgAggregateExchangeRateVote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ExchangeRates) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Feeder) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgAggregateExchangeRateVoteResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgDelegateFeedConsent) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Operator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Delegate) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgDelegateFeedConsentResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgAggregateExchangeRatePrevote) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAggregateExchangeRatePrevote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAggregateExchangeRatePrevote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Feeder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Feeder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAggregateExchangeRatePrevoteResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAggregateExchangeRatePrevoteResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAggregateExchangeRatePrevoteResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAggregateExchangeRateVote) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAggregateExchangeRateVote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAggregateExchangeRateVote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExchangeRates", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExchangeRates = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Feeder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Feeder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAggregateExchangeRateVoteResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAggregateExchangeRateVoteResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAggregateExchangeRateVoteResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDelegateFeedConsent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDelegateFeedConsent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDelegateFeedConsent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Operator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Delegate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Delegate = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDelegateFeedConsentResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDelegateFeedConsentResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDelegateFeedConsentResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/oracle/types/tx.pb.gw.go b/x/oracle/types/tx.pb.gw.go new file mode 100644 index 00000000..0cab5f9f --- /dev/null +++ b/x/oracle/types/tx.pb.gw.go @@ -0,0 +1,337 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: archway/oracle/v1/tx.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +var ( + filter_Msg_AggregateExchangeRatePrevote_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Msg_AggregateExchangeRatePrevote_0(ctx context.Context, marshaler runtime.Marshaler, client MsgClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MsgAggregateExchangeRatePrevote + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_AggregateExchangeRatePrevote_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.AggregateExchangeRatePrevote(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Msg_AggregateExchangeRatePrevote_0(ctx context.Context, marshaler runtime.Marshaler, server MsgServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MsgAggregateExchangeRatePrevote + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_AggregateExchangeRatePrevote_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.AggregateExchangeRatePrevote(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Msg_AggregateExchangeRateVote_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Msg_AggregateExchangeRateVote_0(ctx context.Context, marshaler runtime.Marshaler, client MsgClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MsgAggregateExchangeRateVote + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_AggregateExchangeRateVote_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.AggregateExchangeRateVote(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Msg_AggregateExchangeRateVote_0(ctx context.Context, marshaler runtime.Marshaler, server MsgServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MsgAggregateExchangeRateVote + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_AggregateExchangeRateVote_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.AggregateExchangeRateVote(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Msg_DelegateFeedConsent_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Msg_DelegateFeedConsent_0(ctx context.Context, marshaler runtime.Marshaler, client MsgClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MsgDelegateFeedConsent + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_DelegateFeedConsent_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DelegateFeedConsent(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Msg_DelegateFeedConsent_0(ctx context.Context, marshaler runtime.Marshaler, server MsgServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MsgDelegateFeedConsent + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_DelegateFeedConsent_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.DelegateFeedConsent(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterMsgHandlerServer registers the http handlers for service Msg to "mux". +// UnaryRPC :call MsgServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMsgHandlerFromEndpoint instead. +func RegisterMsgHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MsgServer) error { + + mux.Handle("POST", pattern_Msg_AggregateExchangeRatePrevote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Msg_AggregateExchangeRatePrevote_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Msg_AggregateExchangeRatePrevote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Msg_AggregateExchangeRateVote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Msg_AggregateExchangeRateVote_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Msg_AggregateExchangeRateVote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Msg_DelegateFeedConsent_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Msg_DelegateFeedConsent_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Msg_DelegateFeedConsent_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterMsgHandlerFromEndpoint is same as RegisterMsgHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterMsgHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterMsgHandler(ctx, mux, conn) +} + +// RegisterMsgHandler registers the http handlers for service Msg to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterMsgHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterMsgHandlerClient(ctx, mux, NewMsgClient(conn)) +} + +// RegisterMsgHandlerClient registers the http handlers for service Msg +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MsgClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MsgClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "MsgClient" to call the correct interceptors. +func RegisterMsgHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MsgClient) error { + + mux.Handle("POST", pattern_Msg_AggregateExchangeRatePrevote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Msg_AggregateExchangeRatePrevote_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Msg_AggregateExchangeRatePrevote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Msg_AggregateExchangeRateVote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Msg_AggregateExchangeRateVote_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Msg_AggregateExchangeRateVote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Msg_DelegateFeedConsent_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Msg_DelegateFeedConsent_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Msg_DelegateFeedConsent_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Msg_AggregateExchangeRatePrevote_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"archway", "oracle", "prevote"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Msg_AggregateExchangeRateVote_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"archway", "oracle", "vote"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Msg_DelegateFeedConsent_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"archway", "oracle", "feeder-delegate"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Msg_AggregateExchangeRatePrevote_0 = runtime.ForwardResponseMessage + + forward_Msg_AggregateExchangeRateVote_0 = runtime.ForwardResponseMessage + + forward_Msg_DelegateFeedConsent_0 = runtime.ForwardResponseMessage +) diff --git a/x/oracle/types/vote.go b/x/oracle/types/vote.go new file mode 100644 index 00000000..6ccef5ae --- /dev/null +++ b/x/oracle/types/vote.go @@ -0,0 +1,158 @@ +package types + +import ( + "fmt" + "strings" + + "cosmossdk.io/math" + + "github.com/archway-network/archway/types/set" + "github.com/archway-network/archway/x/oracle/asset" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + ExchangeRateTuplesSeparator = "|" + ExchangeRateTupleStringPrefix = '(' + ExchangeRateTupleStringSuffix = ')' + ExchangeRateTuplePairRateSeparator = "," +) + +// NewAggregateExchangeRatePrevote returns AggregateExchangeRatePrevote object +func NewAggregateExchangeRatePrevote(hash AggregateVoteHash, voter sdk.ValAddress, submitBlock uint64) AggregateExchangeRatePrevote { + return AggregateExchangeRatePrevote{ + Hash: hash.String(), + Voter: voter.String(), + SubmitBlock: submitBlock, + } +} + +// NewAggregateExchangeRateVote creates a AggregateExchangeRateVote instance +func NewAggregateExchangeRateVote(exchangeRateTuples ExchangeRateTuples, voter sdk.ValAddress) AggregateExchangeRateVote { + return AggregateExchangeRateVote{ + ExchangeRateTuples: exchangeRateTuples, + Voter: voter.String(), + } +} + +// NewExchangeRateTuple creates a ExchangeRateTuple instance +func NewExchangeRateTuple(pair asset.Pair, exchangeRate math.LegacyDec) ExchangeRateTuple { + return ExchangeRateTuple{ + pair, + exchangeRate, + } +} + +// ToString converts the ExchangeRateTuple to the vote string. +func (m ExchangeRateTuple) ToString() (string, error) { + err := m.Pair.Validate() + if err != nil { + return "", err + } + + return fmt.Sprintf( + "%c%s%s%s%c", + ExchangeRateTupleStringPrefix, + m.Pair, + ExchangeRateTuplePairRateSeparator, + m.ExchangeRate.String(), + ExchangeRateTupleStringSuffix, + ), nil +} + +// NewExchangeRateTupleFromString populates ExchangeRateTuple from a string, fails if the string is of invalid format. +func NewExchangeRateTupleFromString(s string) (ExchangeRateTuple, error) { + // strip parentheses + if len(s) <= 2 { + return ExchangeRateTuple{}, fmt.Errorf("invalid string length: %v", len(s)) + } + + if s[0] != ExchangeRateTupleStringPrefix || s[len(s)-1] != ExchangeRateTupleStringSuffix { + return ExchangeRateTuple{}, fmt.Errorf("invalid ExchangeRateTuple delimiters, start is expected with '(', end with ')', got: %s", s) + } + + stripParentheses := s[1 : len(s)-1] + split := strings.Split(stripParentheses, ExchangeRateTuplePairRateSeparator) + if len(split) != 2 { + return ExchangeRateTuple{}, fmt.Errorf("invalid ExchangeRateTuple format") + } + + pair, err := asset.TryNewPair(split[0]) + if err != nil { + return ExchangeRateTuple{}, fmt.Errorf("invalid pair definition %s: %w", split[0], err) + } + + dec, err := math.LegacyNewDecFromStr(split[1]) + if err != nil { + return ExchangeRateTuple{}, fmt.Errorf("invalid decimal %s: %w", split[1], err) + } + + return ExchangeRateTuple{ + Pair: pair, + ExchangeRate: dec, + }, nil +} + +// ExchangeRateTuples - array of ExchangeRateTuple +type ExchangeRateTuples []ExchangeRateTuple + +func (tuples ExchangeRateTuples) ToMap() (exchangeRateMap map[asset.Pair]math.LegacyDec) { + exchangeRateMap = make(map[asset.Pair]math.LegacyDec) + for _, tuple := range tuples { + exchangeRateMap[tuple.Pair] = tuple.ExchangeRate + } + return exchangeRateMap +} + +func NewExchangeRateTuplesFromString(s string) (ExchangeRateTuples, error) { + stringTuples := strings.Split(s, ExchangeRateTuplesSeparator) + + tuples := make(ExchangeRateTuples, len(stringTuples)) + + duplicates := make(set.Set[asset.Pair], len(stringTuples)) + + for i, stringTuple := range stringTuples { + exchangeRate, err := NewExchangeRateTupleFromString(stringTuple) + if err != nil { + return []ExchangeRateTuple{}, fmt.Errorf("invalid ExchangeRateTuple at index %d: %w", i, err) + } + + // check duplicates + if duplicates.Has(exchangeRate.Pair) { + // TODO (spekalsg3): why not just ignore a duplicate instead of rejecting the whole msg? + return []ExchangeRateTuple{}, fmt.Errorf("found duplicate at index %d: %s", i, exchangeRate.Pair) + } else { + duplicates.Add(exchangeRate.Pair) + } + + // insert exchange rate into the tuple + tuples[i] = exchangeRate + } + + return tuples, nil +} + +func (tuples ExchangeRateTuples) ToString() (string, error) { + tuplesStringSlice := make([]string, len(tuples)) + for i, r := range tuples { + rStr, err := r.ToString() + if err != nil { + return "", fmt.Errorf("invalid ExchangeRateTuple at index %d: %w", i, err) + } + + tuplesStringSlice[i] = rStr + } + + return strings.Join(tuplesStringSlice, "|"), nil +} + +// ParseExchangeRateTuples ExchangeRateTuple parser +func ParseExchangeRateTuples(tuplesStr string) (ExchangeRateTuples, error) { + tuples, err := NewExchangeRateTuplesFromString(tuplesStr) + if err != nil { + return nil, err + } + + return tuples, nil +} diff --git a/x/oracle/types/vote_test.go b/x/oracle/types/vote_test.go new file mode 100644 index 00000000..04069016 --- /dev/null +++ b/x/oracle/types/vote_test.go @@ -0,0 +1,85 @@ +package types_test + +import ( + "testing" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + "github.com/archway-network/archway/x/oracle/types" +) + +func TestExchangeRateTuples_ToString(t *testing.T) { + t.Run("inverse", func(t *testing.T) { + tuples := types.ExchangeRateTuples{ + { + Pair: "BTC:USD", + ExchangeRate: math.LegacyMustNewDecFromStr("40000.00"), + }, + + { + Pair: "ETH:USD", + ExchangeRate: math.LegacyMustNewDecFromStr("4000.00"), + }, + } + + tuplesStr, err := tuples.ToString() + require.NoError(t, err) + + parsedTuples, err := types.NewExchangeRateTuplesFromString(tuplesStr) + require.NoError(t, err) + + require.Equal(t, tuples, parsedTuples) + }) + + t.Run("check duplicates", func(t *testing.T) { + tuples := types.ExchangeRateTuples{ + { + Pair: "BTC:USD", + ExchangeRate: math.LegacyMustNewDecFromStr("40000.00"), + }, + + { + Pair: "BTC:USD", + ExchangeRate: math.LegacyMustNewDecFromStr("4000.00"), + }, + } + + tuplesStr, err := tuples.ToString() + require.NoError(t, err) + + _, err = types.NewExchangeRateTuplesFromString(tuplesStr) + require.ErrorContains(t, err, "found duplicate") + }) +} + +func TestExchangeRateTuple(t *testing.T) { + t.Run("inverse", func(t *testing.T) { + exchangeRate := types.ExchangeRateTuple{ + Pair: "BTC:USD", + ExchangeRate: math.LegacyMustNewDecFromStr("40000.00"), + } + exchangeRateStr, err := exchangeRate.ToString() + require.NoError(t, err) + + parsedExchangeRate, err := types.NewExchangeRateTupleFromString(exchangeRateStr) + require.NoError(t, err) + + require.Equal(t, exchangeRate, parsedExchangeRate) + }) + + t.Run("invalid size", func(t *testing.T) { + _, err := types.NewExchangeRateTupleFromString("00") + require.ErrorContains(t, err, "invalid string length") + }) + + t.Run("invalid delimiters", func(t *testing.T) { + _, err := types.NewExchangeRateTupleFromString("|1000.0,nibi:usd|") + require.ErrorContains(t, err, "invalid ExchangeRateTuple delimiters") + }) + + t.Run("invalid format", func(t *testing.T) { + _, err := types.NewExchangeRateTupleFromString("(1000.0,nibi:usd,1000.0)") + require.ErrorContains(t, err, "invalid ExchangeRateTuple format") + }) +} diff --git a/x/rewards/ante/fee_deduction.go b/x/rewards/ante/fee_deduction.go index 1512db27..963df3b9 100644 --- a/x/rewards/ante/fee_deduction.go +++ b/x/rewards/ante/fee_deduction.go @@ -173,14 +173,14 @@ func (dfd DeductFeeDecorator) deductFees(ctx sdk.Context, tx sdk.Tx, acc sdk.Acc rebateRatio := dfd.rewardsKeeper.TxFeeRebateRatio(ctx) if rebateRatio.IsZero() || !hasWasmMsgs { if err := dfd.bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), authTypes.FeeCollectorName, fees); err != nil { - return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, err.Error()) + return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, "%s", err.Error()) } return nil } if !flatFees.Empty() { if err := dfd.bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), rewardsTypes.ContractRewardCollector, flatFees); err != nil { - return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, err.Error()) + return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, "%s", err.Error()) } fees = fees.Sub(flatFees...) // reduce flatfees from the sent fees amount } @@ -190,17 +190,17 @@ func (dfd DeductFeeDecorator) deductFees(ctx sdk.Context, tx sdk.Tx, acc sdk.Acc if !authFees.Empty() { if err := dfd.bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), authTypes.FeeCollectorName, authFees); err != nil { - return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, err.Error()) + return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, "%s", err.Error()) } // burn the auth fees. if err := dfd.bankKeeper.BurnCoins(ctx, authTypes.FeeCollectorName, authFees); err != nil { - return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, err.Error()) + return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, "%s", err.Error()) } } if !rewardsFees.Empty() { if err := dfd.bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), rewardsTypes.ContractRewardCollector, rewardsFees); err != nil { - return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, err.Error()) + return errorsmod.Wrapf(sdkErrors.ErrInsufficientFunds, "%s", err.Error()) } } diff --git a/x/rewards/types/tx.pb.go b/x/rewards/types/tx.pb.go index 62cfa71d..328cf953 100644 --- a/x/rewards/types/tx.pb.go +++ b/x/rewards/types/tx.pb.go @@ -469,7 +469,8 @@ var xxx_messageInfo_MsgSetFlatFeeResponse proto.InternalMessageInfo // // Since: archway v5 && cosmos-sdk 0.47 type MsgUpdateParams struct { - // authority is the address that controls the module (defaults to x/gov unless overwritten). + // authority is the address that controls the module (defaults to x/gov unless + // overwritten). Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` // params defines the x/rewards parameters to update. //