From 4921ec9dcf0dcd85e83b70c3ace2218205e8c595 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Wed, 27 Jul 2022 13:27:30 +0200 Subject: [PATCH] chore: merge latest main into 04-channel-upgrades branch (#1788) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: msg types for fee middleware (#1572) * fix broken link * fix: rm AllowUpdateAfter... check (#1118) * update code & test * update proto and adr026 * update CHANGELOG * update cli docs * update broken milestone link * updated docs * update re: comments * nits: adding inline comments Co-authored-by: Sean King * chore: adding module name to incentivized packet events (#1580) * docs: adding events to fee middleware docs (#1578) * adding fee distribution docs for relayer operators * adding validation information and basic cli examples * removing unnecessary whitespace * updating definitions * adding ics29 fee middleware events docs * cleanup Co-authored-by: Sean King * docs: adding End Users section to ics29 docs (#1579) * docs: adding End Users section to ics29 docs * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Carlos Rodriguez * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Carlos Rodriguez * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Carlos Rodriguez * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Carlos Rodriguez * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Carlos Rodriguez * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Carlos Rodriguez * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Carlos Rodriguez * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Carlos Rodriguez * Update docs/middleware/ics29-fee/end-users.md Co-authored-by: Damian Nolan * chore: add link Co-authored-by: Carlos Rodriguez Co-authored-by: Damian Nolan * feat: emitting an event when handling a client upgrade proposal (#1570) * feat: emitting an event when handling a client upgrade proposal * refactor: only emit event if err is nil * refactor: idiotmatic go: * docs: nits (#1595) * docs: document that version string can be empty as argument of RegisterInterchainAccount (#1582) Co-authored-by: Carlos Rodriguez * docs: add upgrade client proposal event (#1596) * Consolidate usage of NewErrorAcknowledgement (#1565) * docs: adding line about module accounts / invariants (#1597) * docs: adding line about module accounts / invariants * Update docs/middleware/ics29-fee/fee-distribution.md Co-authored-by: Damian Nolan * Update docs/middleware/ics29-fee/fee-distribution.md Co-authored-by: Damian Nolan Co-authored-by: Damian Nolan * follow up nits to #1565 (#1598) * delete test files and add error to transfer types * review comments * build(deps): bump github.com/stretchr/testify from 1.7.5 to 1.8.0 (#1616) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.5 to 1.8.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.7.5...v1.8.0) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: bump go package version to v4 (#1564) * chore: bump go package version to v4 * update go.mod * fix alignment * fix build * review comments * build fixes * deps: bumping go version 1.18 (#1627) * bumping go version 1.18 * updating broken workflow setup * add backport to v4.0.x and remove backports to v1 (EoL) (#1629) * delete unused 04-channel version functions (#1636) * delete unused code and associated tests * Update CHANGELOG.md * build(deps): bump github.com/cosmos/cosmos-sdk from 0.45.5 to 0.45.6 (#1615) * build(deps): bump github.com/cosmos/cosmos-sdk from 0.45.5 to 0.45.6 Bumps [github.com/cosmos/cosmos-sdk](https://github.com/cosmos/cosmos-sdk) from 0.45.5 to 0.45.6. - [Release notes](https://github.com/cosmos/cosmos-sdk/releases) - [Changelog](https://github.com/cosmos/cosmos-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/cosmos/cosmos-sdk/compare/v0.45.5...v0.45.6) --- updated-dependencies: - dependency-name: github.com/cosmos/cosmos-sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update CHANGELOG.md * copying part of codeql workflow to try to make it pass Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Carlos Rodriguez Co-authored-by: Carlos Rodriguez * update mergify.yml with new release branches (#1654) * Script to dynamically generate list of e2e tests (E2E #1) (#1644) * Add GitHub actions for e2e tests (E2E #2) (#1646) * Remove crossings hello (#1317) * remove crossing hellos from ChanOpenTry * remove crossing hellos testcase * revert single connectionHops check * add comment in MsgChannelOpenTry tx proto about deprecate field * Update proto/ibc/core/channel/v1/tx.proto Co-authored-by: Aditya * minor fixes && UPDATE CHANGELOG.md * Update proto/ibc/core/channel/v1/tx.proto Co-authored-by: Carlos Rodriguez * Update proto/ibc/core/channel/v1/tx.proto Co-authored-by: Damian Nolan * apply remaining changes for crossing hello removal Deprecate previous channel id with proto tag Remove unnecessary test cases from 04-channel Remove crossing hello check in transfer application and the associated test case * remove previous channel check in WriteChannelOpenTry * regenerate proto files * update documentation * add migration documentation * remove unnecessary doc * remove crossing hello notion from ChanOpenAck * apply review suggestions Co-authored-by: Aditya Co-authored-by: Carlos Rodriguez Co-authored-by: Damian Nolan Co-authored-by: Jacob Gadikian Co-authored-by: Colin Axnér <25233464+colin-axner@users.noreply.github.com> * docs: update roadmap (#1678) * update roadmap * update roadmap * Update roadmap.md Co-authored-by: Carlos Rodriguez * refactor: remove crossing hellos from 03-connection (#1672) * remove crossing hello check from ConnOpenTry and ConnOpenAck * remove unnecessary test cases and fix build * fix tests and add migration docs * fix connection version check in conn open ack * add changelog entry * Update modules/core/03-connection/keeper/handshake.go Co-authored-by: Aditya * remove unnecessary testing function * improve migration documentation as per review suggestion Co-authored-by: Aditya * (core/23-commitment/types) doc: fix typo (#1694) * remove spurious `TestABCICodeDeterminism` tests (#1695) ## Description Thanks @colin-axner for noticing this. closes: #XXXX --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. - [x] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. - [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/structure.md). - [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#testing) - [ ] Updated relevant documentation (`docs/`) or specification (`x//spec/`) - [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). - [ ] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md` - [x] Re-reviewed `Files changed` in the Github PR explorer - [ ] Review `Codecov Report` in the comment section below once CI passes * update bug report issue template (#1693) * fix codeowners for 02-client (#1696) ## Description Thanks again @colin-axner for signaling this! closes: #XXXX --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. - [x] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. - [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/structure.md). - [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#testing) - [ ] Updated relevant documentation (`docs/`) or specification (`x//spec/`) - [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). - [ ] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md` - [x] Re-reviewed `Files changed` in the Github PR explorer - [ ] Review `Codecov Report` in the comment section below once CI passes * build(deps): bump google.golang.org/grpc from 1.47.0 to 1.48.0 (#1699) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.47.0 to 1.48.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.47.0...v1.48.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: update middleware documentation (#1639) * docs: update middleware documentation * remove old text and add func keyword * alignment * fix alignment * Update develop.md * review comments * remove empty line * docs: add links in middleware docs to fee middleware implementation (#1641) * docs: add links in middleware docs to fee middleware implementation * add extra line for better readability * fix typos * Adding github action to run goimports (#1673) * Add E2ETestSuite Type (E2E #3) (#1650) * Separate go mod for e2e (E2E #4) (#1701) * put back module name in event (#1681) * fix typo * Extracting e2e tests into two separate workflows (#1719) * add categories * Add fee middleware test suite functions (E2E #5) (#1710) * Build local image to run tests with make e2e-test (#1722) * Remove leftover crossing hello tests in connection handshake (#1724) * remove leftover crossing hello tests in connection handshake * fix bug in tests * chore: adding environment variable to specify go relayer image (#1727) * Thomas/1584 update docs apps (#1675) * restructure content according to outline, fix image and syntax highlighting, fix titles and prepare for content updates * rewrite bind port section * restructure applications doc into folder structure * add keeper section, make some minor corrections in bind ports, custom packet and implmenent IBC module sections * update ibcmodule interface to encorporate the simpliefied handshake callbacks and version negotiation * fix broken links * fix remaining broken link * fix some nits, correct for removal of crossing hellos and add some more explanation on portIDs * update middleware docs to resolve merge confilicts * update fee mw docs, add formating, fix typos, increase readability (#1665) * update fee mw docs, add formating, fix typos, increase readability * fix broken link * Apply suggestions from code review (De)capitalize headings and references to headings for consistency Co-authored-by: Carlos Rodriguez * resolving merge conflict * split the CLI commands and small typo correction Co-authored-by: Carlos Rodriguez * chore: remove @fedekunze from CODEOWNERS (#1733) * Test for AsyncSingleSender (E2E #6) (#1682) * fix: running e2e-fork for dependabot PRs (#1745) * Adding manual triggering of e2e via workflow dispatch (#1749) * chore: denom traces migration handler (#1680) * update code & test * register migrator service * add changelog entry for #1680 * add issue templates for epics and releases (#1702) * add issue templates for epics and releases * remove text Co-authored-by: Carlos Rodriguez * fix typo * fix typo * feat: allow governance to update the TrustingPeriod of the 07-tendermint light client (#1713) * initial commit * format imports * update docs * update CHANGELOG * update upgrade dev docs * update re: pr comments * E2E Test: TestMsgPayPacketFeeSingleSender (#1756) * move entry to right place * build(deps): bump docker/build-push-action from 3.0.0 to 3.1.0 (#1743) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/e551b19e49efd4e98792db7592c17c09b89db8d8...1cb9d22b932e4832bb29793b7777ec860fc1cde0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Carlos Rodriguez * chore: Update makefile (#1770) * remove unused tools, remove incorrect import formatting * uncomment command in makefile * add version matrix (#1767) * add pseudocode to handle empty version string in OnChanOpenInit * fix broken link (#1776) * add item to update the version matrix after a release (#1775) * E2E Test: TestMsgPayPacketFeeSingleSenderTimesOut (#1751) * Move scripts from .github directory into cmd (#1787) Co-authored-by: Charly Co-authored-by: Sean King Co-authored-by: Sean King Co-authored-by: Carlos Rodriguez Co-authored-by: Carlos Rodriguez Co-authored-by: Cian Hatton Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: vuong <56973102+vuong177@users.noreply.github.com> Co-authored-by: Aditya Co-authored-by: Jacob Gadikian Co-authored-by: Colin Axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: rene <41963722+renaynay@users.noreply.github.com> Co-authored-by: tmsdkeys <98807841+tmsdkeys@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> --- .github/CODEOWNERS | 16 +- .github/ISSUE_TEMPLATE/bug-report.md | 4 + .github/ISSUE_TEMPLATE/epic-tracker.md | 64 + .github/ISSUE_TEMPLATE/release-tracker.md | 66 + .github/mergify.yml | 48 +- .github/scripts/go-imports.sh | 20 + .github/workflows/codeql-analysis.yml | 18 +- .github/workflows/e2e-fork.yml | 50 + .github/workflows/e2e.yaml | 105 ++ .github/workflows/goimports.yaml | 9 + .github/workflows/release.yml | 4 +- .github/workflows/test.yml | 18 +- CHANGELOG.md | 14 +- Dockerfile | 2 +- Makefile | 15 +- RELEASES.md | 15 + cmd/build_test_matrix/main.go | 130 ++ cmd/build_test_matrix/main_test.go | 162 ++ cmd/determine_simd_tag/main.go | 26 + docs/.vuepress/config.js | 294 ++-- .../interchain-accounts/active-channels.md | 6 +- docs/apps/interchain-accounts/auth-modules.md | 8 +- .../adr-002-go-module-versioning.md | 2 +- .../adr-026-ibc-client-recovery-mechanisms.md | 4 + docs/assets/fee-mw/feeflow.png | Bin 0 -> 394717 bytes docs/assets/fee-mw/msgpaypacket.png | Bin 0 -> 150696 bytes docs/assets/fee-mw/paypacketfeeasync.png | Bin 0 -> 142753 bytes docs/assets/fee-mw/registerrelayeraddr.png | Bin 0 -> 157337 bytes docs/ibc/apps.md | 12 +- docs/ibc/apps/apps.md | 51 + docs/ibc/apps/bindports.md | 114 ++ docs/ibc/apps/ibcmodule.md | 342 ++++ docs/ibc/apps/keeper.md | 88 + docs/ibc/apps/packets_acks.md | 99 ++ docs/ibc/apps/routing.md | 36 + docs/ibc/events.md | 5 + docs/ibc/integration.md | 6 +- docs/ibc/middleware/develop.md | 268 ++- docs/ibc/middleware/integration.md | 14 +- docs/ibc/proto-docs.md | 4 +- docs/ibc/upgrades/developer-guide.md | 2 +- docs/middleware/ics29-fee/end-users.md | 30 + docs/middleware/ics29-fee/events.md | 37 + docs/middleware/ics29-fee/fee-distribution.md | 72 +- docs/middleware/ics29-fee/msgs.md | 90 + docs/middleware/ics29-fee/overview.md | 22 +- .../migrations/support-denoms-with-slashes.md | 36 +- docs/migrations/v3-to-v4.md | 41 +- docs/roadmap/roadmap.md | 55 +- e2e/Makefile | 13 + e2e/fee_middleware_test.go | 439 +++++ e2e/go.mod | 142 ++ e2e/go.sum | 1556 +++++++++++++++++ e2e/scripts/run-e2e.sh | 17 + e2e/testconfig/testconfig.go | 93 + e2e/testsuite/relayer.go | 24 + e2e/testsuite/testsuite.go | 340 ++++ e2e/testvalues/values.go | 32 + go.mod | 18 +- go.sum | 107 +- .../27-interchain-accounts/client/cli/cli.go | 4 +- .../controller/client/cli/query.go | 2 +- .../controller/ibc_middleware.go | 17 +- .../controller/ibc_middleware_test.go | 14 +- .../controller/keeper/account.go | 6 +- .../controller/keeper/account_test.go | 8 +- .../controller/keeper/events.go | 31 + .../controller/keeper/genesis.go | 4 +- .../controller/keeper/genesis_test.go | 8 +- .../controller/keeper/grpc_query.go | 2 +- .../controller/keeper/grpc_query_test.go | 2 +- .../controller/keeper/handshake.go | 4 +- .../controller/keeper/handshake_test.go | 8 +- .../controller/keeper/keeper.go | 8 +- .../controller/keeper/keeper_test.go | 6 +- .../controller/keeper/params.go | 2 +- .../controller/keeper/params_test.go | 2 +- .../controller/keeper/relay.go | 6 +- .../controller/keeper/relay_test.go | 10 +- .../controller/types/controller.pb.go | 4 +- .../controller/types/params_test.go | 2 +- .../controller/types/query.pb.go | 14 +- .../host/client/cli/query.go | 8 +- .../27-interchain-accounts/host/ibc_module.go | 14 +- .../host/ibc_module_test.go | 81 +- .../host/keeper/account.go | 2 +- .../host/keeper/account_test.go | 4 +- .../host/keeper/events.go | 20 +- .../host/keeper/genesis.go | 4 +- .../host/keeper/genesis_test.go | 8 +- .../host/keeper/grpc_query.go | 2 +- .../host/keeper/grpc_query_test.go | 2 +- .../host/keeper/handshake.go | 6 +- .../host/keeper/handshake_test.go | 8 +- .../host/keeper/keeper.go | 8 +- .../host/keeper/keeper_test.go | 6 +- .../host/keeper/params.go | 2 +- .../host/keeper/params_test.go | 2 +- .../host/keeper/relay.go | 6 +- .../host/keeper/relay_test.go | 12 +- .../27-interchain-accounts/host/types/ack.go | 27 - .../host/types/ack_test.go | 100 -- .../host/types/host.pb.go | 4 +- .../host/types/params_test.go | 2 +- .../host/types/query.pb.go | 42 +- modules/apps/27-interchain-accounts/module.go | 18 +- .../27-interchain-accounts/module_test.go | 12 +- .../types/account.pb.go | 6 +- .../types/account_test.go | 4 +- .../types/codec_test.go | 4 +- .../27-interchain-accounts/types/events.go | 7 +- .../types/expected_keepers.go | 4 +- .../27-interchain-accounts/types/genesis.go | 6 +- .../types/genesis.pb.go | 88 +- .../types/genesis_test.go | 8 +- .../27-interchain-accounts/types/keys_test.go | 2 +- .../27-interchain-accounts/types/metadata.go | 2 +- .../types/metadata.pb.go | 40 +- .../types/metadata_test.go | 4 +- .../27-interchain-accounts/types/packet.pb.go | 42 +- .../types/packet_test.go | 2 +- .../27-interchain-accounts/types/port_test.go | 4 +- modules/apps/29-fee/client/cli/query.go | 5 +- modules/apps/29-fee/client/cli/tx.go | 4 +- modules/apps/29-fee/fee_test.go | 10 +- modules/apps/29-fee/ibc_middleware.go | 12 +- modules/apps/29-fee/ibc_middleware_test.go | 38 +- modules/apps/29-fee/ica_test.go | 12 +- modules/apps/29-fee/keeper/escrow.go | 4 +- modules/apps/29-fee/keeper/escrow_test.go | 9 +- modules/apps/29-fee/keeper/events.go | 12 +- modules/apps/29-fee/keeper/events_test.go | 2 +- modules/apps/29-fee/keeper/genesis.go | 2 +- modules/apps/29-fee/keeper/genesis_test.go | 6 +- modules/apps/29-fee/keeper/grpc_query.go | 2 +- modules/apps/29-fee/keeper/grpc_query_test.go | 6 +- modules/apps/29-fee/keeper/keeper.go | 6 +- modules/apps/29-fee/keeper/keeper_test.go | 8 +- modules/apps/29-fee/keeper/msg_server.go | 4 +- modules/apps/29-fee/keeper/msg_server_test.go | 10 +- modules/apps/29-fee/keeper/relay.go | 6 +- modules/apps/29-fee/keeper/relay_test.go | 10 +- modules/apps/29-fee/module.go | 6 +- modules/apps/29-fee/transfer_test.go | 8 +- modules/apps/29-fee/types/ack.pb.go | 44 +- modules/apps/29-fee/types/expected_keepers.go | 5 +- modules/apps/29-fee/types/fee.go | 2 +- modules/apps/29-fee/types/fee.pb.go | 32 +- modules/apps/29-fee/types/fee_test.go | 2 +- modules/apps/29-fee/types/genesis.go | 2 +- modules/apps/29-fee/types/genesis.pb.go | 86 +- modules/apps/29-fee/types/genesis_test.go | 6 +- modules/apps/29-fee/types/keys.go | 2 +- modules/apps/29-fee/types/keys_test.go | 6 +- modules/apps/29-fee/types/metadata.pb.go | 4 +- modules/apps/29-fee/types/msgs.go | 4 +- modules/apps/29-fee/types/msgs_test.go | 7 +- modules/apps/29-fee/types/query.pb.go | 172 +- modules/apps/29-fee/types/tx.pb.go | 92 +- modules/apps/transfer/client/cli/query.go | 2 +- modules/apps/transfer/client/cli/tx.go | 6 +- modules/apps/transfer/ibc_module.go | 51 +- modules/apps/transfer/ibc_module_test.go | 14 +- modules/apps/transfer/keeper/MBT_README.md | 2 +- modules/apps/transfer/keeper/encoding.go | 2 +- modules/apps/transfer/keeper/genesis.go | 2 +- modules/apps/transfer/keeper/genesis_test.go | 2 +- modules/apps/transfer/keeper/grpc_query.go | 2 +- .../apps/transfer/keeper/grpc_query_test.go | 4 +- modules/apps/transfer/keeper/keeper.go | 4 +- modules/apps/transfer/keeper/keeper_test.go | 4 +- .../apps/transfer/keeper/mbt_relay_test.go | 10 +- modules/apps/transfer/keeper/migrations.go | 59 + .../apps/transfer/keeper/migrations_test.go | 123 ++ modules/apps/transfer/keeper/msg_server.go | 2 +- modules/apps/transfer/keeper/params.go | 2 +- modules/apps/transfer/keeper/params_test.go | 2 +- modules/apps/transfer/keeper/relay.go | 10 +- modules/apps/transfer/keeper/relay_test.go | 14 +- modules/apps/transfer/module.go | 17 +- modules/apps/transfer/simulation/decoder.go | 2 +- .../apps/transfer/simulation/decoder_test.go | 6 +- modules/apps/transfer/simulation/genesis.go | 2 +- .../apps/transfer/simulation/genesis_test.go | 4 +- modules/apps/transfer/simulation/params.go | 2 +- .../apps/transfer/simulation/params_test.go | 2 +- modules/apps/transfer/transfer_test.go | 6 +- modules/apps/transfer/types/ack.go | 27 - modules/apps/transfer/types/ack_test.go | 73 +- .../apps/transfer/types/expected_keepers.go | 6 +- modules/apps/transfer/types/genesis.go | 2 +- modules/apps/transfer/types/genesis.pb.go | 36 +- modules/apps/transfer/types/genesis_test.go | 2 +- modules/apps/transfer/types/keys_test.go | 2 +- modules/apps/transfer/types/msgs.go | 4 +- modules/apps/transfer/types/msgs_test.go | 2 +- modules/apps/transfer/types/packet.pb.go | 28 +- modules/apps/transfer/types/query.pb.go | 4 +- modules/apps/transfer/types/trace.go | 29 +- modules/apps/transfer/types/trace_test.go | 58 +- modules/apps/transfer/types/transfer.pb.go | 34 +- modules/apps/transfer/types/tx.pb.go | 60 +- modules/core/02-client/abci.go | 6 +- modules/core/02-client/abci_test.go | 12 +- modules/core/02-client/client/cli/cli.go | 2 +- modules/core/02-client/client/cli/query.go | 6 +- modules/core/02-client/client/cli/tx.go | 4 +- .../core/02-client/client/proposal_handler.go | 2 +- modules/core/02-client/client/utils/utils.go | 12 +- modules/core/02-client/genesis.go | 6 +- modules/core/02-client/keeper/client.go | 4 +- modules/core/02-client/keeper/client_test.go | 16 +- modules/core/02-client/keeper/encoding.go | 4 +- modules/core/02-client/keeper/events.go | 17 +- modules/core/02-client/keeper/grpc_query.go | 6 +- .../core/02-client/keeper/grpc_query_test.go | 8 +- modules/core/02-client/keeper/keeper.go | 10 +- modules/core/02-client/keeper/keeper_test.go | 18 +- modules/core/02-client/keeper/migrations.go | 2 +- modules/core/02-client/keeper/params.go | 2 +- modules/core/02-client/keeper/params_test.go | 2 +- modules/core/02-client/keeper/proposal.go | 13 +- .../core/02-client/keeper/proposal_test.go | 8 +- modules/core/02-client/legacy/v100/genesis.go | 8 +- .../02-client/legacy/v100/genesis_test.go | 16 +- .../core/02-client/legacy/v100/solomachine.go | 2 +- .../02-client/legacy/v100/solomachine.pb.go | 172 +- modules/core/02-client/legacy/v100/store.go | 12 +- .../core/02-client/legacy/v100/store_test.go | 12 +- modules/core/02-client/module.go | 4 +- modules/core/02-client/proposal_handler.go | 4 +- .../core/02-client/proposal_handler_test.go | 8 +- modules/core/02-client/simulation/decoder.go | 6 +- .../core/02-client/simulation/decoder_test.go | 10 +- modules/core/02-client/simulation/genesis.go | 2 +- modules/core/02-client/types/client.go | 4 +- modules/core/02-client/types/client.pb.go | 84 +- modules/core/02-client/types/client_test.go | 4 +- modules/core/02-client/types/codec.go | 2 +- modules/core/02-client/types/codec_test.go | 12 +- modules/core/02-client/types/encoding.go | 2 +- modules/core/02-client/types/encoding_test.go | 4 +- modules/core/02-client/types/events.go | 25 +- modules/core/02-client/types/genesis.go | 4 +- modules/core/02-client/types/genesis.pb.go | 64 +- modules/core/02-client/types/genesis_test.go | 16 +- modules/core/02-client/types/height.go | 2 +- modules/core/02-client/types/height_test.go | 2 +- modules/core/02-client/types/keys.go | 2 +- modules/core/02-client/types/keys_test.go | 2 +- modules/core/02-client/types/msgs.go | 4 +- modules/core/02-client/types/msgs_test.go | 12 +- modules/core/02-client/types/params.go | 2 +- modules/core/02-client/types/params_test.go | 2 +- modules/core/02-client/types/proposal.go | 2 +- modules/core/02-client/types/proposal_test.go | 6 +- modules/core/02-client/types/query.go | 2 +- modules/core/02-client/types/query.pb.go | 130 +- modules/core/02-client/types/tx.pb.go | 74 +- modules/core/03-connection/client/cli/cli.go | 2 +- .../core/03-connection/client/cli/query.go | 6 +- .../core/03-connection/client/utils/utils.go | 14 +- modules/core/03-connection/genesis.go | 4 +- modules/core/03-connection/keeper/events.go | 2 +- .../core/03-connection/keeper/grpc_query.go | 6 +- .../03-connection/keeper/grpc_query_test.go | 8 +- .../core/03-connection/keeper/handshake.go | 87 +- .../03-connection/keeper/handshake_test.go | 126 +- modules/core/03-connection/keeper/keeper.go | 10 +- .../core/03-connection/keeper/keeper_test.go | 4 +- modules/core/03-connection/keeper/params.go | 2 +- .../core/03-connection/keeper/params_test.go | 2 +- modules/core/03-connection/keeper/verify.go | 4 +- .../core/03-connection/keeper/verify_test.go | 16 +- modules/core/03-connection/module.go | 4 +- .../core/03-connection/simulation/decoder.go | 4 +- .../03-connection/simulation/decoder_test.go | 8 +- .../core/03-connection/simulation/genesis.go | 2 +- modules/core/03-connection/types/codec.go | 2 +- .../core/03-connection/types/connection.go | 6 +- .../core/03-connection/types/connection.pb.go | 95 +- .../03-connection/types/connection_test.go | 8 +- modules/core/03-connection/types/events.go | 2 +- .../03-connection/types/expected_keepers.go | 2 +- modules/core/03-connection/types/genesis.go | 2 +- .../core/03-connection/types/genesis.pb.go | 48 +- .../core/03-connection/types/genesis_test.go | 6 +- modules/core/03-connection/types/keys.go | 2 +- modules/core/03-connection/types/keys_test.go | 2 +- modules/core/03-connection/types/msgs.go | 8 +- modules/core/03-connection/types/msgs_test.go | 12 +- .../core/03-connection/types/params_test.go | 2 +- modules/core/03-connection/types/query.go | 4 +- modules/core/03-connection/types/query.pb.go | 106 +- modules/core/03-connection/types/tx.pb.go | 124 +- modules/core/03-connection/types/version.go | 6 +- .../core/03-connection/types/version_test.go | 8 +- modules/core/04-channel/client/cli/cli.go | 2 +- modules/core/04-channel/client/cli/query.go | 6 +- modules/core/04-channel/client/utils/utils.go | 12 +- modules/core/04-channel/genesis.go | 4 +- modules/core/04-channel/keeper/events.go | 4 +- modules/core/04-channel/keeper/grpc_query.go | 8 +- .../core/04-channel/keeper/grpc_query_test.go | 10 +- modules/core/04-channel/keeper/handshake.go | 82 +- .../core/04-channel/keeper/handshake_test.go | 52 +- modules/core/04-channel/keeper/keeper.go | 12 +- modules/core/04-channel/keeper/keeper_test.go | 6 +- modules/core/04-channel/keeper/packet.go | 10 +- modules/core/04-channel/keeper/packet_test.go | 16 +- modules/core/04-channel/keeper/timeout.go | 8 +- .../core/04-channel/keeper/timeout_test.go | 12 +- modules/core/04-channel/module.go | 4 +- modules/core/04-channel/simulation/decoder.go | 4 +- .../04-channel/simulation/decoder_test.go | 8 +- modules/core/04-channel/simulation/genesis.go | 2 +- .../core/04-channel/types/acknowledgement.go | 15 +- .../04-channel/types/acknowledgement_test.go | 85 +- modules/core/04-channel/types/channel.go | 4 +- modules/core/04-channel/types/channel.pb.go | 114 +- modules/core/04-channel/types/channel_test.go | 2 +- modules/core/04-channel/types/codec.go | 2 +- modules/core/04-channel/types/events.go | 2 +- .../core/04-channel/types/expected_keepers.go | 4 +- modules/core/04-channel/types/genesis.go | 2 +- modules/core/04-channel/types/genesis.pb.go | 62 +- modules/core/04-channel/types/genesis_test.go | 2 +- modules/core/04-channel/types/keys.go | 2 +- modules/core/04-channel/types/keys_test.go | 2 +- modules/core/04-channel/types/msgs.go | 6 +- modules/core/04-channel/types/msgs_test.go | 10 +- modules/core/04-channel/types/packet.go | 6 +- modules/core/04-channel/types/packet_test.go | 4 +- modules/core/04-channel/types/query.go | 4 +- modules/core/04-channel/types/query.pb.go | 186 +- modules/core/04-channel/types/tx.pb.go | 191 +- modules/core/04-channel/types/upgrade.pb.go | 8 +- modules/core/04-channel/types/version.go | 27 - modules/core/04-channel/types/version_test.go | 77 - modules/core/05-port/keeper/keeper.go | 4 +- modules/core/05-port/keeper/keeper_test.go | 4 +- modules/core/05-port/module.go | 4 +- modules/core/05-port/types/module.go | 4 +- modules/core/05-port/types/query.pb.go | 2 +- modules/core/23-commitment/types/codec.go | 2 +- .../core/23-commitment/types/commitment.pb.go | 44 +- modules/core/23-commitment/types/merkle.go | 4 +- .../core/23-commitment/types/merkle_test.go | 2 +- .../core/23-commitment/types/utils_test.go | 2 +- modules/core/24-host/keys.go | 2 +- modules/core/24-host/parse_test.go | 4 +- modules/core/ante/ante.go | 6 +- modules/core/ante/ante_test.go | 12 +- modules/core/client/cli/cli.go | 8 +- modules/core/client/query.go | 6 +- modules/core/genesis.go | 10 +- modules/core/genesis_test.go | 22 +- modules/core/keeper/grpc_query.go | 6 +- modules/core/keeper/keeper.go | 16 +- modules/core/keeper/keeper_test.go | 9 +- modules/core/keeper/migrations.go | 2 +- modules/core/keeper/msg_server.go | 14 +- modules/core/keeper/msg_server_test.go | 18 +- modules/core/legacy/v100/genesis.go | 10 +- modules/core/legacy/v100/genesis_test.go | 18 +- modules/core/module.go | 20 +- modules/core/simulation/decoder.go | 10 +- modules/core/simulation/decoder_test.go | 14 +- modules/core/simulation/genesis.go | 16 +- modules/core/simulation/genesis_test.go | 6 +- modules/core/types/codec.go | 14 +- modules/core/types/genesis.go | 6 +- modules/core/types/genesis.pb.go | 46 +- modules/core/types/query.go | 12 +- .../light-clients/06-solomachine/module.go | 2 +- .../06-solomachine/types/client_state.go | 8 +- .../06-solomachine/types/client_state_test.go | 16 +- .../06-solomachine/types/codec.go | 4 +- .../06-solomachine/types/codec_test.go | 10 +- .../06-solomachine/types/consensus_state.go | 4 +- .../types/consensus_state_test.go | 6 +- .../06-solomachine/types/header.go | 4 +- .../06-solomachine/types/header_test.go | 6 +- .../06-solomachine/types/misbehaviour.go | 6 +- .../types/misbehaviour_handle.go | 4 +- .../types/misbehaviour_handle_test.go | 8 +- .../06-solomachine/types/misbehaviour_test.go | 6 +- .../06-solomachine/types/proof.go | 10 +- .../06-solomachine/types/proof_test.go | 6 +- .../06-solomachine/types/proposal_handle.go | 4 +- .../types/proposal_handle_test.go | 8 +- .../06-solomachine/types/solomachine.go | 2 +- .../06-solomachine/types/solomachine.pb.go | 172 +- .../06-solomachine/types/solomachine_test.go | 8 +- .../06-solomachine/types/update.go | 4 +- .../06-solomachine/types/update_test.go | 8 +- modules/light-clients/07-tendermint/module.go | 2 +- .../07-tendermint/types/client_state.go | 12 +- .../07-tendermint/types/client_state_test.go | 16 +- .../07-tendermint/types/codec.go | 2 +- .../07-tendermint/types/consensus_state.go | 6 +- .../types/consensus_state_test.go | 6 +- .../07-tendermint/types/genesis.go | 4 +- .../07-tendermint/types/genesis_test.go | 6 +- .../07-tendermint/types/header.go | 6 +- .../07-tendermint/types/header_test.go | 6 +- .../07-tendermint/types/misbehaviour.go | 6 +- .../types/misbehaviour_handle.go | 4 +- .../types/misbehaviour_handle_test.go | 10 +- .../07-tendermint/types/misbehaviour_test.go | 10 +- .../07-tendermint/types/proposal_handle.go | 12 +- .../types/proposal_handle_test.go | 67 +- .../07-tendermint/types/store.go | 6 +- .../07-tendermint/types/store_test.go | 14 +- .../07-tendermint/types/tendermint.pb.go | 142 +- .../07-tendermint/types/tendermint_test.go | 10 +- .../07-tendermint/types/update.go | 6 +- .../07-tendermint/types/update_test.go | 12 +- .../07-tendermint/types/upgrade.go | 6 +- .../07-tendermint/types/upgrade_test.go | 10 +- modules/light-clients/09-localhost/module.go | 2 +- .../09-localhost/types/client_state.go | 10 +- .../09-localhost/types/client_state_test.go | 16 +- .../light-clients/09-localhost/types/codec.go | 2 +- .../09-localhost/types/localhost.pb.go | 6 +- .../09-localhost/types/localhost_test.go | 6 +- proto/ibc/applications/fee/v1/ack.proto | 2 +- proto/ibc/applications/fee/v1/fee.proto | 2 +- proto/ibc/applications/fee/v1/genesis.proto | 2 +- proto/ibc/applications/fee/v1/metadata.proto | 2 +- proto/ibc/applications/fee/v1/query.proto | 2 +- proto/ibc/applications/fee/v1/tx.proto | 2 +- .../controller/v1/controller.proto | 2 +- .../controller/v1/query.proto | 2 +- .../interchain_accounts/host/v1/host.proto | 2 +- .../interchain_accounts/host/v1/query.proto | 2 +- .../interchain_accounts/v1/account.proto | 2 +- .../interchain_accounts/v1/genesis.proto | 2 +- .../interchain_accounts/v1/metadata.proto | 2 +- .../interchain_accounts/v1/packet.proto | 2 +- .../applications/transfer/v1/genesis.proto | 2 +- .../ibc/applications/transfer/v1/query.proto | 2 +- .../applications/transfer/v1/transfer.proto | 2 +- proto/ibc/applications/transfer/v1/tx.proto | 2 +- .../ibc/applications/transfer/v2/packet.proto | 2 +- proto/ibc/core/channel/v1/channel.proto | 2 +- proto/ibc/core/channel/v1/genesis.proto | 2 +- proto/ibc/core/channel/v1/query.proto | 2 +- proto/ibc/core/channel/v1/tx.proto | 7 +- proto/ibc/core/channel/v1/upgrade.proto | 2 +- proto/ibc/core/client/v1/client.proto | 2 +- proto/ibc/core/client/v1/genesis.proto | 2 +- proto/ibc/core/client/v1/query.proto | 2 +- proto/ibc/core/client/v1/tx.proto | 2 +- proto/ibc/core/commitment/v1/commitment.proto | 2 +- proto/ibc/core/connection/v1/connection.proto | 2 +- proto/ibc/core/connection/v1/genesis.proto | 2 +- proto/ibc/core/connection/v1/query.proto | 2 +- proto/ibc/core/connection/v1/tx.proto | 17 +- proto/ibc/core/types/v1/genesis.proto | 2 +- .../lightclients/localhost/v1/localhost.proto | 2 +- .../solomachine/v1/solomachine.proto | 2 +- .../solomachine/v2/solomachine.proto | 2 +- .../tendermint/v1/tendermint.proto | 2 +- testing/README.md | 4 +- testing/app.go | 4 +- testing/chain.go | 16 +- testing/chain_test.go | 3 +- testing/config.go | 10 +- testing/coordinator.go | 39 - testing/endpoint.go | 14 +- testing/events.go | 6 +- testing/mock/ibc_app.go | 4 +- testing/mock/ibc_module.go | 6 +- testing/mock/ibc_module_test.go | 6 +- testing/mock/mock.go | 9 +- testing/mock/privval_test.go | 2 +- testing/path.go | 2 +- testing/sdk_test.go | 6 +- testing/simapp/ante_handler.go | 4 +- testing/simapp/app.go | 52 +- testing/simapp/encoding.go | 2 +- testing/simapp/genesis_account_test.go | 2 +- testing/simapp/sim_bench_test.go | 2 +- testing/simapp/sim_test.go | 6 +- testing/simapp/simd/cmd/cmd_test.go | 4 +- testing/simapp/simd/cmd/genaccounts_test.go | 4 +- testing/simapp/simd/cmd/root.go | 4 +- testing/simapp/simd/main.go | 4 +- testing/simapp/state.go | 2 +- testing/simapp/test_helpers.go | 2 +- testing/simapp/utils.go | 2 +- testing/solomachine.go | 10 +- testing/values.go | 12 +- 494 files changed, 7864 insertions(+), 3762 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/epic-tracker.md create mode 100644 .github/ISSUE_TEMPLATE/release-tracker.md create mode 100755 .github/scripts/go-imports.sh create mode 100644 .github/workflows/e2e-fork.yml create mode 100644 .github/workflows/e2e.yaml create mode 100644 .github/workflows/goimports.yaml create mode 100644 cmd/build_test_matrix/main.go create mode 100644 cmd/build_test_matrix/main_test.go create mode 100644 cmd/determine_simd_tag/main.go create mode 100644 docs/assets/fee-mw/feeflow.png create mode 100644 docs/assets/fee-mw/msgpaypacket.png create mode 100644 docs/assets/fee-mw/paypacketfeeasync.png create mode 100644 docs/assets/fee-mw/registerrelayeraddr.png create mode 100644 docs/ibc/apps/apps.md create mode 100644 docs/ibc/apps/bindports.md create mode 100644 docs/ibc/apps/ibcmodule.md create mode 100644 docs/ibc/apps/keeper.md create mode 100644 docs/ibc/apps/packets_acks.md create mode 100644 docs/ibc/apps/routing.md create mode 100644 docs/middleware/ics29-fee/end-users.md create mode 100644 docs/middleware/ics29-fee/events.md create mode 100644 docs/middleware/ics29-fee/msgs.md create mode 100644 e2e/Makefile create mode 100644 e2e/fee_middleware_test.go create mode 100644 e2e/go.mod create mode 100644 e2e/go.sum create mode 100755 e2e/scripts/run-e2e.sh create mode 100644 e2e/testconfig/testconfig.go create mode 100644 e2e/testsuite/relayer.go create mode 100644 e2e/testsuite/testsuite.go create mode 100644 e2e/testvalues/values.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/events.go delete mode 100644 modules/apps/27-interchain-accounts/host/types/ack.go delete mode 100644 modules/apps/27-interchain-accounts/host/types/ack_test.go create mode 100644 modules/apps/transfer/keeper/migrations.go create mode 100644 modules/apps/transfer/keeper/migrations_test.go delete mode 100644 modules/apps/transfer/types/ack.go delete mode 100644 modules/core/04-channel/types/version.go delete mode 100644 modules/core/04-channel/types/version_test.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f6569b64ddd..13e9c5c254c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,23 +13,23 @@ # CODEOWNERS for the core IBC module -/modules/core/ @colin-axner @fedekunze @AdityaSripal -/proto/ibc/core/ @colin-axner @fedekunze @AdityaSripal +/modules/core/ @colin-axner @AdityaSripal +/proto/ibc/core/ @colin-axner @AdityaSripal ## CODEOWNERS for core/02-client -/modules/core/02-client @seantking @damiannolan -/proto/ibc/core/client @seantking @damiannolan +/modules/core/02-client @colin-axner @AdityaSripal @seantking @damiannolan +/proto/ibc/core/client @colin-axner @AdityaSripal @seantking @damiannolan # CODEOWNERS for the light-clients -/modules/light-clients/ @colin-axner @fedekunze @AdityaSripal @seantking @damiannolan -/proto/ibc/lightclients/ @colin-axner @fedekunze @AdityaSripal @seantking @damiannolan +/modules/light-clients/ @colin-axner @AdityaSripal @seantking @damiannolan +/proto/ibc/lightclients/ @colin-axner @AdityaSripal @seantking @damiannolan # CODEOWNERS for ICS 20 -/modules/apps/transfer/ @colin-axner @fedekunze @AdityaSripal -/proto/ibc/applications/transfer/ @colin-axner @fedekunze @AdityaSripal +/modules/apps/transfer/ @colin-axner @AdityaSripal +/proto/ibc/applications/transfer/ @colin-axner @AdityaSripal # CODEOWNERS for interchain-accounts module diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 5bdfad7c29a..9cb089d1f23 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -20,6 +20,10 @@ through the appropriate channels won't receive any bounty. +## Expected Behaviour + + + ## Version diff --git a/.github/ISSUE_TEMPLATE/epic-tracker.md b/.github/ISSUE_TEMPLATE/epic-tracker.md new file mode 100644 index 00000000000..df3f553ff49 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/epic-tracker.md @@ -0,0 +1,64 @@ +--- +name: Epic Tracker +about: Create an issue to track feature epic progress + +--- + + + +## Requirements document + + + +## IBC spec + + + +## ADRs + + + +## Milestones + + + +## Implementation issues + + + +## QA scenarios + + + +## Automated e2e tests + + + +## Pre-releases + + + +## Checklist + + + +- [ ] Internal audit(s) +- [ ] External audit(s) +- [ ] Documentation +- [ ] Swagger +- [ ] Integration with relayers: + - [ ] Hermes + - [ ] Rly + +____ + +#### For Admin Use + +- [ ] Not duplicate issue +- [ ] Appropriate labels applied +- [ ] Appropriate contributors tagged/assigned diff --git a/.github/ISSUE_TEMPLATE/release-tracker.md b/.github/ISSUE_TEMPLATE/release-tracker.md new file mode 100644 index 00000000000..873f4e487ab --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release-tracker.md @@ -0,0 +1,66 @@ +--- +name: Release tracker +about: Create an issue to track release progress + +--- + + + +## Milestones + + + +### IBC spec compatibility + + + +### QA + +#### Backwards compatibility + + + +- [ ] Fungible token transfers over a non-incentivised channel works with a counterparty chain running each previous major version. +- [ ] Fungible token transfers over an incentivised channel works with a counterparty chain running each previous major version that supports ICS-29 Fee Middleware. +- [ ] Interchain Accounts over a non-incentivised channel works with a counterparty chain running each previous major version that supports ICS-27 Interchain Accounts over non-incentivised channels. +- [ ] Interchain Accounts over an incentivised channel works with a counterparty chain running each previous major version that supports ICS-27 Interchain Accounts over incentivised channels. + +### Migration + + + +## Checklist + + + +- [ ] Bump [go package version](https://github.com/cosmos/ibc-go/blob/main/go.mod#L3). +- [ ] Change all imports starting with `github.com/cosmos/ibc-go/v{x}` to `github.com/cosmos/ibc-go/v{x+1}`. +- [ ] Branch off main to create release branch in the form of `release/vx.y.z`. +- [ ] Add branch protection rules to new release branch. +- [ ] Add backport task to [`mergify.yml`](https://github.com/cosmos/ibc-go/blob/main/.github/mergify.yml) +- [ ] Upgrade ibc-go version in [ibctest](https://github.com/strangelove-ventures/ibctest). +- [ ] Check Swagger is up-to-date. + +## Post-release checklist + +- [ ] Update [`CHANGELOG.md`](https://github.com/cosmos/ibc-go/blob/main/CHANGELOG.md) +- [ ] Update the table of supported release lines (and End of Life dates) in [`RELEASES.md`](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md). +- [ ] Update [version matrix](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md#version-matrix) in `RELEASES.md`. +- [ ] Update docs site: + - [ ] Add new release branch to [`docs/versions`](https://github.com/cosmos/ibc-go/blob/main/docs/versions) file. + - [ ] Add `label` and `key` to `versions` array in [`config.js`](https://github.com/cosmos/ibc-go/blob/main/docs/.vuepress/config.js#L33). +- [ ] After changes to docs site are deployed, check [ibc.cosmos.network](https://ibc.cosmos.network) is updated. + +____ + +#### For Admin Use + +- [ ] Not duplicate issue +- [ ] Appropriate labels applied +- [ ] Appropriate contributors tagged/assigned diff --git a/.github/mergify.yml b/.github/mergify.yml index 868594d1d57..2dfc4653a7d 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -18,67 +18,67 @@ pull_request_rules: commit_message_template: | {{ title }} (#{{ number }}) {{ body }} - - name: backport patches to v1.3.x branch + - name: backport patches to v2.1.x branch conditions: - base=main - - label=backport-to-v1.3.x + - label=backport-to-v2.1.x actions: backport: branches: - - release/v1.3.x - - name: backport patches to v1.4.x branch + - release/v2.1.x + - name: backport patches to v2.2.x branch conditions: - base=main - - label=backport-to-v1.4.x + - label=backport-to-v2.2.x actions: backport: branches: - - release/v1.4.x - - name: backport patches to v1.5.x branch + - release/v2.2.x + - name: backport patches to v2.3.x branch conditions: - base=main - - label=backport-to-v1.5.x + - label=backport-to-v2.3.x actions: backport: branches: - - release/v1.5.x - - name: backport patches to v2.1.x branch + - release/v2.3.x + - name: backport patches to v2.4.x branch conditions: - base=main - - label=backport-to-v2.1.x + - label=backport-to-v2.4.x actions: backport: branches: - - release/v2.1.x - - name: backport patches to v2.2.x branch + - release/v2.4.x + - name: backport patches to v3.0.x branch conditions: - base=main - - label=backport-to-v2.2.x + - label=backport-to-v3.0.x actions: backport: branches: - - release/v2.2.x - - name: backport patches to v2.3.x branch + - release/v3.0.x + - name: backport patches to v3.1.x branch conditions: - base=main - - label=backport-to-v2.3.x + - label=backport-to-v3.1.x actions: backport: branches: - - release/v2.3.x - - name: backport patches to v3.0.x branch + - release/v3.1.x + - name: backport patches to v3.2.x branch conditions: - base=main - - label=backport-to-v3.0.x + - label=backport-to-v3.2.x actions: backport: branches: - - release/v3.0.x - - name: backport patches to v3.1.x branch + - release/v3.2.x + - name: backport patches to v4.0.x branch conditions: - base=main - - label=backport-to-v3.1.x + - label=backport-to-v4.0.x actions: backport: branches: - - release/v3.1.x + - release/v4.0.x diff --git a/.github/scripts/go-imports.sh b/.github/scripts/go-imports.sh new file mode 100755 index 00000000000..bc5e6db3f86 --- /dev/null +++ b/.github/scripts/go-imports.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +formatted_files="$(docker run -v "$(pwd)":/ibc-go --rm -w "/ibc-go" --entrypoint="" cytopia/goimports goimports -l -local 'github.com/cosmos/ibc-go' /ibc-go)" + +exit_code=0 +for f in $formatted_files +do + # we don't care about formatting in pb.go files. + if [ "${f: -5}" == "pb.go" ]; then + continue + fi + exit_code=1 + echo "formatted file ${f}..." +done + +if [ "${exit_code}" == 1 ]; then + echo "not all files were correctly formated, run the following:" + echo "make goimports" +fi + +exit $exit_code diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index aaf7c7b8db3..f9a7c4a9230 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -56,9 +56,25 @@ jobs: # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main + queries: crypto-com/cosmos-sdk-codeql@main,security-and-quality if: env.GIT_DIFF + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) - - run: make build + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + if: env.GIT_DIFF + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/e2e-fork.yml b/.github/workflows/e2e-fork.yml new file mode 100644 index 00000000000..d3717d2c35a --- /dev/null +++ b/.github/workflows/e2e-fork.yml @@ -0,0 +1,50 @@ +name: Tests / E2E Fork +on: + workflow_dispatch: + pull_request: + branches: + - main + paths-ignore: + - docs/** + +jobs: + # dynamically build a matrix of test/test suite pairs to run + build-test-matrix: + if: ${{ github.event.pull_request.head.repo.fork || github.actor == 'dependabot[bot]' || github.event_name == 'workflow_dispatch' }} + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - id: set-matrix + run: echo "::set-output name=matrix::$(go run cmd/build_test_matrix/main.go)" + + e2e: + env: + SIMD_TAG: latest + SIMD_IMAGE: ibc-go-simd-e2e + if: ${{ github.event.pull_request.head.repo.fork || github.actor == 'dependabot[bot]' || github.event_name == 'workflow_dispatch' }} + needs: + - build-test-matrix + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.build-test-matrix.outputs.matrix) }} + steps: + - uses: actions/checkout@v3 + - name: Docker Build + run: docker build . -t "${SIMD_IMAGE}:${SIMD_TAG}" + - name: Setup Go + uses: actions/setup-go@v3 + with: + go-version: 1.18 + - name: Run e2e Test + env: + # see images here https://github.com/cosmos/relayer/pkgs/container/relayer/versions + RLY_TAG: "v2.0.0-rc2" + run: | + cd e2e + make e2e-test suite=${{ matrix.suite }} test=${{ matrix.test }} diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml new file mode 100644 index 00000000000..ae4d29e7b51 --- /dev/null +++ b/.github/workflows/e2e.yaml @@ -0,0 +1,105 @@ +name: Tests / E2E +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + paths-ignore: + - docs/** + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ibc-go-simd-e2e + +jobs: + docker-build: + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Log in to the Container registry + uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@69f6fc9d46f2f8bf0d5491e4aabe0bb8c6a4678a + with: + images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@1cb9d22b932e4832bb29793b7777ec860fc1cde0 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + # dynamically build a matrix of test/test suite pairs to run + build-test-matrix: + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - id: set-matrix + run: echo "::set-output name=matrix::$(go run cmd/build_test_matrix/main.go)" + + + # the tag of the image will differ if this is a PR or the branch is being merged into main. + # we store the tag as an environment variable and use it in the E2E tests to determine the tag. + determine-image-tag: + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} + runs-on: ubuntu-latest + outputs: + simd-tag: ${{ steps.get-tag.outputs.simd-tag }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - id: get-tag + run: | + tag=$(go run cmd/determine_simd_tag/main.go -pr "${{ github.event.pull_request.number }}" ) + echo "Using tag $tag" + echo "::set-output name=simd-tag::$tag" + + + e2e: + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} + runs-on: ubuntu-latest + needs: + - build-test-matrix + - determine-image-tag + - docker-build + env: + SIMD_TAG: ${{ needs.determine-image-tag.outputs.simd-tag }} + SIMD_IMAGE: ghcr.io/cosmos/ibc-go-simd-e2e + # see images here https://github.com/cosmos/relayer/pkgs/container/relayer/versions + RLY_TAG: "v2.0.0-rc2" + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.build-test-matrix.outputs.matrix) }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - name: Log in to the Container registry + uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Run e2e Test + run: | + cd e2e + make e2e-test suite=${{ matrix.suite }} test=${{ matrix.test }} diff --git a/.github/workflows/goimports.yaml b/.github/workflows/goimports.yaml new file mode 100644 index 00000000000..b951b17aa1d --- /dev/null +++ b/.github/workflows/goimports.yaml @@ -0,0 +1,9 @@ +name: Goimports +on: pull_request +jobs: + goimports: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: "Go Imports" + run: .github/scripts/go-imports.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f59f0c63d25..06b11e26d46 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: '1.17' + go-version: '1.18' - name: Release uses: goreleaser/goreleaser-action@v3 @@ -46,7 +46,7 @@ jobs: images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }} - name: Build and push Docker image - uses: docker/build-push-action@e551b19e49efd4e98792db7592c17c09b89db8d8 + uses: docker/build-push-action@1cb9d22b932e4832bb29793b7777ec860fc1cde0 with: context: . push: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d6e00030df0..09add80b02b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,7 @@ on: push: branches: - main + jobs: cleanup-runs: runs-on: ubuntu-latest @@ -20,12 +21,12 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.17 + go-version: 1.18 - name: Display go version run: go version - name: install tparse run: | - export GO111MODULE="on" && go get github.com/mfridman/tparse@v0.8.3 + go install github.com/mfridman/tparse@v0.8.3 - uses: actions/cache@v3 with: path: ~/go/bin @@ -40,7 +41,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.17 + go-version: 1.18 - uses: technote-space/get-diff-action@v6.1.0 id: git_diff with: @@ -51,13 +52,6 @@ jobs: - name: Build run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make build - docker-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Docker Build - run: docker build . --no-cache - split-test-files: runs-on: ubuntu-latest steps: @@ -95,7 +89,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.17 + go-version: 1.18 - uses: technote-space/get-diff-action@v6.1.0 with: PATTERNS: | @@ -108,7 +102,7 @@ jobs: if: env.GIT_DIFF - name: test & coverage report creation run: | - cat pkgs.txt.part.${{ matrix.part }} | xargs go test -race -mod=readonly -timeout 30m -coverprofile=${{ matrix.part }}profile.out -covermode=atomic -tags='ledger test_ledger_mock' + cat pkgs.txt.part.${{ matrix.part }} | xargs go test $(go list ./... | grep -v e2e) -race -mod=readonly -timeout 30m -coverprofile=${{ matrix.part }}profile.out -covermode=atomic -tags='ledger test_ledger_mock' if: env.GIT_DIFF - uses: actions/upload-artifact@v3 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index cb6e080f5f4..41c31d738fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,26 +38,38 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Dependencies -* [\#1525](https://github.com/cosmos/ibc-go/pull/1525) Bump SDK version to v0.45.5 +* [\#1615](https://github.com/cosmos/ibc-go/pull/1615) Bump SDK version to v0.45.6 +* [\#1627](https://github.com/cosmos/ibc-go/pull/1627) Bump Go version to 1.18 ### API Breaking +* (modules/core/03-connection) [\#1672](https://github.com/cosmos/ibc-go/pull/1672) Remove crossing hellos from connection handshakes. The `PreviousConnectionId` in `MsgConnectionOpenTry` has been deprecated. +* (modules/core/04-channel) [\#1317](https://github.com/cosmos/ibc-go/pull/1317) Remove crossing hellos from channel handshakes. The `PreviousChannelId` in `MsgChannelOpenTry` has been deprecated. * (transfer) [\#1250](https://github.com/cosmos/ibc-go/pull/1250) Deprecate `GetTransferAccount` since the `transfer` module account is never used. * (channel) [\#1283](https://github.com/cosmos/ibc-go/pull/1283) The `OnChanOpenInit` application callback now returns a version string in line with the latest [spec changes](https://github.com/cosmos/ibc/pull/629). * (modules/29-fee)[\#1338](https://github.com/cosmos/ibc-go/pull/1338) Renaming `Result` field in `IncentivizedAcknowledgement` to `AppAcknowledgement`. * (modules/29-fee)[\#1343](https://github.com/cosmos/ibc-go/pull/1343) Renaming `KeyForwardRelayerAddress` to `KeyRelayerAddressForAsyncAck`, and `ParseKeyForwardRelayerAddress` to `ParseKeyRelayerAddressForAsyncAck`. * (apps/27-interchain-accounts)[\#1432](https://github.com/cosmos/ibc-go/pull/1432) Updating `RegisterInterchainAccount` to include an additional `version` argument, supporting ICS29 fee middleware functionality in ICS27 interchain accounts. +* (apps/27-interchain-accounts)[\#1565](https://github.com/cosmos/ibc-go/pull/1565) Removing `NewErrorAcknowledgement` in favour of `channeltypes.NewErrorAcknowledgement`. +* (transfer)[\#1565](https://github.com/cosmos/ibc-go/pull/1565) Removing `NewErrorAcknowledgement` in favour of `channeltypes.NewErrorAcknowledgement`. +* (channel)[\#1565](https://github.com/cosmos/ibc-go/pull/1565) Updating `NewErrorAcknowledgement` to accept an error instead of a string and removing the possibility of non-deterministic writes to application state. +* (core/04-channel)[\#1636](https://github.com/cosmos/ibc-go/pull/1636) Removing `SplitChannelVersion` and `MergeChannelVersions` functions since they are not used. ### State Machine Breaking ### Improvements +* (app/20-transfer) [\#1680](https://github.com/cosmos/ibc-go/pull/1680) Adds migration to correct any malformed trace path information of tokens with denoms that contains slashes. The transfer module consensus version has been bumped to 2. +* (app/20-transfer) [\#1730](https://github.com/cosmos/ibc-go/pull/1730) parse the ics20 denomination provided via a packet using the channel identifier format specified by ibc-go. * (cleanup) [\#1335](https://github.com/cosmos/ibc-go/pull/1335/) `gofumpt -w -l .` to standardize the code layout more strictly than `go fmt ./...` * (middleware) [\#1022](https://github.com/cosmos/ibc-go/pull/1022) Add `GetAppVersion` to the ICS4Wrapper interface. This function should be used by IBC applications to obtain their own version since the version set in the channel structure may be wrapped many times by middleware. * (modules/core/04-channel) [\#1232](https://github.com/cosmos/ibc-go/pull/1232) Updating params on `NewPacketId` and moving to bottom of file. * (app/29-fee) [\#1305](https://github.com/cosmos/ibc-go/pull/1305) Change version string for fee module to `ics29-1` * (app/29-fee) [\#1341](https://github.com/cosmos/ibc-go/pull/1341) Check if the fee module is locked and if the fee module is enabled before refunding all fees +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. * (testing/simapp) [\#1397](https://github.com/cosmos/ibc-go/pull/1397) Adding mock module to maccperms and adding check to ensure mock module is not a blocked account address. +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (modules/light-clients/07-tendermint) [\#1713](https://github.com/cosmos/ibc-go/pull/1713) Allow client upgrade proposals to update `TrustingPeriod`. See ADR-026 for context. ### Features diff --git a/Dockerfile b/Dockerfile index eb044d5eaf9..a193f54906e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17 as builder +FROM golang:1.18 as builder ENV GOPATH="" ENV GOMODULE="on" diff --git a/Makefile b/Makefile index 0ea7f0c10c5..eba4b5c2de2 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ PACKAGES_NOSIMULATION=$(shell go list ./... | grep -v '/simulation') PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation') +CHANGED_GO_FILES := $(shell git diff --name-only | grep .go$$ | grep -v pb.go) +ALL_GO_FILES := $(shell find . -regex ".*\.go$$" | grep -v pb.go) VERSION := $(shell echo $(shell git describe --always) | sed 's/^v//') COMMIT := $(shell git log -1 --format='%H') LEDGER_ENABLED ?= true @@ -91,7 +93,7 @@ ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS))) BUILD_FLAGS += -trimpath endif -all: tools build lint test +all: build lint test # The below include contains the tools and runsim targets. #include contrib/devtools/Makefile @@ -154,7 +156,7 @@ mocks: $(MOCKS_DIR) $(MOCKS_DIR): mkdir -p $(MOCKS_DIR) -distclean: clean tools-clean +distclean: clean clean: rm -rf \ $(BUILDDIR)/ \ @@ -335,12 +337,17 @@ lint-fix: golangci-lint run --fix --out-format=tab --issues-exit-code=0 .PHONY: lint lint-fix -format: +format: goimports find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs gofmt -w -s find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs misspell -w - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs goimports -w -local github.com/cosmos/cosmos-sdk .PHONY: format +goimports: + $(DOCKER) run -v $(CURDIR):/ibc-go --rm -w "/ibc-go" cytopia/goimports -w -local 'github.com/cosmos/ibc-go' "$(CHANGED_GO_FILES)" &> /dev/null || echo "No changed go files to format" + +goimports-all: + $(DOCKER) run -v $(CURDIR):/ibc-go --rm -w "/ibc-go" cytopia/goimports -w -local 'github.com/cosmos/ibc-go' "$(ALL_GO_FILES)" + ############################################################################### ### Devdoc ### ############################################################################### diff --git a/RELEASES.md b/RELEASES.md index cb8ccb18224..9adabdc61f9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -97,6 +97,21 @@ As rule of thumb, the following changes will **NOT** be automatically accepted i * **API-breaking changes**, i.e. changes that prevent client applications to *build without modifications* to the client application's source code. * **CLI-breaking changes**, i.e. changes that require usage changes for CLI users. +## Version matrix + +Versions of Golang, Cosmos SDK and Tendermint used by ibc-go in the currently active releases: + +| Go | ibc-go | Cosmos SDK | Tendermint | +|----|--------|------------|------------| +| 1.15 | v2.1.0 | v0.44.6 | v0.34.14 | +| 1.15 | v2.1.1 | v0.44.8 | v0.34.19 | +| 1.15 | v2.2.0 | v0.45.1 | v0.34.14 | +| 1.15 | v2.2.1 | v0.45.1 | v0.34.14 | +| 1.17 | v2.3.0 | v0.45.4 | v0.34.19 | +| 1.17 | v3.0.0 | v0.45.1 | v0.34.14 | +| 1.17 | v3.0.1 | v0.45.4 | v0.34.19 | +| 1.17 | v3.1.0 | v0.45.4 | v0.34.19 | + ## Graphics The decision tree above was generated with the following code: diff --git a/cmd/build_test_matrix/main.go b/cmd/build_test_matrix/main.go new file mode 100644 index 00000000000..c86324b31f8 --- /dev/null +++ b/cmd/build_test_matrix/main.go @@ -0,0 +1,130 @@ +package main + +import ( + "encoding/json" + "fmt" + "go/ast" + "go/parser" + "go/token" + "io/fs" + "os" + "path/filepath" + "strings" +) + +const ( + testNamePrefix = "Test" + testFileNameSuffix = "_test.go" + e2eTestDirectory = "e2e" +) + +// GithubActionTestMatrix represents +type GithubActionTestMatrix struct { + Include []TestSuitePair `json:"include"` +} + +type TestSuitePair struct { + Test string `json:"test"` + Suite string `json:"suite"` +} + +func main() { + githubActionMatrix, err := getGithubActionMatrixForTests(e2eTestDirectory) + if err != nil { + fmt.Printf("error generating github action json: %s", err) + os.Exit(1) + } + + ghBytes, err := json.Marshal(githubActionMatrix) + if err != nil { + fmt.Printf("error marshalling github action json: %s", err) + os.Exit(1) + } + fmt.Println(string(ghBytes)) +} + +// getGithubActionMatrixForTests returns a json string representing the contents that should go in the matrix +// field in a github action workflow. This string can be used with `fromJSON(str)` to dynamically build +// the workflow matrix to include all E2E tests under the e2eRootDirectory directory. +func getGithubActionMatrixForTests(e2eRootDirectory string) (GithubActionTestMatrix, error) { + testSuiteMapping := map[string][]string{} + fset := token.NewFileSet() + err := filepath.Walk(e2eRootDirectory, func(path string, info fs.FileInfo, err error) error { + // only look at test files + if !strings.HasSuffix(path, testFileNameSuffix) { + return nil + } + + f, err := parser.ParseFile(fset, path, nil, 0) + if err != nil { + return fmt.Errorf("failed parsing file: %s", err) + } + + suiteNameForFile, testCases, err := extractSuiteAndTestNames(f) + if err != nil { + return fmt.Errorf("failed extracting test suite name and test cases: %s", err) + } + + testSuiteMapping[suiteNameForFile] = testCases + + return nil + }) + + if err != nil { + return GithubActionTestMatrix{}, err + } + + gh := GithubActionTestMatrix{ + Include: []TestSuitePair{}, + } + + for testSuiteName, testCases := range testSuiteMapping { + for _, testCaseName := range testCases { + gh.Include = append(gh.Include, TestSuitePair{ + Test: testCaseName, + Suite: testSuiteName, + }) + } + } + + return gh, nil +} + +// extractSuiteAndTestNames extracts the name of the test suite function as well +// as all tests associated with it in the same file. +func extractSuiteAndTestNames(file *ast.File) (string, []string, error) { + var suiteNameForFile string + var testCases []string + + for _, d := range file.Decls { + if f, ok := d.(*ast.FuncDecl); ok { + functionName := f.Name.Name + if isTestSuiteMethod(f) { + if suiteNameForFile != "" { + return "", nil, fmt.Errorf("found a second test function: %s when %s was already found", f.Name.Name, suiteNameForFile) + } + suiteNameForFile = functionName + continue + } + if isTestFunction(f) { + testCases = append(testCases, functionName) + } + } + } + if suiteNameForFile == "" { + return "", nil, fmt.Errorf("file %s had no test suite test case", file.Name.Name) + } + return suiteNameForFile, testCases, nil +} + +// isTestSuiteMethod returns true if the function is a test suite function. +// e.g. func TestFeeMiddlewareTestSuite(t *testing.T) { ... } +func isTestSuiteMethod(f *ast.FuncDecl) bool { + return strings.HasPrefix(f.Name.Name, testNamePrefix) && len(f.Type.Params.List) == 1 +} + +// isTestFunction returns true if the function name starts with "Test" and has no parameters. +// as test suite functions do not accept a *testing.T. +func isTestFunction(f *ast.FuncDecl) bool { + return strings.HasPrefix(f.Name.Name, testNamePrefix) && len(f.Type.Params.List) == 0 +} diff --git a/cmd/build_test_matrix/main_test.go b/cmd/build_test_matrix/main_test.go new file mode 100644 index 00000000000..47de4d981c2 --- /dev/null +++ b/cmd/build_test_matrix/main_test.go @@ -0,0 +1,162 @@ +package main + +import ( + "os" + "path" + "sort" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + nonTestFile = "not_test_file.go" + goTestFileNameOne = "first_go_file_test.go" + goTestFileNameTwo = "second_go_file_test.go" +) + +func TestGetGithubActionMatrixForTests(t *testing.T) { + t.Run("empty dir does not fail", func(t *testing.T) { + testingDir := t.TempDir() + _, err := getGithubActionMatrixForTests(testingDir) + assert.NoError(t, err) + }) + + t.Run("only test functions are picked up", func(t *testing.T) { + testingDir := t.TempDir() + createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) + + gh, err := getGithubActionMatrixForTests(testingDir) + assert.NoError(t, err) + + expected := GithubActionTestMatrix{ + Include: []TestSuitePair{ + { + Suite: "TestFeeMiddlewareTestSuite", + Test: "TestA", + }, + { + Suite: "TestFeeMiddlewareTestSuite", + Test: "TestB", + }, + }, + } + assertGithubActionTestMatricesEqual(t, expected, gh) + }) + + t.Run("all files are picked up", func(t *testing.T) { + testingDir := t.TempDir() + createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) + createFileWithTestSuiteAndTests(t, "TransferTestSuite", "TestC", "TestD", testingDir, goTestFileNameTwo) + + gh, err := getGithubActionMatrixForTests(testingDir) + assert.NoError(t, err) + + expected := GithubActionTestMatrix{ + Include: []TestSuitePair{ + { + Suite: "TestTransferTestSuite", + Test: "TestC", + }, + { + Suite: "TestFeeMiddlewareTestSuite", + Test: "TestA", + }, + { + Suite: "TestFeeMiddlewareTestSuite", + Test: "TestB", + }, + { + Suite: "TestTransferTestSuite", + Test: "TestD", + }, + }, + } + + assertGithubActionTestMatricesEqual(t, expected, gh) + }) + + t.Run("non test files are not picked up", func(t *testing.T) { + testingDir := t.TempDir() + createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, nonTestFile) + + gh, err := getGithubActionMatrixForTests(testingDir) + assert.NoError(t, err) + assert.Empty(t, gh.Include) + }) + + t.Run("fails when there are multiple suite runs", func(t *testing.T) { + testingDir := t.TempDir() + createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, nonTestFile) + + fileWithTwoSuites := `package foo +func SuiteOne(t *testing.T) { + suite.Run(t, new(FeeMiddlewareTestSuite)) +} + +func SuiteTwo(t *testing.T) { + suite.Run(t, new(FeeMiddlewareTestSuite)) +} + +type FeeMiddlewareTestSuite struct {} +` + + err := os.WriteFile(path.Join(testingDir, goTestFileNameOne), []byte(fileWithTwoSuites), os.FileMode(777)) + assert.NoError(t, err) + + _, err = getGithubActionMatrixForTests(testingDir) + assert.Error(t, err) + }) +} + +func assertGithubActionTestMatricesEqual(t *testing.T, expected, actual GithubActionTestMatrix) { + // sort by both suite and test as the order of the end result does not matter as + // all tests will be run. + sort.SliceStable(expected.Include, func(i, j int) bool { + memberI := expected.Include[i] + memberJ := expected.Include[j] + if memberI.Suite == memberJ.Suite { + return memberI.Test < memberJ.Test + } + return memberI.Suite < memberJ.Suite + }) + + sort.SliceStable(actual.Include, func(i, j int) bool { + memberI := actual.Include[i] + memberJ := actual.Include[j] + if memberI.Suite == memberJ.Suite { + return memberI.Test < memberJ.Test + } + return memberI.Suite < memberJ.Suite + }) + assert.Equal(t, expected.Include, actual.Include) +} + +func goTestFileContents(suiteName, fnName1, fnName2 string) string { + + replacedSuiteName := strings.ReplaceAll(`package foo + +func TestSuiteName(t *testing.T) { + suite.Run(t, new(SuiteName)) +} + +type SuiteName struct {} + +func (s *SuiteName) fnName1() {} +func (s *SuiteName) fnName2() {} + +func (s *SuiteName) suiteHelper() {} + +func helper() {} +`, "SuiteName", suiteName) + + replacedFn1Name := strings.ReplaceAll(replacedSuiteName, "fnName1", fnName1) + return strings.ReplaceAll(replacedFn1Name, "fnName2", fnName2) +} + +func createFileWithTestSuiteAndTests(t *testing.T, suiteName, fn1Name, fn2Name, dir, filename string) { + goFileContents := goTestFileContents(suiteName, fn1Name, fn2Name) + err := os.WriteFile(path.Join(dir, filename), []byte(goFileContents), os.FileMode(777)) + assert.NoError(t, err) +} diff --git a/cmd/determine_simd_tag/main.go b/cmd/determine_simd_tag/main.go new file mode 100644 index 00000000000..af3a6281268 --- /dev/null +++ b/cmd/determine_simd_tag/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "flag" + "fmt" +) + +var prNum string + +func init() { + flag.StringVar(&prNum, "pr", "", "the number of the pr") + flag.Parse() +} + +// in the context of a GithubAction workflow, the PR is non empty if it is a pr. When +// code is merged to main, it will be empty. In this case we just use the "main" tag. +func main() { + fmt.Printf(getSimdTag(prNum)) +} + +func getSimdTag(prNum string) string { + if prNum == "" { + return "main" + } + return fmt.Sprintf("pr-%s", prNum) +} diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index e748d200226..f459a997da6 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -3,19 +3,48 @@ module.exports = { title: "IBC-Go", locales: { "/": { - lang: "en-US" + lang: "en-US", }, }, base: process.env.VUEPRESS_BASE || "/", head: [ - ['link', { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png" }], - ['link', { rel: "icon", type: "image/png", sizes: "32x32", href: "/favicon-32x32.png" }], - ['link', { rel: "icon", type: "image/png", sizes: "16x16", href: "/favicon-16x16.png" }], - ['link', { rel: "manifest", href: "/site.webmanifest" }], - ['meta', { name: "msapplication-TileColor", content: "#2e3148" }], - ['meta', { name: "theme-color", content: "#ffffff" }], - ['link', { rel: "icon", type: "image/svg+xml", href: "/favicon-svg.svg" }], - ['link', { rel: "apple-touch-icon-precomposed", href: "/apple-touch-icon-precomposed.png" }], + [ + "link", + { + rel: "apple-touch-icon", + sizes: "180x180", + href: "/apple-touch-icon.png", + }, + ], + [ + "link", + { + rel: "icon", + type: "image/png", + sizes: "32x32", + href: "/favicon-32x32.png", + }, + ], + [ + "link", + { + rel: "icon", + type: "image/png", + sizes: "16x16", + href: "/favicon-16x16.png", + }, + ], + ["link", { rel: "manifest", href: "/site.webmanifest" }], + ["meta", { name: "msapplication-TileColor", content: "#2e3148" }], + ["meta", { name: "theme-color", content: "#ffffff" }], + ["link", { rel: "icon", type: "image/svg+xml", href: "/favicon-svg.svg" }], + [ + "link", + { + rel: "apple-touch-icon-precomposed", + href: "/apple-touch-icon-precomposed.png", + }, + ], ], themeConfig: { repo: "cosmos/ibc-go", @@ -32,109 +61,109 @@ module.exports = { //}, versions: [ { - "label": "main", - "key": "main" + label: "main", + key: "main", }, { - "label": "v1.1.0", - "key": "v1.1.0" + label: "v1.1.0", + key: "v1.1.0", }, { - "label": "v1.2.0", - "key": "v1.2.0" + label: "v1.2.0", + key: "v1.2.0", }, { - "label": "v1.3.0", - "key": "v1.3.0" + label: "v1.3.0", + key: "v1.3.0", }, { - "label": "v1.5.0", - "key": "v1.5.0" + label: "v1.5.0", + key: "v1.5.0", }, { - "label": "v1.4.0", - "key": "v1.4.0" + label: "v1.4.0", + key: "v1.4.0", }, { - "label": "v2.0.0", - "key": "v2.0.0" - } , + label: "v2.0.0", + key: "v2.0.0", + }, { - "label": "v2.1.0", - "key": "v2.1.0" - }, - { - "label": "v2.2.0", - "key": "v2.2.0" + label: "v2.1.0", + key: "v2.1.0", }, - { - "label": "v2.3.0", - "key": "v2.3.0" + { + label: "v2.2.0", + key: "v2.2.0", + }, + { + label: "v2.3.0", + key: "v2.3.0", }, { - "label": "v3.0.0", - "key": "v3.0.0" + label: "v3.0.0", + key: "v3.0.0", }, { - "label": "v3.1.0", - "key": "v3.1.0" - } + label: "v3.1.0", + key: "v3.1.0", + }, ], topbar: { - banner: true + banner: true, }, - sidebar: { + sidebar: { auto: false, nav: [ - { + { title: "Using IBC-Go", children: [ { title: "Overview", directory: false, - path: "/ibc/overview.html" - }, + path: "/ibc/overview.html", + }, { title: "Integration", directory: false, - path: "/ibc/integration.html" + path: "/ibc/integration.html", }, { title: "Applications", - directory: false, - path: "/ibc/apps.html" + directory: true, + path: "/ibc/apps", }, { title: "Middleware", directory: true, - path: "/ibc/middleware" + path: "/ibc/middleware", }, { title: "Upgrades", directory: true, - path: "/ibc/upgrades" + path: "/ibc/upgrades", }, { title: "Governance Proposals", directory: false, - path: "/ibc/proposals.html" + path: "/ibc/proposals.html", }, { title: "Relayer", directory: false, - path: "/ibc/relayer.html" + path: "/ibc/relayer.html", }, { title: "Protobuf Documentation", directory: false, - path: "/ibc/proto-docs.html" + path: "/ibc/proto-docs.html", }, { title: "Roadmap", directory: false, - path: "/roadmap/roadmap.html" + path: "/roadmap/roadmap.html", }, - ] + ], }, { title: "IBC Application Modules", @@ -147,34 +176,34 @@ module.exports = { { title: "Overview", directory: false, - path: "/apps/interchain-accounts/overview.html" - }, + path: "/apps/interchain-accounts/overview.html", + }, { title: "Authentication Modules", directory: false, - path: "/apps/interchain-accounts/auth-modules.html" + path: "/apps/interchain-accounts/auth-modules.html", }, { title: "Active Channels", directory: false, - path: "/apps/interchain-accounts/active-channels.html" + path: "/apps/interchain-accounts/active-channels.html", }, { title: "Integration", directory: false, - path: "/apps/interchain-accounts/integration.html" + path: "/apps/interchain-accounts/integration.html", }, { title: "Parameters", directory: false, - path: "/apps/interchain-accounts/parameters.html" + path: "/apps/interchain-accounts/parameters.html", }, { title: "Transactions", directory: false, - path: "/apps/interchain-accounts/transactions.html" + path: "/apps/interchain-accounts/transactions.html", }, - ] + ], }, { title: "Transfer", @@ -184,109 +213,125 @@ module.exports = { { title: "Overview", directory: false, - path: "/apps/transfer/overview.html" - }, + path: "/apps/transfer/overview.html", + }, { title: "State", directory: false, - path: "/apps/transfer/state.html" + path: "/apps/transfer/state.html", }, { title: "State Transitions", directory: false, - path: "/apps/transfer/state-transitions.html" + path: "/apps/transfer/state-transitions.html", }, { title: "Messages", directory: false, - path: "/apps/transfer/messages.html" + path: "/apps/transfer/messages.html", }, { title: "Events", directory: false, - path: "/apps/transfer/events.html" + path: "/apps/transfer/events.html", }, { title: "Metrics", directory: false, - path: "/apps/transfer/metrics.html" + path: "/apps/transfer/metrics.html", }, { title: "Params", directory: false, - path: "/apps/transfer/params.html" + path: "/apps/transfer/params.html", }, - ] + ], }, - ] + ], }, { title: "IBC Middleware Modules", children: [ { - title: "ICS29 Fee Middleware", + title: "Fee Middleware", directory: true, path: "/middleware", children: [ { title: "Overview", directory: false, - path: "/middleware/ics29-fee/overview.html" - }, + path: "/middleware/ics29-fee/overview.html", + }, { title: "Integration", directory: false, - path: "/middleware/ics29-fee/integration.html" + path: "/middleware/ics29-fee/integration.html", + }, + { + title: "Fee Messages", + directory: false, + path: "/middleware/ics29-fee/msgs.html", }, { title: "Fee Distribution", directory: false, - path: "/middleware/ics29-fee/fee-distribution.html" + path: "/middleware/ics29-fee/fee-distribution.html", }, - ] + { + title: "Events", + directory: false, + path: "/middleware/ics29-fee/events.html", + }, + { + title: "End Users", + directory: false, + path: "/middleware/ics29-fee/end-users.html", + }, + ], }, - ] + ], }, { title: "Migrations", children: [ { - title: "Support transfer of coins whose base denom contains slashes", + title: + "Support transfer of coins whose base denom contains slashes", directory: false, - path: "/migrations/support-denoms-with-slashes.html" + path: "/migrations/support-denoms-with-slashes.html", }, { title: "SDK v0.43 to IBC-Go v1", directory: false, - path: "/migrations/sdk-to-v1.html" + path: "/migrations/sdk-to-v1.html", }, { title: "IBC-Go v1 to v2", directory: false, - path: "/migrations/v1-to-v2.html" + path: "/migrations/v1-to-v2.html", }, { title: "IBC-Go v2 to v3", directory: false, - path: "/migrations/v2-to-v3.html" + path: "/migrations/v2-to-v3.html", }, { title: "IBC-Go v3 to v4", directory: false, - path: "/migrations/v3-to-v4.html" + path: "/migrations/v3-to-v4.html", }, - ] + ], }, { title: "Resources", children: [ { title: "IBC Specification", - path: "https://github.com/cosmos/ibc" + path: "https://github.com/cosmos/ibc", }, - ] - } - ] + ], + }, + ], }, gutter: { title: "Help & Support", @@ -295,46 +340,46 @@ module.exports = { title: "Discord", text: "Chat with IBC developers on Discord.", url: "https://discordapp.com/channels/669268347736686612", - bg: "linear-gradient(225.11deg, #2E3148 0%, #161931 95.68%)" + bg: "linear-gradient(225.11deg, #2E3148 0%, #161931 95.68%)", }, github: { title: "Found an Issue?", - text: "Help us improve this page by suggesting edits on GitHub." - } + text: "Help us improve this page by suggesting edits on GitHub.", + }, }, footer: { question: { - text: "Chat with IBC developers in Discord." + text: "Chat with IBC developers in Discord.", }, textLink: { text: "ibcprotocol.org", - url: "https://ibcprotocol.org" + url: "https://ibcprotocol.org", }, services: [ { service: "medium", - url: "https://blog.cosmos.network/" + url: "https://blog.cosmos.network/", }, { service: "twitter", - url: "https://twitter.com/cosmos" + url: "https://twitter.com/cosmos", }, { service: "linkedin", - url: "https://www.linkedin.com/company/interchain-gmbh" + url: "https://www.linkedin.com/company/interchain-gmbh", }, { service: "reddit", - url: "https://reddit.com/r/cosmosnetwork" + url: "https://reddit.com/r/cosmosnetwork", }, { service: "telegram", - url: "https://t.me/cosmosproject" + url: "https://t.me/cosmosproject", }, { service: "youtube", - url: "https://www.youtube.com/c/CosmosProject" - } + url: "https://www.youtube.com/c/CosmosProject", + }, ], smallprint: "The development of IBC-Go is led primarily by [Interchain GmbH](https://interchain.berlin/). Funding for this development comes primarily from the Interchain Foundation, a Swiss non-profit.", @@ -344,64 +389,63 @@ module.exports = { children: [ { title: "Cosmos SDK", - url: "https://docs.cosmos.network" + url: "https://docs.cosmos.network", }, { title: "Cosmos Hub", - url: "https://hub.cosmos.network" + url: "https://hub.cosmos.network", }, { title: "Tendermint Core", - url: "https://docs.tendermint.com" - } - ] + url: "https://docs.tendermint.com", + }, + ], }, { title: "Community", children: [ { title: "Cosmos blog", - url: "https://blog.cosmos.network" + url: "https://blog.cosmos.network", }, { title: "Forum", - url: "https://forum.cosmos.network" + url: "https://forum.cosmos.network", }, { title: "Chat", - url: "https://discord.gg/W8trcGV" - } - ] + url: "https://discord.gg/W8trcGV", + }, + ], }, { title: "Contributing", children: [ { title: "Contributing to the docs", - url: - "https://github.com/cosmos/ibc-go/blob/main/docs/DOCS_README.md" + url: "https://github.com/cosmos/ibc-go/blob/main/docs/DOCS_README.md", }, { title: "Source code on GitHub", - url: "https://github.com/cosmos/ibc-go/" - } - ] - } - ] - } + url: "https://github.com/cosmos/ibc-go/", + }, + ], + }, + ], + }, }, plugins: [ [ "@vuepress/google-analytics", { - ga: "UA-51029217-2" - } + ga: "UA-51029217-2", + }, ], [ "sitemap", { - hostname: "https://ibc.cosmos.network" - } - ] - ] + hostname: "https://ibc.cosmos.network", + }, + ], + ], }; diff --git a/docs/apps/interchain-accounts/active-channels.md b/docs/apps/interchain-accounts/active-channels.md index c574ea87d85..d387bdea038 100644 --- a/docs/apps/interchain-accounts/active-channels.md +++ b/docs/apps/interchain-accounts/active-channels.md @@ -12,11 +12,11 @@ channel type that provides ordering of packets without the channel closing on ti When an Interchain Account is registered using the `RegisterInterchainAccount` API, a new channel is created on a particular port. During the `OnChanOpenAck` and `OnChanOpenConfirm` steps (controller & host chain) the `Active Channel` for this interchain account is stored in state. -It is possible to create a new channel using the same controller chain portID if the previously set `Active Channel` is now in a `CLOSED` state. This channel creation can be initialized programatically by sending a new `OnChanOpenInit` message like so: +It is possible to create a new channel using the same controller chain portID if the previously set `Active Channel` is now in a `CLOSED` state. This channel creation can be initialized programatically by sending a new `MsgChannelOpenInit` message like so: ```go - msg := channeltypes.NewMsgChannelOpenInit(portID, string(versionBytes), channeltypes.ORDERED, []string{connectionID}, icatypes.PortID, icatypes.ModuleName) - handler := k.msgRouter.Handler(msg) +msg := channeltypes.NewMsgChannelOpenInit(portID, string(versionBytes), channeltypes.ORDERED, []string{connectionID}, icatypes.PortID, icatypes.ModuleName) +handler := k.msgRouter.Handler(msg) ``` Alternatively, any relayer operator may initiate a new channel handshake for this interchain account once the previously set `Active Channel` is in a `CLOSED` state. This is done by initiating the channel handshake on the controller chain using the same portID associated with the interchain account in question. diff --git a/docs/apps/interchain-accounts/auth-modules.md b/docs/apps/interchain-accounts/auth-modules.md index fdff2385282..5d75409b3c4 100644 --- a/docs/apps/interchain-accounts/auth-modules.md +++ b/docs/apps/interchain-accounts/auth-modules.md @@ -38,15 +38,15 @@ func (im IBCModule) OnChanOpenInit( chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string, -) error { +) (string, error) { // the authentication module *must* claim the channel capability on OnChanOpenInit if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return err + return version, err } // perform custom logic - return nil + return version, nil } // OnChanOpenAck implements the IBCModule interface @@ -157,7 +157,7 @@ if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID return nil ``` -The `version` argument is used to support ICS29 fee middleware for relayer incentivization of ICS27 packets. Consumers of the `RegisterInterchainAccount` are expected to build the appropriate JSON encoded version string themselves and pass it accordingly. +The `version` argument is used to support ICS29 fee middleware for relayer incentivization of ICS27 packets. Consumers of the `RegisterInterchainAccount` are expected to build the appropriate JSON encoded version string themselves and pass it accordingly. If an empty string is passed in the `version` argument, then the version will be initialized to a default value in the `OnChanOpenInit` callback of the controller's handler, so that channel handshake can proceed. The following code snippet illustrates how to construct an appropriate interchain accounts `Metadata` and encode it as a JSON bytestring: diff --git a/docs/architecture/adr-002-go-module-versioning.md b/docs/architecture/adr-002-go-module-versioning.md index 28207d5474d..a046792b142 100644 --- a/docs/architecture/adr-002-go-module-versioning.md +++ b/docs/architecture/adr-002-go-module-versioning.md @@ -72,7 +72,7 @@ This prevents the Go module version from being incremented with breaking changes It also requires all extended functions to live in the same Go module, disrupting the existing code structure. The version that implements this change will still be incompatible with previous versions, but future versions could be imported together without namespace collisions. -For example, lets say this solution is implmented in v3. Then +For example, lets say this solution is implemented in v3. Then `github.com/cosmos/ibc-go/v2` cannot be imported with any other ibc-go version diff --git a/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md b/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md index 516002ed1b9..bec25a3aad9 100644 --- a/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md +++ b/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md @@ -7,6 +7,7 @@ - 2021/01/15: Revision to support substitute clients for unfreezing - 2021/05/20: Revision to simplify consensus state copying, remove initial height - 2022/04/08: Revision to deprecate AllowUpdateAfterExpiry and AllowUpdateAfterMisbehaviour +- 2022/07/15: Revision to allow updating of TrustingPeriod ## Status @@ -51,6 +52,9 @@ We elect not to deal with chains which have actually halted, which is necessaril Previously, `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehaviour` were used to signal the recovery options for an expired or frozen client, and governance proposals were not allowed to overwrite the client if these parameters were set to false. However, this has now been deprecated because a code migration can overwrite the client and consensus states regardless of the value of these parameters. If governance would vote to overwrite a client or consensus state, it is likely that governance would also be willing to perform a code migration to do the same. + In addition, `TrustingPeriod` was initally not allowed to be updated by a client upgrade proposal. However, due to the number of situations experienced in production where the `TrustingPeriod` of a client should be allowed to be updated because of ie: initial misconfiguration for a canonical channel, governance should be allowed to update this client parameter. + + Note that this should NOT be lightly updated, as there may be a gap in time between when misbehaviour has occured and when the evidence of misbehaviour is submitted. For example, if the `UnbondingPeriod` is 2 weeks and the `TrustingPeriod` has also been set to two weeks, a validator could wait until right before `UnbondingPeriod` finishes, submit false information, then unbond and exit without being slashed for misbehaviour. Therefore, we recommend that the trusting period for the 07-tendermint client be set to 2/3 of the `UnbondingPeriod`. Note that clients frozen due to misbehaviour must wait for the evidence to expire to avoid becoming refrozen. diff --git a/docs/assets/fee-mw/feeflow.png b/docs/assets/fee-mw/feeflow.png new file mode 100644 index 0000000000000000000000000000000000000000..ba02071f4d8e8132ac527c279cf32da9d9dbe24d GIT binary patch literal 394717 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