From 6852832fe86ff159878f16264fb5f8d2ef14cd285442dfe94554ea4852257643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mukan=20Erkin=20T=C3=B6r=C3=BCk?= Date: Mon, 11 May 2026 03:18:28 +0300 Subject: [PATCH] initial: sovereign Mukan Network fork --- .clang-format | 116 + .github/.codespellignore | 2 + .github/ISSUE_TEMPLATE/bug-report.md | 42 + .github/ISSUE_TEMPLATE/epic-tracker.md | 64 + .github/ISSUE_TEMPLATE/feature-request.md | 40 + .github/ISSUE_TEMPLATE/release-tracker.md | 83 + .github/PULL_REQUEST_TEMPLATE.md | 41 + .github/dependabot.yml | 39 + .github/mergify.yml | 84 + .../workflows/build-simd-image-from-tag.yml | 42 + .../build-wasm-simd-image-from-tag.yml | 108 + .github/workflows/codeql-analysis.yml | 81 + .github/workflows/docker.yml | 70 + .github/workflows/docs-check.yml | 36 + .github/workflows/docs-deploy.yml | 34 + .../e2e-compatibility-workflow-call.yaml | 74 + .github/workflows/e2e-compatibility.yaml | 230 + .github/workflows/e2e-test-workflow-call.yml | 279 + .github/workflows/e2e-upgrade.yaml | 82 + .github/workflows/e2e.yaml | 118 + .github/workflows/golangci.yml | 31 + .github/workflows/proto-breaking-check.yml | 16 + .github/workflows/proto-registry.yml | 28 + .github/workflows/test.yml | 86 + .gitignore | 5 + .golangci.yml | 139 + CHANGELOG.md | 1829 ++ CODE_OF_CONDUCT.md | 46 + CONTRIBUTING.md | 78 + Dockerfile | 36 + LICENSE | 674 + Makefile | 407 + README.md | 30 + RELEASES.md | 163 + SECURITY.md | 16 + buf.work.yaml | 8 + cmd/build_test_matrix/main.go | 195 + cmd/build_test_matrix/main_test.go | 191 + codecov.yml | 24 + contrib/devtools/Makefile | 76 + contrib/test_cover.sh | 14 + docs/.gitignore | 20 + docs/.markdownlint-cli2.jsonc | 7 + docs/.markdownlint.jsonc | 27 + docs/README.md | 289 + docs/architecture/README.md | 48 + .../adr-001-coin-source-tracing.md | 375 + .../adr-002-go-module-versioning.md | 112 + .../adr-003-ics27-acknowledgement.md | 120 + .../adr-004-ics29-lock-fee-module.md | 58 + .../adr-005-consensus-height-events.md | 92 + .../adr-006-02-client-refactor.md | 203 + .../adr-007-solomachine-signbytes.md | 52 + docs/architecture/adr-008-app-caller-cbs.md | 569 + .../adr-009-v6-ics27-msgserver.md | 115 + .../adr-010-light-clients-as-sdk-modules.md | 106 + ...r-011-transfer-total-escrow-state-entry.md | 145 + .../adr-015-ibc-packet-receiver.md | 299 + .../adr-025-ibc-passive-channels.md | 141 + .../adr-026-ibc-client-recovery-mechanisms.md | 90 + docs/architecture/adr-027-ibc-wasm.md | 167 + docs/architecture/adr.template.md | 38 + ...grade Feature Assessment - Report v1.1.pdf | Bin 0 -> 1022554 bytes .../Ethan Frey - Wasm Client Review.pdf | Bin 0 -> 467683 bytes docs/audits/08-wasm/Halborn audit report.pdf | Bin 0 -> 1359777 bytes ... New Features Assessment - Report v1.0.pdf | Bin 0 -> 764389 bytes .../Trail of Bits audit - Final Report.pdf | Bin 0 -> 1147519 bytes ...-April-2025-Collaborative-Audit-Report.pdf | Bin 0 -> 1213621 bytes docs/babel.config.js | 3 + docs/client/config.json | 85 + docs/client/swagger-ui/swagger.yaml | 19555 ++++++++++++++++ docs/dev/development-setup.md | 60 + docs/dev/go-style-guide.md | 119 + docs/dev/project-structure.md | 48 + docs/dev/pull-requests.md | 68 + docs/dev/release-management.md | 86 + docs/docs/00-intro.md | 42 + docs/docs/01-ibc/01-overview.md | 293 + docs/docs/01-ibc/02-integration.md | 359 + docs/docs/01-ibc/03-apps/00-ibcv2apps.md | 316 + docs/docs/01-ibc/03-apps/01-apps.md | 446 + docs/docs/01-ibc/03-apps/02-ibcmodule.md | 367 + docs/docs/01-ibc/03-apps/03-bindports.md | 106 + docs/docs/01-ibc/03-apps/04-keeper.md | 70 + docs/docs/01-ibc/03-apps/05-packets_acks.md | 163 + docs/docs/01-ibc/03-apps/06-routing.md | 44 + docs/docs/01-ibc/03-apps/_category_.json | 5 + .../01-ibc/03-apps/images/packet_flow.png | Bin 0 -> 352988 bytes .../01-ibc/03-apps/images/packet_flow_v2.png | Bin 0 -> 602039 bytes docs/docs/01-ibc/04-middleware/01-overview.md | 55 + docs/docs/01-ibc/04-middleware/02-develop.md | 478 + .../01-ibc/04-middleware/02-developIBCv2.md | 260 + .../01-ibc/04-middleware/03-integration.md | 72 + .../docs/01-ibc/04-middleware/_category_.json | 5 + .../04-middleware/images/middleware-stack.png | Bin 0 -> 194858 bytes docs/docs/01-ibc/05-upgrades/00-intro.md | 15 + .../docs/01-ibc/05-upgrades/01-quick-guide.md | 60 + .../01-ibc/05-upgrades/02-developer-guide.md | 14 + .../01-ibc/05-upgrades/03-genesis-restart.md | 52 + docs/docs/01-ibc/05-upgrades/_category_.json | 5 + docs/docs/01-ibc/07-relayer.md | 53 + docs/docs/01-ibc/08-best-practices.md | 25 + docs/docs/01-ibc/09-permissioning.md | 32 + docs/docs/01-ibc/_category_.json | 5 + docs/docs/02-apps/01-transfer/01-overview.md | 142 + docs/docs/02-apps/01-transfer/02-state.md | 14 + .../01-transfer/03-state-transitions.md | 37 + docs/docs/02-apps/01-transfer/04-messages.md | 76 + docs/docs/02-apps/01-transfer/05-events.md | 59 + docs/docs/02-apps/01-transfer/06-metrics.md | 17 + docs/docs/02-apps/01-transfer/07-params.md | 93 + .../02-apps/01-transfer/08-authorizations.md | 56 + docs/docs/02-apps/01-transfer/09-client.md | 94 + .../02-apps/01-transfer/10-IBCv2-transfer.md | 65 + docs/docs/02-apps/01-transfer/_category_.json | 5 + .../images/forwarding-3-chains-dark.png | Bin 0 -> 65220 bytes .../images/forwarding-3-chains-light.png | Bin 0 -> 53492 bytes .../02-interchain-accounts/01-overview.md | 51 + .../02-interchain-accounts/02-development.md | 40 + .../02-interchain-accounts/03-auth-modules.md | 27 + .../02-interchain-accounts/04-integration.md | 195 + .../02-interchain-accounts/05-messages.md | 153 + .../02-interchain-accounts/06-parameters.md | 65 + .../02-interchain-accounts/07-tx-encoding.md | 58 + .../02-interchain-accounts/08-client.md | 202 + .../09-active-channels.md | 45 + .../10-legacy/01-auth-modules.md | 268 + .../10-legacy/02-integration.md | 196 + .../10-legacy/03-keeper-api.md | 123 + .../10-legacy/_category_.json | 5 + .../10-legacy/images/ica-pre-v6.png | Bin 0 -> 34698 bytes .../02-interchain-accounts/_category_.json | 5 + .../02-interchain-accounts/images/ica-v6.png | Bin 0 -> 163580 bytes docs/docs/02-apps/_category_.json | 5 + .../01-developer-guide/01-overview.md | 95 + .../02-light-client-module.md | 76 + .../01-developer-guide/03-client-state.md | 21 + .../01-developer-guide/04-consensus-state.md | 27 + .../05-updates-and-misbehaviour.md | 104 + .../01-developer-guide/06-upgrades.md | 62 + .../01-developer-guide/07-proofs.md | 71 + .../01-developer-guide/08-proposals.md | 36 + .../01-developer-guide/09-setup.md | 135 + .../01-developer-guide/_category_.json | 5 + .../02-localhost/01-overview.md | 56 + .../02-localhost/02-integration.md | 19 + .../02-localhost/03-client-state.md | 10 + .../02-localhost/04-connection.md | 29 + .../02-localhost/05-state-verification.md | 23 + .../02-localhost/_category_.json | 5 + .../03-solomachine/01-solomachine.md | 26 + .../03-solomachine/02-concepts.md | 168 + .../03-solomachine/03-state.md | 12 + .../03-solomachine/04-state_transitions.md | 43 + .../03-solomachine/_category_.json | 5 + .../03-light-clients/04-wasm/01-overview.md | 26 + .../03-light-clients/04-wasm/02-concepts.md | 90 + .../04-wasm/03-integration.md | 398 + .../03-light-clients/04-wasm/04-messages.md | 75 + .../03-light-clients/04-wasm/05-governance.md | 126 + .../03-light-clients/04-wasm/06-events.md | 26 + .../03-light-clients/04-wasm/07-contracts.md | 110 + .../03-light-clients/04-wasm/08-client.md | 151 + .../03-light-clients/04-wasm/09-migrations.md | 239 + .../03-light-clients/04-wasm/_category_.json | 5 + .../05-tendermint/01-overview.md | 167 + .../05-tendermint/_category_.json | 5 + docs/docs/03-light-clients/06-proposals.md | 120 + docs/docs/03-light-clients/_category_.json | 5 + .../04-middleware/01-callbacks/01-overview.md | 51 + .../01-callbacks/02-integration.md | 81 + .../01-callbacks/03-interfaces.md | 170 + .../04-middleware/01-callbacks/04-events.md | 39 + .../01-callbacks/05-end-users.md | 96 + .../docs/04-middleware/01-callbacks/06-gas.md | 74 + .../01-callbacks/07-callbacks-IBCv2.md | 29 + .../01-callbacks/_category_.json | 5 + .../01-callbacks/images/callbackflow.svg | 43 + .../01-callbacks/images/ics4-callbackflow.svg | 43 + docs/docs/04-middleware/_category_.json | 5 + .../01-support-denoms-with-slashes.md | 87 + docs/docs/05-migrations/02-sdk-to-v1.md | 195 + docs/docs/05-migrations/03-v1-to-v2.md | 59 + docs/docs/05-migrations/04-v2-to-v3.md | 186 + docs/docs/05-migrations/05-v3-to-v4.md | 159 + docs/docs/05-migrations/06-v4-to-v5.md | 441 + docs/docs/05-migrations/07-v5-to-v6.md | 299 + docs/docs/05-migrations/08-v6-to-v7.md | 357 + docs/docs/05-migrations/09-v7-to-v7_1.md | 66 + docs/docs/05-migrations/10-v7_2-to-v7_3.md | 50 + docs/docs/05-migrations/11-v7-to-v8.md | 221 + docs/docs/05-migrations/12-v8-to-v8_1.md | 42 + docs/docs/05-migrations/13-v8_1-to-v10.md | 289 + docs/docs/05-migrations/_category_.json | 5 + .../images/auth-module-decision-tree.png | Bin 0 -> 80522 bytes docs/docs/05-migrations/migration.template.md | 28 + docs/docs/images/ibcoverview-dark.svg | 135 + docs/docs/images/ibcoverview-light.svg | 135 + docs/docusaurus.config.js | 357 + docs/events/events.md | 250 + docs/package-lock.json | 15565 ++++++++++++ docs/package.json | 56 + docs/params/params.md | 24 + docs/requirements/ics08-requirements.md | 124 + .../ics27-multiplexed-requirements.md | 101 + docs/requirements/ics27-requirements.md | 118 + docs/requirements/ics27-v2-requirements.md | 87 + docs/requirements/ics29-v1-requirements.md | 177 + docs/requirements/localhost-requirements.md | 69 + .../path-unwinding-forwarding-requirements.md | 99 + docs/requirements/requirements-template.md | 53 + docs/sidebars.js | 67 + docs/src/components/HighlightBox.jsx | 157 + docs/src/components/HighlightTag.jsx | 71 + docs/src/css/base.css | 32 + docs/src/css/custom.css | 553 + docs/src/css/fonts.css | 64 + docs/src/theme/CodeBlock/index.js | 16 + docs/static/.nojekyll | 0 docs/static/CNAME | 1 + docs/static/fonts/inter/Inter-Black.woff | Bin 0 -> 138764 bytes docs/static/fonts/inter/Inter-Black.woff2 | Bin 0 -> 102868 bytes .../static/fonts/inter/Inter-BlackItalic.woff | Bin 0 -> 146824 bytes .../fonts/inter/Inter-BlackItalic.woff2 | Bin 0 -> 108752 bytes docs/static/fonts/inter/Inter-Bold.woff | Bin 0 -> 143208 bytes docs/static/fonts/inter/Inter-Bold.woff2 | Bin 0 -> 106140 bytes docs/static/fonts/inter/Inter-BoldItalic.woff | Bin 0 -> 151052 bytes .../static/fonts/inter/Inter-BoldItalic.woff2 | Bin 0 -> 111808 bytes docs/static/fonts/inter/Inter-ExtraBold.woff | Bin 0 -> 142920 bytes docs/static/fonts/inter/Inter-ExtraBold.woff2 | Bin 0 -> 106108 bytes .../fonts/inter/Inter-ExtraBoldItalic.woff | Bin 0 -> 150628 bytes .../fonts/inter/Inter-ExtraBoldItalic.woff2 | Bin 0 -> 111708 bytes docs/static/fonts/inter/Inter-ExtraLight.woff | Bin 0 -> 140724 bytes .../static/fonts/inter/Inter-ExtraLight.woff2 | Bin 0 -> 104232 bytes .../fonts/inter/Inter-ExtraLightItalic.woff | Bin 0 -> 149996 bytes .../fonts/inter/Inter-ExtraLightItalic.woff2 | Bin 0 -> 111392 bytes docs/static/fonts/inter/Inter-Italic.woff | Bin 0 -> 144372 bytes docs/static/fonts/inter/Inter-Italic.woff2 | Bin 0 -> 106876 bytes docs/static/fonts/inter/Inter-Light.woff | Bin 0 -> 140632 bytes docs/static/fonts/inter/Inter-Light.woff2 | Bin 0 -> 104332 bytes .../static/fonts/inter/Inter-LightItalic.woff | Bin 0 -> 150092 bytes .../fonts/inter/Inter-LightItalic.woff2 | Bin 0 -> 111332 bytes docs/static/fonts/inter/Inter-Medium.woff | Bin 0 -> 142552 bytes docs/static/fonts/inter/Inter-Medium.woff2 | Bin 0 -> 105924 bytes .../fonts/inter/Inter-MediumItalic.woff | Bin 0 -> 150988 bytes .../fonts/inter/Inter-MediumItalic.woff2 | Bin 0 -> 112184 bytes docs/static/fonts/inter/Inter-Regular.woff | Bin 0 -> 133844 bytes docs/static/fonts/inter/Inter-Regular.woff2 | Bin 0 -> 98868 bytes docs/static/fonts/inter/Inter-SemiBold.woff | Bin 0 -> 142932 bytes docs/static/fonts/inter/Inter-SemiBold.woff2 | Bin 0 -> 105804 bytes .../fonts/inter/Inter-SemiBoldItalic.woff | Bin 0 -> 151180 bytes .../fonts/inter/Inter-SemiBoldItalic.woff2 | Bin 0 -> 112048 bytes docs/static/fonts/inter/Inter-Thin.woff | Bin 0 -> 135920 bytes docs/static/fonts/inter/Inter-Thin.woff2 | Bin 0 -> 99632 bytes docs/static/fonts/inter/Inter-ThinItalic.woff | Bin 0 -> 145480 bytes .../static/fonts/inter/Inter-ThinItalic.woff2 | Bin 0 -> 106496 bytes .../static/fonts/inter/Inter-italic.var.woff2 | Bin 0 -> 245036 bytes docs/static/fonts/inter/Inter-roman.var.woff2 | Bin 0 -> 227180 bytes docs/static/fonts/intervar/Inter.var.woff2 | Bin 0 -> 324864 bytes .../jetbrainsmono/JetBrainsMono-Bold.woff2 | Bin 0 -> 71180 bytes .../JetBrainsMono-BoldItalic.woff2 | Bin 0 -> 73976 bytes .../JetBrainsMono-ExtraBold.woff2 | Bin 0 -> 70124 bytes .../JetBrainsMono-ExtraBoldItalic.woff2 | Bin 0 -> 73264 bytes .../JetBrainsMono-ExtraLight.woff2 | Bin 0 -> 69780 bytes .../JetBrainsMono-ExtraLightItalic.woff2 | Bin 0 -> 72520 bytes .../jetbrainsmono/JetBrainsMono-Italic.woff2 | Bin 0 -> 72268 bytes .../jetbrainsmono/JetBrainsMono-Light.woff2 | Bin 0 -> 70416 bytes .../JetBrainsMono-LightItalic.woff2 | Bin 0 -> 73552 bytes .../jetbrainsmono/JetBrainsMono-Medium.woff2 | Bin 0 -> 70480 bytes .../JetBrainsMono-MediumItalic.woff2 | Bin 0 -> 73704 bytes .../jetbrainsmono/JetBrainsMono-Regular.woff2 | Bin 0 -> 69440 bytes .../JetBrainsMono-SemiBold.woff2 | Bin 0 -> 70820 bytes .../JetBrainsMono-SemiBoldItalic.woff2 | Bin 0 -> 74088 bytes .../jetbrainsmono/JetBrainsMono-Thin.woff2 | Bin 0 -> 68064 bytes .../JetBrainsMono-ThinItalic.woff2 | Bin 0 -> 71180 bytes docs/static/img/IBC-go-cover.svg | 42 + docs/static/img/black-ibc-logo-400x400.svg | 10 + docs/static/img/black-ibc-logo.svg | 12 + docs/static/img/black-large-ibc-logo.svg | 52 + docs/static/img/cosmos-logo-bw.svg | 8 + docs/static/img/ibc-go-docs-social-card.png | Bin 0 -> 60423 bytes docs/static/img/ico-chevron.svg | 3 + docs/static/img/icons/hi-coffee-icon.svg | 6 + docs/static/img/icons/hi-info-icon.svg | 5 + docs/static/img/icons/hi-note-icon.svg | 3 + .../static/img/icons/hi-prerequisite-icon.svg | 6 + docs/static/img/icons/hi-reading-icon.svg | 3 + docs/static/img/icons/hi-star-icon.svg | 3 + docs/static/img/icons/hi-target-icon.svg | 3 + docs/static/img/icons/hi-tip-icon.svg | 3 + docs/static/img/icons/hi-warn-icon.svg | 5 + docs/static/img/spirograph-white.svg | 5 + docs/static/img/white-cosmos-icon.svg | 3 + docs/static/img/white-ibc-logo-400x400.svg | 10 + docs/static/img/white-ibc-logo.svg | 12 + docs/static/img/white-large-ibc-logo.svg | 52 + docs/tailwind.config.js | 104 + .../version-v10.1.x/00-intro.md | 42 + .../version-v10.1.x/01-ibc/01-overview.md | 293 + .../version-v10.1.x/01-ibc/02-integration.md | 356 + .../01-ibc/03-apps/00-ibcv2apps.md | 316 + .../version-v10.1.x/01-ibc/03-apps/01-apps.md | 446 + .../01-ibc/03-apps/02-ibcmodule.md | 367 + .../01-ibc/03-apps/03-bindports.md | 106 + .../01-ibc/03-apps/04-keeper.md | 70 + .../01-ibc/03-apps/05-packets_acks.md | 163 + .../01-ibc/03-apps/06-routing.md | 44 + .../01-ibc/03-apps/_category_.json | 5 + .../01-ibc/03-apps/images/packet_flow.png | Bin 0 -> 352988 bytes .../01-ibc/03-apps/images/packet_flow_v2.png | Bin 0 -> 602039 bytes .../01-ibc/04-middleware/01-overview.md | 55 + .../01-ibc/04-middleware/02-develop.md | 478 + .../01-ibc/04-middleware/02-developIBCv2.md | 260 + .../01-ibc/04-middleware/03-integration.md | 72 + .../01-ibc/04-middleware/_category_.json | 5 + .../04-middleware/images/middleware-stack.png | Bin 0 -> 194858 bytes .../01-ibc/05-upgrades/00-intro.md | 15 + .../01-ibc/05-upgrades/01-quick-guide.md | 60 + .../01-ibc/05-upgrades/02-developer-guide.md | 14 + .../01-ibc/05-upgrades/03-genesis-restart.md | 52 + .../01-ibc/05-upgrades/_category_.json | 5 + .../version-v10.1.x/01-ibc/07-relayer.md | 53 + .../01-ibc/08-best-practices.md | 25 + .../01-ibc/09-permissioning.md | 32 + .../version-v10.1.x/01-ibc/_category_.json | 5 + .../02-apps/01-transfer/01-overview.md | 142 + .../02-apps/01-transfer/02-state.md | 14 + .../01-transfer/03-state-transitions.md | 37 + .../02-apps/01-transfer/04-messages.md | 76 + .../02-apps/01-transfer/05-events.md | 59 + .../02-apps/01-transfer/06-metrics.md | 17 + .../02-apps/01-transfer/07-params.md | 93 + .../02-apps/01-transfer/08-authorizations.md | 56 + .../02-apps/01-transfer/09-client.md | 94 + .../02-apps/01-transfer/10-IBCv2-transfer.md | 65 + .../02-apps/01-transfer/_category_.json | 5 + .../images/forwarding-3-chains-dark.png | Bin 0 -> 65220 bytes .../images/forwarding-3-chains-light.png | Bin 0 -> 53492 bytes .../02-interchain-accounts/01-overview.md | 51 + .../02-interchain-accounts/02-development.md | 40 + .../02-interchain-accounts/03-auth-modules.md | 27 + .../02-interchain-accounts/04-integration.md | 195 + .../02-interchain-accounts/05-messages.md | 153 + .../02-interchain-accounts/06-parameters.md | 65 + .../02-interchain-accounts/07-tx-encoding.md | 58 + .../02-interchain-accounts/08-client.md | 202 + .../09-active-channels.md | 45 + .../10-legacy/01-auth-modules.md | 268 + .../10-legacy/02-integration.md | 196 + .../10-legacy/03-keeper-api.md | 123 + .../10-legacy/_category_.json | 5 + .../10-legacy/images/ica-pre-v6.png | Bin 0 -> 34698 bytes .../02-interchain-accounts/_category_.json | 5 + .../02-interchain-accounts/images/ica-v6.png | Bin 0 -> 163580 bytes .../version-v10.1.x/02-apps/_category_.json | 5 + .../01-developer-guide/01-overview.md | 95 + .../02-light-client-module.md | 76 + .../01-developer-guide/03-client-state.md | 21 + .../01-developer-guide/04-consensus-state.md | 27 + .../05-updates-and-misbehaviour.md | 104 + .../01-developer-guide/06-upgrades.md | 62 + .../01-developer-guide/07-proofs.md | 71 + .../01-developer-guide/08-proposals.md | 36 + .../01-developer-guide/09-setup.md | 135 + .../01-developer-guide/_category_.json | 5 + .../02-localhost/01-overview.md | 56 + .../02-localhost/02-integration.md | 19 + .../02-localhost/03-client-state.md | 10 + .../02-localhost/04-connection.md | 29 + .../02-localhost/05-state-verification.md | 23 + .../02-localhost/_category_.json | 5 + .../03-solomachine/01-solomachine.md | 26 + .../03-solomachine/02-concepts.md | 168 + .../03-solomachine/03-state.md | 12 + .../03-solomachine/04-state_transitions.md | 43 + .../03-solomachine/_category_.json | 5 + .../03-light-clients/04-wasm/01-overview.md | 26 + .../03-light-clients/04-wasm/02-concepts.md | 90 + .../04-wasm/03-integration.md | 398 + .../03-light-clients/04-wasm/04-messages.md | 75 + .../03-light-clients/04-wasm/05-governance.md | 126 + .../03-light-clients/04-wasm/06-events.md | 26 + .../03-light-clients/04-wasm/07-contracts.md | 110 + .../03-light-clients/04-wasm/08-client.md | 151 + .../03-light-clients/04-wasm/09-migrations.md | 239 + .../03-light-clients/04-wasm/_category_.json | 5 + .../05-tendermint/01-overview.md | 167 + .../05-tendermint/_category_.json | 5 + .../03-light-clients/06-proposals.md | 120 + .../03-light-clients/_category_.json | 5 + .../04-middleware/01-callbacks/01-overview.md | 51 + .../01-callbacks/02-integration.md | 81 + .../01-callbacks/03-interfaces.md | 170 + .../04-middleware/01-callbacks/04-events.md | 39 + .../01-callbacks/05-end-users.md | 96 + .../04-middleware/01-callbacks/06-gas.md | 74 + .../01-callbacks/07-callbacks-IBCv2.md | 29 + .../01-callbacks/_category_.json | 5 + .../01-callbacks/images/callbackflow.svg | 43 + .../01-callbacks/images/ics4-callbackflow.svg | 43 + .../04-middleware/_category_.json | 5 + .../01-support-denoms-with-slashes.md | 87 + .../05-migrations/02-sdk-to-v1.md | 195 + .../05-migrations/03-v1-to-v2.md | 59 + .../05-migrations/04-v2-to-v3.md | 186 + .../05-migrations/05-v3-to-v4.md | 159 + .../05-migrations/06-v4-to-v5.md | 441 + .../05-migrations/07-v5-to-v6.md | 299 + .../05-migrations/08-v6-to-v7.md | 357 + .../05-migrations/09-v7-to-v7_1.md | 66 + .../05-migrations/10-v7_2-to-v7_3.md | 50 + .../05-migrations/11-v7-to-v8.md | 221 + .../05-migrations/12-v8-to-v8_1.md | 42 + .../05-migrations/13-v8_1-to-v10.md | 289 + .../05-migrations/_category_.json | 5 + .../images/auth-module-decision-tree.png | Bin 0 -> 80522 bytes .../05-migrations/migration.template.md | 28 + .../images/ibcoverview-dark.svg | 135 + .../images/ibcoverview-light.svg | 135 + .../versioned_docs/version-v4.6.x/00-intro.md | 20 + .../version-v4.6.x/01-ibc/01-overview.md | 297 + .../version-v4.6.x/01-ibc/02-integration.md | 222 + .../version-v4.6.x/01-ibc/03-apps/01-apps.md | 56 + .../01-ibc/03-apps/02-ibcmodule.md | 351 + .../01-ibc/03-apps/03-bindports.md | 122 + .../01-ibc/03-apps/04-keeper.md | 96 + .../01-ibc/03-apps/05-packets_acks.md | 108 + .../01-ibc/03-apps/06-routing.md | 44 + .../01-ibc/03-apps/_category_.json | 5 + .../01-ibc/03-apps/images/packet_flow.png | Bin 0 -> 352988 bytes .../01-ibc/04-middleware/01-develop.md | 422 + .../01-ibc/04-middleware/02-integration.md | 72 + .../01-ibc/04-middleware/_category_.json | 5 + .../01-ibc/05-upgrades/00-intro.md | 15 + .../01-ibc/05-upgrades/01-quick-guide.md | 60 + .../01-ibc/05-upgrades/02-developer-guide.md | 56 + .../01-ibc/05-upgrades/03-genesis-restart.md | 52 + .../01-ibc/05-upgrades/_category_.json | 5 + .../version-v4.6.x/01-ibc/06-proposals.md | 91 + .../version-v4.6.x/01-ibc/07-relayer.md | 53 + .../version-v4.6.x/01-ibc/08-proto-docs.md | 10 + .../version-v4.6.x/01-ibc/09-roadmap.md | 61 + .../version-v4.6.x/01-ibc/_category_.json | 5 + .../02-apps/01-transfer/01-overview.md | 128 + .../02-apps/01-transfer/02-state.md | 13 + .../01-transfer/03-state-transitions.md | 37 + .../02-apps/01-transfer/04-messages.md | 46 + .../02-apps/01-transfer/05-events.md | 55 + .../02-apps/01-transfer/06-metrics.md | 18 + .../02-apps/01-transfer/07-params.md | 34 + .../02-apps/01-transfer/_category_.json | 5 + .../02-interchain-accounts/01-overview.md | 47 + .../02-interchain-accounts/02-auth-modules.md | 402 + .../03-active-channels.md | 28 + .../02-interchain-accounts/04-integration.md | 193 + .../02-interchain-accounts/05-parameters.md | 65 + .../02-interchain-accounts/06-transactions.md | 27 + .../02-interchain-accounts/_category_.json | 5 + .../images/send-interchain-tx.png | Bin 0 -> 168904 bytes .../version-v4.6.x/02-apps/_category_.json | 5 + .../03-middleware/01-ics29-fee/01-overview.md | 54 + .../01-ics29-fee/02-integration.md | 174 + .../03-middleware/01-ics29-fee/03-msgs.md | 95 + .../01-ics29-fee/04-fee-distribution.md | 114 + .../03-middleware/01-ics29-fee/05-events.md | 43 + .../01-ics29-fee/06-end-users.md | 36 + .../01-ics29-fee/_category_.json | 5 + .../01-ics29-fee/images/feeflow.png | Bin 0 -> 394717 bytes .../01-ics29-fee/images/msgpaypacket.png | Bin 0 -> 150696 bytes .../01-ics29-fee/images/paypacketfeeasync.png | Bin 0 -> 142753 bytes .../03-middleware/_category_.json | 5 + .../01-support-denoms-with-slashes.md | 88 + .../04-migrations/02-sdk-to-v1.md | 195 + .../04-migrations/03-v1-to-v2.md | 60 + .../04-migrations/04-v2-to-v3.md | 186 + .../04-migrations/05-v3-to-v4.md | 160 + .../04-migrations/_category_.json | 5 + .../versioned_docs/version-v5.4.x/00-intro.md | 20 + .../version-v5.4.x/01-ibc/01-overview.md | 297 + .../version-v5.4.x/01-ibc/02-integration.md | 222 + .../version-v5.4.x/01-ibc/03-apps/01-apps.md | 56 + .../01-ibc/03-apps/02-ibcmodule.md | 351 + .../01-ibc/03-apps/03-bindports.md | 122 + .../01-ibc/03-apps/04-keeper.md | 96 + .../01-ibc/03-apps/05-packets_acks.md | 108 + .../01-ibc/03-apps/06-routing.md | 44 + .../01-ibc/03-apps/_category_.json | 5 + .../01-ibc/03-apps/images/packet_flow.png | Bin 0 -> 352988 bytes .../01-ibc/04-middleware/01-develop.md | 422 + .../01-ibc/04-middleware/02-integration.md | 72 + .../01-ibc/04-middleware/_category_.json | 5 + .../01-ibc/05-upgrades/00-intro.md | 8 + .../01-ibc/05-upgrades/01-quick-guide.md | 60 + .../01-ibc/05-upgrades/02-developer-guide.md | 56 + .../01-ibc/05-upgrades/03-genesis-restart.md | 52 + .../01-ibc/05-upgrades/_category_.json | 5 + .../version-v5.4.x/01-ibc/06-proposals.md | 130 + .../version-v5.4.x/01-ibc/07-relayer.md | 53 + .../version-v5.4.x/01-ibc/08-proto-docs.md | 10 + .../version-v5.4.x/01-ibc/09-roadmap.md | 60 + .../version-v5.4.x/01-ibc/_category_.json | 5 + .../02-apps/01-transfer/01-overview.md | 128 + .../02-apps/01-transfer/02-state.md | 13 + .../01-transfer/03-state-transitions.md | 37 + .../02-apps/01-transfer/04-messages.md | 46 + .../02-apps/01-transfer/05-events.md | 55 + .../02-apps/01-transfer/06-metrics.md | 18 + .../02-apps/01-transfer/07-params.md | 34 + .../02-apps/01-transfer/_category_.json | 5 + .../02-interchain-accounts/01-overview.md | 43 + .../02-interchain-accounts/02-auth-modules.md | 402 + .../03-active-channels.md | 28 + .../02-interchain-accounts/04-integration.md | 194 + .../02-interchain-accounts/05-parameters.md | 65 + .../02-interchain-accounts/06-transactions.md | 27 + .../02-interchain-accounts/_category_.json | 5 + .../images/send-interchain-tx.png | Bin 0 -> 168904 bytes .../version-v5.4.x/02-apps/_category_.json | 5 + .../03-middleware/01-ics29-fee/01-overview.md | 55 + .../01-ics29-fee/02-integration.md | 174 + .../03-middleware/01-ics29-fee/03-msgs.md | 96 + .../01-ics29-fee/04-fee-distribution.md | 114 + .../03-middleware/01-ics29-fee/05-events.md | 43 + .../01-ics29-fee/06-end-users.md | 36 + .../01-ics29-fee/_category_.json | 5 + .../01-ics29-fee/images/feeflow.png | Bin 0 -> 394717 bytes .../01-ics29-fee/images/msgpaypacket.png | Bin 0 -> 150696 bytes .../01-ics29-fee/images/paypacketfeeasync.png | Bin 0 -> 142753 bytes .../03-middleware/_category_.json | 5 + .../01-support-denoms-with-slashes.md | 88 + .../04-migrations/02-sdk-to-v1.md | 195 + .../04-migrations/03-v1-to-v2.md | 60 + .../04-migrations/04-v2-to-v3.md | 186 + .../04-migrations/05-v3-to-v4.md | 160 + .../04-migrations/_category_.json | 5 + .../versioned_docs/version-v6.3.x/00-intro.md | 20 + .../version-v6.3.x/01-ibc/01-overview.md | 297 + .../version-v6.3.x/01-ibc/02-integration.md | 222 + .../version-v6.3.x/01-ibc/03-apps/01-apps.md | 56 + .../01-ibc/03-apps/02-ibcmodule.md | 358 + .../01-ibc/03-apps/03-bindports.md | 122 + .../01-ibc/03-apps/04-keeper.md | 96 + .../01-ibc/03-apps/05-packets_acks.md | 118 + .../01-ibc/03-apps/06-routing.md | 44 + .../01-ibc/03-apps/_category_.json | 5 + .../01-ibc/03-apps/images/packet_flow.png | Bin 0 -> 352988 bytes .../01-ibc/04-middleware/01-develop.md | 453 + .../01-ibc/04-middleware/02-integration.md | 72 + .../01-ibc/04-middleware/_category_.json | 5 + .../01-ibc/05-upgrades/00-intro.md | 15 + .../01-ibc/05-upgrades/01-quick-guide.md | 60 + .../01-ibc/05-upgrades/02-developer-guide.md | 56 + .../01-ibc/05-upgrades/03-genesis-restart.md | 52 + .../01-ibc/05-upgrades/_category_.json | 5 + .../version-v6.3.x/01-ibc/06-proposals.md | 130 + .../version-v6.3.x/01-ibc/07-relayer.md | 53 + .../version-v6.3.x/01-ibc/08-proto-docs.md | 10 + .../version-v6.3.x/01-ibc/09-roadmap.md | 60 + .../version-v6.3.x/01-ibc/_category_.json | 5 + .../02-apps/01-transfer/01-overview.md | 128 + .../02-apps/01-transfer/02-state.md | 13 + .../01-transfer/03-state-transitions.md | 37 + .../02-apps/01-transfer/04-messages.md | 46 + .../02-apps/01-transfer/05-events.md | 55 + .../02-apps/01-transfer/06-metrics.md | 18 + .../02-apps/01-transfer/07-params.md | 34 + .../02-apps/01-transfer/08-authorizations.md | 54 + .../02-apps/01-transfer/_category_.json | 5 + .../02-interchain-accounts/01-overview.md | 39 + .../02-interchain-accounts/02-development.md | 40 + .../02-interchain-accounts/03-auth-modules.md | 27 + .../02-interchain-accounts/04-integration.md | 199 + .../02-interchain-accounts/05-messages.md | 77 + .../02-interchain-accounts/06-parameters.md | 65 + .../02-interchain-accounts/07-client.md | 184 + .../08-active-channels.md | 40 + .../09-legacy/01-auth-modules.md | 274 + .../09-legacy/02-integration.md | 201 + .../09-legacy/03-keeper-api.md | 125 + .../09-legacy/_category_.json | 5 + .../09-legacy/images/ica-pre-v6.png | Bin 0 -> 34698 bytes .../02-interchain-accounts/_category_.json | 5 + .../02-interchain-accounts/images/ica-v6.png | Bin 0 -> 163580 bytes .../version-v6.3.x/02-apps/_category_.json | 5 + .../03-middleware/01-ics29-fee/01-overview.md | 55 + .../01-ics29-fee/02-integration.md | 174 + .../03-middleware/01-ics29-fee/03-msgs.md | 95 + .../01-ics29-fee/04-fee-distribution.md | 114 + .../03-middleware/01-ics29-fee/05-events.md | 43 + .../01-ics29-fee/06-end-users.md | 36 + .../01-ics29-fee/_category_.json | 5 + .../01-ics29-fee/images/feeflow.png | Bin 0 -> 394717 bytes .../01-ics29-fee/images/msgpaypacket.png | Bin 0 -> 150696 bytes .../01-ics29-fee/images/paypacketfeeasync.png | Bin 0 -> 142753 bytes .../03-middleware/_category_.json | 5 + .../01-support-denoms-with-slashes.md | 88 + .../04-migrations/02-sdk-to-v1.md | 195 + .../04-migrations/03-v1-to-v2.md | 60 + .../04-migrations/04-v2-to-v3.md | 186 + .../04-migrations/05-v3-to-v4.md | 160 + .../04-migrations/06-v4-to-v5.md | 441 + .../04-migrations/07-v5-to-v6.md | 299 + .../04-migrations/_category_.json | 5 + .../images/auth-module-decision-tree.png | Bin 0 -> 80522 bytes .../versioned_docs/version-v7.8.x/00-intro.md | 16 + .../version-v7.8.x/01-ibc/01-overview.md | 297 + .../version-v7.8.x/01-ibc/02-integration.md | 235 + .../version-v7.8.x/01-ibc/03-apps/01-apps.md | 57 + .../01-ibc/03-apps/02-ibcmodule.md | 382 + .../01-ibc/03-apps/03-bindports.md | 122 + .../01-ibc/03-apps/04-keeper.md | 96 + .../01-ibc/03-apps/05-packets_acks.md | 167 + .../01-ibc/03-apps/06-routing.md | 44 + .../01-ibc/03-apps/_category_.json | 5 + .../01-ibc/03-apps/images/packet_flow.png | Bin 0 -> 352988 bytes .../01-ibc/04-middleware/01-develop.md | 487 + .../01-ibc/04-middleware/02-integration.md | 72 + .../01-ibc/04-middleware/_category_.json | 5 + .../01-ibc/05-upgrades/00-intro.md | 15 + .../01-ibc/05-upgrades/01-quick-guide.md | 60 + .../01-ibc/05-upgrades/02-developer-guide.md | 15 + .../01-ibc/05-upgrades/03-genesis-restart.md | 52 + .../01-ibc/05-upgrades/_category_.json | 5 + .../version-v7.8.x/01-ibc/06-proposals.md | 132 + .../version-v7.8.x/01-ibc/07-relayer.md | 53 + .../version-v7.8.x/01-ibc/08-proto-docs.md | 11 + .../version-v7.8.x/01-ibc/09-roadmap.md | 74 + .../01-ibc/10-troubleshooting.md | 15 + .../version-v7.8.x/01-ibc/_category_.json | 5 + .../02-apps/01-transfer/01-overview.md | 128 + .../02-apps/01-transfer/02-state.md | 13 + .../01-transfer/03-state-transitions.md | 37 + .../02-apps/01-transfer/04-messages.md | 61 + .../02-apps/01-transfer/05-events.md | 58 + .../02-apps/01-transfer/06-metrics.md | 18 + .../02-apps/01-transfer/07-params.md | 34 + .../02-apps/01-transfer/08-authorizations.md | 57 + .../02-apps/01-transfer/09-client.md | 70 + .../02-apps/01-transfer/_category_.json | 5 + .../02-interchain-accounts/01-overview.md | 39 + .../02-interchain-accounts/02-development.md | 40 + .../02-interchain-accounts/03-auth-modules.md | 27 + .../02-interchain-accounts/04-integration.md | 202 + .../02-interchain-accounts/05-messages.md | 143 + .../02-interchain-accounts/06-parameters.md | 65 + .../02-interchain-accounts/07-tx-encoding.md | 58 + .../02-interchain-accounts/08-client.md | 183 + .../09-active-channels.md | 45 + .../10-legacy/01-auth-modules.md | 274 + .../10-legacy/02-integration.md | 203 + .../10-legacy/03-keeper-api.md | 127 + .../10-legacy/_category_.json | 5 + .../10-legacy/images/ica-pre-v6.png | Bin 0 -> 34698 bytes .../02-interchain-accounts/_category_.json | 5 + .../02-interchain-accounts/images/ica-v6.png | Bin 0 -> 163580 bytes .../version-v7.8.x/02-apps/_category_.json | 5 + .../01-developer-guide/01-overview.md | 79 + .../01-developer-guide/02-client-state.md | 79 + .../01-developer-guide/03-consensus-state.md | 27 + .../04-updates-and-misbehaviour.md | 99 + .../01-developer-guide/05-upgrades.md | 66 + .../01-developer-guide/06-proofs.md | 66 + .../01-developer-guide/07-proposals.md | 36 + .../01-developer-guide/08-genesis.md | 42 + .../01-developer-guide/09-setup.md | 135 + .../01-developer-guide/_category_.json | 5 + .../02-solomachine/01-solomachine.md | 26 + .../02-solomachine/02-concepts.md | 168 + .../02-solomachine/03-state.md | 12 + .../02-solomachine/04-state_transitions.md | 43 + .../02-solomachine/_category_.json | 5 + .../03-localhost/01-overview.md | 46 + .../03-localhost/02-integration.md | 20 + .../03-localhost/03-client-state.md | 64 + .../03-localhost/04-connection.md | 29 + .../03-localhost/05-state-verification.md | 22 + .../03-localhost/_category_.json | 5 + .../03-light-clients/04-wasm/01-overview.md | 26 + .../03-light-clients/04-wasm/02-concepts.md | 74 + .../04-wasm/03-integration.md | 386 + .../03-light-clients/04-wasm/04-messages.md | 75 + .../03-light-clients/04-wasm/05-governance.md | 126 + .../03-light-clients/04-wasm/06-events.md | 26 + .../03-light-clients/04-wasm/07-contracts.md | 113 + .../03-light-clients/04-wasm/08-client.md | 151 + .../03-light-clients/04-wasm/_category_.json | 5 + .../03-light-clients/_category_.json | 5 + .../04-middleware/01-ics29-fee/01-overview.md | 54 + .../01-ics29-fee/02-integration.md | 174 + .../04-middleware/01-ics29-fee/03-msgs.md | 96 + .../01-ics29-fee/04-fee-distribution.md | 114 + .../04-middleware/01-ics29-fee/05-events.md | 43 + .../01-ics29-fee/06-end-users.md | 36 + .../01-ics29-fee/_category_.json | 5 + .../01-ics29-fee/images/feeflow.png | Bin 0 -> 394717 bytes .../01-ics29-fee/images/msgpaypacket.png | Bin 0 -> 150696 bytes .../01-ics29-fee/images/paypacketfeeasync.png | Bin 0 -> 142753 bytes .../04-middleware/02-callbacks/01-overview.md | 51 + .../02-callbacks/02-integration.md | 108 + .../02-callbacks/03-interfaces.md | 151 + .../04-middleware/02-callbacks/04-events.md | 39 + .../02-callbacks/05-end-users.md | 96 + .../04-middleware/02-callbacks/06-gas.md | 77 + .../02-callbacks/_category_.json | 5 + .../02-callbacks/images/callbackflow.svg | 43 + .../02-callbacks/images/ics4-callbackflow.svg | 43 + .../04-middleware/_category_.json | 5 + .../01-support-denoms-with-slashes.md | 88 + .../05-migrations/02-sdk-to-v1.md | 195 + .../05-migrations/03-v1-to-v2.md | 60 + .../05-migrations/04-v2-to-v3.md | 186 + .../05-migrations/05-v3-to-v4.md | 160 + .../05-migrations/06-v4-to-v5.md | 441 + .../05-migrations/07-v5-to-v6.md | 299 + .../05-migrations/08-v6-to-v7.md | 357 + .../05-migrations/09-v7-to-v7_1.md | 67 + .../05-migrations/10-v7_2-to-v7_3.md | 49 + .../05-migrations/_category_.json | 5 + .../images/auth-module-decision-tree.png | Bin 0 -> 80522 bytes .../versioned_docs/version-v8.5.x/00-intro.md | 36 + .../version-v8.5.x/01-ibc/01-overview.md | 329 + .../version-v8.5.x/01-ibc/02-integration.md | 230 + .../version-v8.5.x/01-ibc/03-apps/01-apps.md | 494 + .../01-ibc/03-apps/02-ibcmodule.md | 383 + .../01-ibc/03-apps/03-bindports.md | 122 + .../01-ibc/03-apps/04-keeper.md | 96 + .../01-ibc/03-apps/05-packets_acks.md | 166 + .../01-ibc/03-apps/06-routing.md | 44 + .../01-ibc/03-apps/_category_.json | 5 + .../01-ibc/03-apps/images/packet_flow.png | Bin 0 -> 352988 bytes .../01-ibc/04-middleware/01-overview.md | 55 + .../01-ibc/04-middleware/02-develop.md | 495 + .../01-ibc/04-middleware/03-integration.md | 74 + .../01-ibc/04-middleware/_category_.json | 5 + .../04-middleware/images/middleware-stack.png | Bin 0 -> 194858 bytes .../01-ibc/05-upgrades/00-intro.md | 15 + .../01-ibc/05-upgrades/01-quick-guide.md | 60 + .../01-ibc/05-upgrades/02-developer-guide.md | 14 + .../01-ibc/05-upgrades/03-genesis-restart.md | 52 + .../01-ibc/05-upgrades/_category_.json | 5 + .../01-ibc/06-channel-upgrades.md | 413 + .../version-v8.5.x/01-ibc/07-proposals.md | 118 + .../version-v8.5.x/01-ibc/08-relayer.md | 53 + .../version-v8.5.x/01-ibc/09-proto-docs.md | 11 + .../version-v8.5.x/01-ibc/10-roadmap.md | 54 + .../01-ibc/11-troubleshooting.md | 15 + .../01-ibc/12-capability-module.md | 139 + .../version-v8.5.x/01-ibc/_category_.json | 5 + .../02-apps/01-transfer/01-overview.md | 138 + .../02-apps/01-transfer/02-state.md | 13 + .../01-transfer/03-state-transitions.md | 37 + .../02-apps/01-transfer/04-messages.md | 61 + .../02-apps/01-transfer/05-events.md | 57 + .../02-apps/01-transfer/06-metrics.md | 18 + .../02-apps/01-transfer/07-params.md | 94 + .../02-apps/01-transfer/08-authorizations.md | 59 + .../02-apps/01-transfer/09-client.md | 69 + .../02-apps/01-transfer/_category_.json | 5 + .../02-interchain-accounts/01-overview.md | 48 + .../02-interchain-accounts/02-development.md | 40 + .../02-interchain-accounts/03-auth-modules.md | 27 + .../02-interchain-accounts/04-integration.md | 202 + .../02-interchain-accounts/05-messages.md | 153 + .../02-interchain-accounts/06-parameters.md | 65 + .../02-interchain-accounts/07-tx-encoding.md | 58 + .../02-interchain-accounts/08-client.md | 202 + .../09-active-channels.md | 45 + .../10-legacy/01-auth-modules.md | 274 + .../10-legacy/02-integration.md | 203 + .../10-legacy/03-keeper-api.md | 127 + .../10-legacy/_category_.json | 5 + .../10-legacy/images/ica-pre-v6.png | Bin 0 -> 34698 bytes .../02-interchain-accounts/_category_.json | 5 + .../02-interchain-accounts/images/ica-v6.png | Bin 0 -> 163580 bytes .../version-v8.5.x/02-apps/_category_.json | 5 + .../01-developer-guide/01-overview.md | 79 + .../01-developer-guide/02-client-state.md | 79 + .../01-developer-guide/03-consensus-state.md | 29 + .../04-updates-and-misbehaviour.md | 98 + .../01-developer-guide/05-upgrades.md | 66 + .../01-developer-guide/06-proofs.md | 66 + .../01-developer-guide/07-proposals.md | 36 + .../01-developer-guide/08-genesis.md | 45 + .../01-developer-guide/09-setup.md | 135 + .../01-developer-guide/_category_.json | 5 + .../02-localhost/01-overview.md | 46 + .../02-localhost/02-integration.md | 19 + .../02-localhost/03-client-state.md | 64 + .../02-localhost/04-connection.md | 29 + .../02-localhost/05-state-verification.md | 22 + .../02-localhost/_category_.json | 5 + .../03-solomachine/01-solomachine.md | 26 + .../03-solomachine/02-concepts.md | 168 + .../03-solomachine/03-state.md | 12 + .../03-solomachine/04-state_transitions.md | 43 + .../03-solomachine/_category_.json | 5 + .../03-light-clients/04-wasm/01-overview.md | 26 + .../03-light-clients/04-wasm/02-concepts.md | 74 + .../04-wasm/03-integration.md | 396 + .../03-light-clients/04-wasm/04-messages.md | 75 + .../03-light-clients/04-wasm/05-governance.md | 126 + .../03-light-clients/04-wasm/06-events.md | 26 + .../03-light-clients/04-wasm/07-contracts.md | 113 + .../03-light-clients/04-wasm/08-client.md | 151 + .../03-light-clients/04-wasm/09-migrations.md | 103 + .../03-light-clients/04-wasm/_category_.json | 5 + .../03-light-clients/_category_.json | 5 + .../04-middleware/01-ics29-fee/01-overview.md | 54 + .../01-ics29-fee/02-integration.md | 177 + .../04-middleware/01-ics29-fee/03-msgs.md | 97 + .../01-ics29-fee/04-fee-distribution.md | 117 + .../04-middleware/01-ics29-fee/05-events.md | 43 + .../01-ics29-fee/06-end-users.md | 39 + .../01-ics29-fee/_category_.json | 5 + .../01-ics29-fee/images/feeflow.png | Bin 0 -> 394717 bytes .../01-ics29-fee/images/msgpaypacket.png | Bin 0 -> 150696 bytes .../01-ics29-fee/images/paypacketfeeasync.png | Bin 0 -> 142753 bytes .../04-middleware/02-callbacks/01-overview.md | 51 + .../02-callbacks/02-integration.md | 108 + .../02-callbacks/03-interfaces.md | 151 + .../04-middleware/02-callbacks/04-events.md | 39 + .../02-callbacks/05-end-users.md | 96 + .../04-middleware/02-callbacks/06-gas.md | 77 + .../02-callbacks/_category_.json | 5 + .../02-callbacks/images/callbackflow.svg | 43 + .../02-callbacks/images/ics4-callbackflow.svg | 43 + .../04-middleware/_category_.json | 5 + .../01-support-denoms-with-slashes.md | 87 + .../05-migrations/02-sdk-to-v1.md | 195 + .../05-migrations/03-v1-to-v2.md | 59 + .../05-migrations/04-v2-to-v3.md | 186 + .../05-migrations/05-v3-to-v4.md | 159 + .../05-migrations/06-v4-to-v5.md | 441 + .../05-migrations/07-v5-to-v6.md | 299 + .../05-migrations/08-v6-to-v7.md | 357 + .../05-migrations/09-v7-to-v7_1.md | 66 + .../05-migrations/10-v7_2-to-v7_3.md | 50 + .../05-migrations/11-v7-to-v8.md | 221 + .../05-migrations/12-v8-to-v8_1.md | 42 + .../05-migrations/_category_.json | 5 + .../images/auth-module-decision-tree.png | Bin 0 -> 80522 bytes .../05-migrations/migration.template.md | 28 + .../images/ibcoverview-dark.svg | 135 + .../images/ibcoverview-light.svg | 135 + .../version-v10.1.x-sidebars.json | 40 + .../version-v4.6.x-sidebars.json | 35 + .../version-v5.4.x-sidebars.json | 35 + .../version-v6.3.x-sidebars.json | 35 + .../version-v7.8.x-sidebars.json | 35 + .../version-v8.5.x-sidebars.json | 40 + docs/versions.json | 8 + e2e/Makefile | 19 + e2e/README.md | 242 + e2e/ci-e2e-config.yaml | 81 + e2e/dockerutil/dockerutil.go | 71 + e2e/go.mod | 282 + e2e/go.sum | 2652 +++ e2e/internal/directories/directories.go | 37 + e2e/relayer/relayer.go | 179 + e2e/sample.config.extended.yaml | 70 + e2e/sample.config.yaml | 8 + e2e/scripts/init.sh | 27 + e2e/scripts/run-e2e.sh | 116 + e2e/semverutil/semver.go | 61 + e2e/semverutil/semver_test.go | 54 + e2e/tests/core/02-client/client_test.go | 526 + .../core/03-connection/connection_test.go | 153 + e2e/tests/interchain_accounts/base_test.go | 542 + e2e/tests/interchain_accounts/gov_test.go | 131 + e2e/tests/interchain_accounts/groups_test.go | 221 + .../interchain_accounts/localhost_test.go | 490 + e2e/tests/interchain_accounts/params_test.go | 275 + e2e/tests/interchain_accounts/query_test.go | 167 + e2e/tests/transfer/authz_test.go | 379 + e2e/tests/transfer/base_test.go | 406 + e2e/tests/transfer/localhost_test.go | 174 + e2e/tests/transfer/send_enabled_test.go | 99 + e2e/tests/transfer/send_receive_test.go | 155 + e2e/tests/upgrades/genesis_test.go | 267 + e2e/tests/upgrades/upgrade_test.go | 995 + e2e/testsuite/codec.go | 129 + e2e/testsuite/diagnostics/diagnostics.go | 163 + e2e/testsuite/events.go | 22 + e2e/testsuite/query/grpc_query.go | 161 + e2e/testsuite/query/queries.go | 165 + e2e/testsuite/sanitize/messages.go | 82 + e2e/testsuite/testconfig.go | 1098 + e2e/testsuite/testsuite.go | 740 + e2e/testsuite/tx.go | 352 + e2e/testvalues/values.go | 127 + go.mod | 223 + go.sum | 2443 ++ go.work.example | 11 + internal/logging/logging.go | 23 + internal/validate/validate.go | 21 + internal/validate/validate_test.go | 57 + maintainership.png | Bin 0 -> 718328 bytes .../27-interchain-accounts/client/cli/cli.go | 44 + .../controller/client/cli/cli.go | 42 + .../controller/client/cli/query.go | 76 + .../controller/client/cli/tx.go | 140 + .../controller/ibc_middleware.go | 281 + .../controller/ibc_middleware_test.go | 936 + .../controller/keeper/account.go | 91 + .../controller/keeper/account_test.go | 116 + .../controller/keeper/events.go | 34 + .../controller/keeper/export_test.go | 16 + .../controller/keeper/genesis.go | 40 + .../controller/keeper/genesis_test.go | 110 + .../controller/keeper/grpc_query.go | 48 + .../controller/keeper/grpc_query_test.go | 84 + .../controller/keeper/handshake.go | 258 + .../controller/keeper/handshake_test.go | 488 + .../controller/keeper/keeper.go | 329 + .../controller/keeper/keeper_test.go | 364 + .../controller/keeper/migrations.go | 32 + .../controller/keeper/migrations_test.go | 58 + .../controller/keeper/msg_server.go | 93 + .../controller/keeper/msg_server_test.go | 252 + .../controller/keeper/relay.go | 60 + .../controller/keeper/relay_test.go | 219 + .../controller/types/codec.go | 18 + .../controller/types/codec_test.go | 61 + .../controller/types/controller.pb.go | 313 + .../controller/types/errors.go | 10 + .../controller/types/keys.go | 12 + .../controller/types/msgs.go | 111 + .../controller/types/msgs_test.go | 269 + .../controller/types/params.go | 18 + .../controller/types/params_legacy.go | 37 + .../controller/types/query.pb.go | 984 + .../controller/types/query.pb.gw.go | 276 + .../controller/types/tx.pb.go | 1599 ++ modules/apps/27-interchain-accounts/doc.go | 8 + .../genesis/types/genesis.go | 128 + .../genesis/types/genesis.pb.go | 1690 ++ .../genesis/types/genesis_test.go | 332 + .../host/client/cli/cli.go | 41 + .../host/client/cli/query.go | 100 + .../host/client/cli/tx.go | 162 + .../host/client/cli/tx_test.go | 163 + .../27-interchain-accounts/host/ibc_module.go | 175 + .../host/ibc_module_test.go | 755 + .../host/keeper/account.go | 35 + .../host/keeper/events.go | 45 + .../host/keeper/export_test.go | 21 + .../host/keeper/genesis.go | 38 + .../host/keeper/genesis_test.go | 134 + .../host/keeper/grpc_query.go | 21 + .../host/keeper/grpc_query_test.go | 12 + .../host/keeper/handshake.go | 121 + .../host/keeper/handshake_test.go | 406 + .../host/keeper/keeper.go | 301 + .../host/keeper/keeper_test.go | 421 + .../host/keeper/migrations.go | 35 + .../host/keeper/migrations_test.go | 62 + .../host/keeper/msg_server.go | 74 + .../host/keeper/msg_server_test.go | 188 + .../host/keeper/relay.go | 152 + .../host/keeper/relay_test.go | 898 + .../host/types/codec.go | 18 + .../host/types/codec_test.go | 52 + .../host/types/errors.go | 10 + .../host/types/host.pb.go | 602 + .../27-interchain-accounts/host/types/keys.go | 31 + .../27-interchain-accounts/host/types/msgs.go | 57 + .../host/types/msgs_test.go | 142 + .../host/types/params.go | 50 + .../host/types/params_legacy.go | 59 + .../host/types/params_test.go | 18 + .../host/types/query.pb.go | 545 + .../host/types/query.pb.gw.go | 153 + .../host/types/tx.pb.go | 1059 + modules/apps/27-interchain-accounts/module.go | 207 + .../27-interchain-accounts/module_test.go | 23 + .../simulation/decoder.go | 30 + .../simulation/decoder_test.go | 64 + .../simulation/genesis.go | 70 + .../simulation/genesis_test.go | 58 + .../simulation/proposals.go | 66 + .../simulation/proposals_test.go | 101 + .../27-interchain-accounts/types/account.go | 156 + .../types/account.pb.go | 376 + .../types/account_test.go | 178 + .../27-interchain-accounts/types/codec.go | 111 + .../types/codec_test.go | 470 + .../27-interchain-accounts/types/errors.go | 26 + .../27-interchain-accounts/types/events.go | 11 + .../types/expected_keepers.go | 34 + .../apps/27-interchain-accounts/types/keys.go | 68 + .../27-interchain-accounts/types/keys_test.go | 23 + .../27-interchain-accounts/types/metadata.go | 182 + .../types/metadata.pb.go | 590 + .../types/metadata_test.go | 446 + .../27-interchain-accounts/types/packet.go | 99 + .../27-interchain-accounts/types/packet.pb.go | 634 + .../types/packet_test.go | 203 + .../apps/27-interchain-accounts/types/port.go | 17 + .../27-interchain-accounts/types/port_test.go | 57 + .../27-interchain-accounts/types/router.go | 20 + modules/apps/callbacks/CHANGELOG.md | 69 + modules/apps/callbacks/README.md | 19 + modules/apps/callbacks/callbacks_test.go | 250 + modules/apps/callbacks/ibc_middleware.go | 366 + modules/apps/callbacks/ibc_middleware_test.go | 1143 + modules/apps/callbacks/ica_test.go | 210 + modules/apps/callbacks/internal/process.go | 61 + modules/apps/callbacks/replay_test.go | 344 + .../apps/callbacks/testing/simapp/README.md | 5 + .../callbacks/testing/simapp/ante_handler.go | 52 + modules/apps/callbacks/testing/simapp/app.go | 880 + .../testing/simapp/contract_keeper.go | 261 + .../apps/callbacks/testing/simapp/encoding.go | 16 + .../apps/callbacks/testing/simapp/export.go | 243 + .../apps/callbacks/testing/simapp/genesis.go | 14 + .../testing/simapp/genesis_account.go | 47 + .../callbacks/testing/simapp/params/amino.go | 27 + .../callbacks/testing/simapp/params/doc.go | 19 + .../testing/simapp/params/encoding.go | 16 + .../callbacks/testing/simapp/params/proto.go | 26 + modules/apps/callbacks/transfer_test.go | 273 + modules/apps/callbacks/types/callbacks.go | 264 + .../apps/callbacks/types/callbacks_test.go | 881 + modules/apps/callbacks/types/errors.go | 15 + modules/apps/callbacks/types/events.go | 104 + modules/apps/callbacks/types/events_test.go | 242 + .../apps/callbacks/types/expected_keepers.go | 108 + modules/apps/callbacks/types/export_test.go | 15 + modules/apps/callbacks/types/keys.go | 33 + modules/apps/callbacks/types/types_test.go | 32 + modules/apps/callbacks/v2/ibc_middleware.go | 454 + .../apps/callbacks/v2/ibc_middleware_test.go | 848 + modules/apps/callbacks/v2/v2_test.go | 166 + modules/apps/transfer/client/cli/cli.go | 45 + modules/apps/transfer/client/cli/query.go | 202 + modules/apps/transfer/client/cli/tx.go | 128 + modules/apps/transfer/doc.go | 8 + modules/apps/transfer/ibc_module.go | 282 + modules/apps/transfer/ibc_module_test.go | 656 + .../apps/transfer/internal/events/events.go | 134 + .../transfer/internal/telemetry/telemetry.go | 71 + .../transfer/internal/types/denomtrace.pb.go | 378 + .../internal/types/legacy_denomtrace.go | 42 + .../internal/types/legacy_denomtrace_test.go | 26 + modules/apps/transfer/keeper/MBT_README.md | 49 + modules/apps/transfer/keeper/export_test.go | 34 + modules/apps/transfer/keeper/genesis.go | 35 + modules/apps/transfer/keeper/genesis_test.go | 59 + modules/apps/transfer/keeper/grpc_query.go | 160 + .../apps/transfer/keeper/grpc_query_test.go | 398 + modules/apps/transfer/keeper/keeper.go | 326 + modules/apps/transfer/keeper/keeper_test.go | 384 + .../apps/transfer/keeper/mbt_relay_test.go | 403 + modules/apps/transfer/keeper/migrations.go | 167 + .../apps/transfer/keeper/migrations_test.go | 482 + .../model_based_tests/Test5Packets.json | 492 + .../keeper/model_based_tests/Test5Packets.tla | 1056 + .../Test5PacketsAllDifferentPass.json | 612 + .../Test5PacketsAllDifferentPass.tla | 1188 + .../TestOnRecvAcknowledgementErrorFail.json | 58 + .../TestOnRecvAcknowledgementErrorFail.tla | 159 + .../TestOnRecvAcknowledgementErrorPass.json | 159 + .../TestOnRecvAcknowledgementErrorPass.tla | 310 + .../TestOnRecvAcknowledgementResultFail.json | 58 + .../TestOnRecvAcknowledgementResultFail.tla | 159 + .../TestOnRecvAcknowledgementResultPass.json | 58 + .../TestOnRecvAcknowledgementResultPass.tla | 159 + .../TestOnRecvPacketFail.json | 58 + .../TestOnRecvPacketFail.tla | 159 + .../TestOnRecvPacketPass.json | 73 + .../TestOnRecvPacketPass.tla | 174 + .../model_based_tests/TestOnTimeoutFail.json | 58 + .../model_based_tests/TestOnTimeoutFail.tla | 159 + .../model_based_tests/TestOnTimeoutPass.json | 159 + .../model_based_tests/TestOnTimeoutPass.tla | 310 + .../TestSendTransferFail.json | 58 + .../TestSendTransferFail.tla | 159 + .../TestSendTransferPass.json | 174 + .../TestSendTransferPass.tla | 323 + .../model_based_tests/TestUnescrowTokens.json | 305 + .../model_based_tests/TestUnescrowTokens.tla | 563 + modules/apps/transfer/keeper/msg_server.go | 151 + .../apps/transfer/keeper/msg_server_test.go | 359 + modules/apps/transfer/keeper/relay.go | 397 + .../transfer/keeper/relay_model/account.tla | 36 + .../keeper/relay_model/account_record.tla | 46 + .../relay_model/apalache-to-relay-test.json | 100 + .../relay_model/apalache-to-relay-test2.json | 104 + .../transfer/keeper/relay_model/denom.tla | 50 + .../keeper/relay_model/denom_record.tla | 53 + .../keeper/relay_model/denom_record2.tla | 114 + .../keeper/relay_model/denom_sequence.tla | 47 + .../keeper/relay_model/identifiers.tla | 10 + .../transfer/keeper/relay_model/relay.tla | 278 + .../keeper/relay_model/relay_tests.tla | 96 + modules/apps/transfer/keeper/relay_test.go | 1262 + modules/apps/transfer/module.go | 172 + modules/apps/transfer/simulation/decoder.go | 30 + .../apps/transfer/simulation/decoder_test.go | 53 + modules/apps/transfer/simulation/genesis.go | 55 + .../apps/transfer/simulation/genesis_test.go | 87 + modules/apps/transfer/simulation/proposals.go | 42 + .../transfer/simulation/proposals_test.go | 43 + modules/apps/transfer/transfer_test.go | 201 + modules/apps/transfer/types/authz.pb.go | 752 + modules/apps/transfer/types/codec.go | 36 + modules/apps/transfer/types/codec_test.go | 73 + modules/apps/transfer/types/denom.go | 226 + modules/apps/transfer/types/denom_test.go | 333 + modules/apps/transfer/types/deprecated.go | 60 + modules/apps/transfer/types/encoding.go | 26 + modules/apps/transfer/types/errors.go | 24 + modules/apps/transfer/types/events.go | 22 + .../apps/transfer/types/expected_keepers.go | 70 + modules/apps/transfer/types/export_test.go | 6 + modules/apps/transfer/types/genesis.go | 39 + modules/apps/transfer/types/genesis.pb.go | 513 + modules/apps/transfer/types/genesis_test.go | 48 + modules/apps/transfer/types/hop.go | 32 + modules/apps/transfer/types/hop_test.go | 68 + modules/apps/transfer/types/keys.go | 77 + modules/apps/transfer/types/keys_test.go | 24 + modules/apps/transfer/types/msgs.go | 147 + modules/apps/transfer/types/msgs_test.go | 157 + modules/apps/transfer/types/packet.go | 287 + modules/apps/transfer/types/packet.pb.go | 534 + modules/apps/transfer/types/packet_test.go | 657 + modules/apps/transfer/types/params.go | 21 + modules/apps/transfer/types/params_legacy.go | 42 + modules/apps/transfer/types/query.pb.go | 2637 +++ modules/apps/transfer/types/query.pb.gw.go | 662 + modules/apps/transfer/types/solidity_abi.go | 111 + .../apps/transfer/types/solidity_abi_test.go | 23 + modules/apps/transfer/types/token.go | 55 + modules/apps/transfer/types/token.pb.go | 840 + modules/apps/transfer/types/token_test.go | 202 + modules/apps/transfer/types/transfer.pb.go | 359 + .../transfer/types/transfer_authorization.go | 198 + .../types/transfer_authorization_test.go | 393 + modules/apps/transfer/types/tx.pb.go | 1309 ++ modules/apps/transfer/types/types_test.go | 29 + modules/apps/transfer/v2/ibc_module.go | 200 + modules/apps/transfer/v2/ibc_module_test.go | 421 + modules/core/02-client/abci.go | 35 + modules/core/02-client/abci_test.go | 133 + modules/core/02-client/client/cli/cli.go | 63 + modules/core/02-client/client/cli/query.go | 438 + modules/core/02-client/client/cli/tx.go | 546 + modules/core/02-client/client/utils/utils.go | 210 + modules/core/02-client/doc.go | 7 + modules/core/02-client/genesis.go | 73 + modules/core/02-client/keeper/client.go | 152 + modules/core/02-client/keeper/client_test.go | 693 + modules/core/02-client/keeper/events.go | 136 + modules/core/02-client/keeper/events_test.go | 94 + modules/core/02-client/keeper/grpc_query.go | 431 + .../core/02-client/keeper/grpc_query_test.go | 1025 + modules/core/02-client/keeper/keeper.go | 517 + modules/core/02-client/keeper/keeper_test.go | 781 + modules/core/02-client/keeper/migrations.go | 55 + .../core/02-client/keeper/migrations_test.go | 59 + .../migrations/v7/expected_keepers.go | 16 + .../core/02-client/migrations/v7/genesis.go | 78 + .../02-client/migrations/v7/genesis_test.go | 141 + .../02-client/migrations/v7/solomachine.go | 236 + .../02-client/migrations/v7/solomachine.pb.go | 4119 ++++ modules/core/02-client/migrations/v7/store.go | 204 + .../02-client/migrations/v7/store_test.go | 171 + modules/core/02-client/module.go | 23 + modules/core/02-client/simulation/decoder.go | 31 + .../core/02-client/simulation/decoder_test.go | 70 + modules/core/02-client/simulation/genesis.go | 14 + modules/core/02-client/types/client.go | 113 + modules/core/02-client/types/client.pb.go | 1238 + modules/core/02-client/types/client_test.go | 86 + modules/core/02-client/types/codec.go | 171 + modules/core/02-client/types/codec_test.go | 245 + modules/core/02-client/types/encoding.go | 114 + modules/core/02-client/types/encoding_test.go | 28 + modules/core/02-client/types/errors.go | 41 + modules/core/02-client/types/events.go | 32 + .../core/02-client/types/expected_keepers.go | 25 + modules/core/02-client/types/genesis.go | 244 + modules/core/02-client/types/genesis.pb.go | 1057 + modules/core/02-client/types/genesis_test.go | 488 + modules/core/02-client/types/height.go | 191 + modules/core/02-client/types/height_test.go | 159 + modules/core/02-client/types/keys.go | 101 + modules/core/02-client/types/keys_test.go | 67 + .../core/02-client/types/legacy_proposal.go | 150 + .../02-client/types/legacy_proposal_test.go | 89 + .../types/legacy_upgrade_proposal.pb.go | 829 + modules/core/02-client/types/msgs.go | 344 + modules/core/02-client/types/msgs_test.go | 968 + modules/core/02-client/types/params.go | 72 + modules/core/02-client/types/params_legacy.go | 37 + modules/core/02-client/types/params_test.go | 56 + modules/core/02-client/types/query.go | 66 + modules/core/02-client/types/query.pb.go | 5342 +++++ modules/core/02-client/types/query.pb.gw.go | 1151 + modules/core/02-client/types/router.go | 51 + modules/core/02-client/types/router_test.go | 132 + modules/core/02-client/types/store.go | 37 + modules/core/02-client/types/tx.pb.go | 3748 +++ modules/core/02-client/v2/genesis.go | 41 + modules/core/02-client/v2/genesis_test.go | 54 + .../core/02-client/v2/keeper/grpc_query.go | 66 + .../02-client/v2/keeper/grpc_query_test.go | 161 + modules/core/02-client/v2/keeper/keeper.go | 64 + .../core/02-client/v2/keeper/keeper_test.go | 86 + modules/core/02-client/v2/module.go | 22 + modules/core/02-client/v2/module_test.go | 31 + modules/core/02-client/v2/types/codec.go | 17 + modules/core/02-client/v2/types/config.go | 53 + modules/core/02-client/v2/types/config.pb.go | 326 + .../core/02-client/v2/types/config_test.go | 84 + .../core/02-client/v2/types/counterparty.go | 9 + .../02-client/v2/types/counterparty.pb.go | 378 + modules/core/02-client/v2/types/errors.go | 8 + modules/core/02-client/v2/types/genesis.go | 36 + modules/core/02-client/v2/types/genesis.pb.go | 563 + .../core/02-client/v2/types/genesis_test.go | 108 + modules/core/02-client/v2/types/keys.go | 21 + modules/core/02-client/v2/types/msgs.go | 73 + modules/core/02-client/v2/types/msgs_test.go | 229 + modules/core/02-client/v2/types/query.pb.go | 991 + .../core/02-client/v2/types/query.pb.gw.go | 290 + modules/core/02-client/v2/types/tx.pb.go | 1093 + modules/core/03-connection/client/cli/cli.go | 26 + .../core/03-connection/client/cli/query.go | 144 + .../core/03-connection/client/utils/utils.go | 218 + modules/core/03-connection/doc.go | 12 + modules/core/03-connection/genesis.go | 34 + modules/core/03-connection/keeper/events.go | 74 + .../core/03-connection/keeper/events_test.go | 156 + .../core/03-connection/keeper/grpc_query.go | 204 + .../03-connection/keeper/grpc_query_test.go | 492 + .../core/03-connection/keeper/handshake.go | 224 + .../03-connection/keeper/handshake_test.go | 370 + modules/core/03-connection/keeper/keeper.go | 253 + .../core/03-connection/keeper/keeper_test.go | 181 + .../core/03-connection/keeper/migrations.go | 40 + .../03-connection/keeper/migrations_test.go | 42 + modules/core/03-connection/keeper/verify.go | 227 + .../core/03-connection/keeper/verify_test.go | 518 + .../migrations/v7/expected_keepers.go | 8 + .../03-connection/migrations/v7/localhost.go | 9 + modules/core/03-connection/module.go | 18 + .../core/03-connection/simulation/decoder.go | 33 + .../03-connection/simulation/decoder_test.go | 69 + .../core/03-connection/simulation/genesis.go | 14 + modules/core/03-connection/types/codec.go | 30 + .../core/03-connection/types/codec_test.go | 68 + .../core/03-connection/types/connection.go | 84 + .../core/03-connection/types/connection.pb.go | 1960 ++ .../03-connection/types/connection_test.go | 119 + modules/core/03-connection/types/errors.go | 19 + modules/core/03-connection/types/events.go | 25 + .../03-connection/types/expected_keepers.go | 23 + modules/core/03-connection/types/genesis.go | 80 + .../core/03-connection/types/genesis.pb.go | 491 + .../core/03-connection/types/genesis_test.go | 149 + modules/core/03-connection/types/keys.go | 65 + modules/core/03-connection/types/keys_test.go | 52 + modules/core/03-connection/types/msgs.go | 204 + modules/core/03-connection/types/msgs_test.go | 269 + modules/core/03-connection/types/params.go | 29 + .../core/03-connection/types/params_legacy.go | 36 + .../core/03-connection/types/params_test.go | 32 + modules/core/03-connection/types/query.go | 71 + modules/core/03-connection/types/query.pb.go | 3234 +++ .../core/03-connection/types/query.pb.gw.go | 684 + modules/core/03-connection/types/tx.pb.go | 3255 +++ modules/core/03-connection/types/version.go | 192 + .../core/03-connection/types/version_test.go | 165 + modules/core/04-channel/client/cli/cli.go | 37 + modules/core/04-channel/client/cli/query.go | 493 + modules/core/04-channel/client/utils/utils.go | 303 + modules/core/04-channel/doc.go | 17 + modules/core/04-channel/genesis.go | 50 + modules/core/04-channel/keeper/ante.go | 24 + modules/core/04-channel/keeper/ante_test.go | 62 + modules/core/04-channel/keeper/events.go | 269 + modules/core/04-channel/keeper/export_test.go | 21 + modules/core/04-channel/keeper/grpc_query.go | 622 + .../core/04-channel/keeper/grpc_query_test.go | 1903 ++ modules/core/04-channel/keeper/handshake.go | 418 + .../core/04-channel/keeper/handshake_test.go | 644 + modules/core/04-channel/keeper/keeper.go | 586 + modules/core/04-channel/keeper/keeper_test.go | 469 + modules/core/04-channel/keeper/migrations.go | 27 + modules/core/04-channel/keeper/packet.go | 449 + modules/core/04-channel/keeper/packet_test.go | 1010 + modules/core/04-channel/keeper/timeout.go | 261 + .../core/04-channel/keeper/timeout_test.go | 481 + .../04-channel/migrations/v10/channel.pb.go | 2964 +++ .../migrations/v10/expected_keepers.go | 14 + .../core/04-channel/migrations/v10/store.go | 124 + .../04-channel/migrations/v10/store_test.go | 232 + .../04-channel/migrations/v10/upgrade.pb.go | 842 + modules/core/04-channel/module.go | 18 + modules/core/04-channel/simulation/decoder.go | 49 + .../04-channel/simulation/decoder_test.go | 89 + modules/core/04-channel/simulation/genesis.go | 14 + .../core/04-channel/types/acknowledgement.go | 92 + .../04-channel/types/acknowledgement_test.go | 171 + modules/core/04-channel/types/channel.go | 89 + modules/core/04-channel/types/channel.pb.go | 2716 +++ modules/core/04-channel/types/channel_test.go | 93 + modules/core/04-channel/types/codec.go | 42 + modules/core/04-channel/types/codec_test.go | 98 + modules/core/04-channel/types/errors.go | 62 + modules/core/04-channel/types/events.go | 52 + .../core/04-channel/types/expected_keepers.go | 70 + modules/core/04-channel/types/genesis.go | 160 + modules/core/04-channel/types/genesis.pb.go | 1011 + modules/core/04-channel/types/genesis_test.go | 228 + modules/core/04-channel/types/keys.go | 67 + modules/core/04-channel/types/keys_test.go | 50 + modules/core/04-channel/types/msgs.go | 376 + modules/core/04-channel/types/msgs_test.go | 1058 + modules/core/04-channel/types/packet.go | 142 + modules/core/04-channel/types/packet_test.go | 74 + modules/core/04-channel/types/query.go | 106 + modules/core/04-channel/types/query.pb.go | 8635 +++++++ modules/core/04-channel/types/query.pb.gw.go | 1956 ++ modules/core/04-channel/types/timeout.go | 73 + modules/core/04-channel/types/timeout_test.go | 230 + modules/core/04-channel/types/tx.pb.go | 5596 +++++ modules/core/04-channel/v2/client/cli/abci.go | 71 + modules/core/04-channel/v2/client/cli/cli.go | 48 + .../core/04-channel/v2/client/cli/query.go | 350 + modules/core/04-channel/v2/genesis.go | 73 + modules/core/04-channel/v2/genesis_test.go | 76 + modules/core/04-channel/v2/keeper/events.go | 133 + .../core/04-channel/v2/keeper/export_test.go | 70 + .../core/04-channel/v2/keeper/grpc_query.go | 322 + .../04-channel/v2/keeper/grpc_query_test.go | 815 + modules/core/04-channel/v2/keeper/keeper.go | 263 + .../core/04-channel/v2/keeper/keeper_test.go | 31 + .../core/04-channel/v2/keeper/msg_server.go | 250 + .../04-channel/v2/keeper/msg_server_test.go | 553 + modules/core/04-channel/v2/keeper/packet.go | 354 + .../core/04-channel/v2/keeper/packet_test.go | 603 + modules/core/04-channel/v2/module.go | 22 + modules/core/04-channel/v2/module_test.go | 31 + .../04-channel/v2/types/acknowledgement.go | 52 + .../v2/types/acknowledgement_test.go | 50 + modules/core/04-channel/v2/types/codec.go | 21 + .../core/04-channel/v2/types/commitment.go | 66 + .../04-channel/v2/types/commitment_test.go | 101 + modules/core/04-channel/v2/types/errors.go | 19 + modules/core/04-channel/v2/types/events.go | 28 + .../04-channel/v2/types/expected_keepers.go | 28 + modules/core/04-channel/v2/types/genesis.go | 117 + .../core/04-channel/v2/types/genesis.pb.go | 1042 + .../core/04-channel/v2/types/genesis_test.go | 84 + modules/core/04-channel/v2/types/keys.go | 25 + modules/core/04-channel/v2/types/merkle.go | 22 + .../core/04-channel/v2/types/merkle_test.go | 69 + modules/core/04-channel/v2/types/msgs.go | 145 + modules/core/04-channel/v2/types/msgs_test.go | 305 + modules/core/04-channel/v2/types/packet.go | 87 + modules/core/04-channel/v2/types/packet.pb.go | 1342 ++ .../core/04-channel/v2/types/packet_test.go | 144 + modules/core/04-channel/v2/types/query.go | 82 + modules/core/04-channel/v2/types/query.pb.go | 4757 ++++ .../core/04-channel/v2/types/query.pb.gw.go | 1042 + modules/core/04-channel/v2/types/tx.pb.go | 2261 ++ modules/core/05-port/doc.go | 7 + modules/core/05-port/keeper/keeper.go | 47 + modules/core/05-port/keeper/keeper_test.go | 31 + modules/core/05-port/module.go | 18 + modules/core/05-port/types/errors.go | 13 + modules/core/05-port/types/keys.go | 15 + modules/core/05-port/types/module.go | 147 + modules/core/05-port/types/router.go | 79 + modules/core/23-commitment/types/codec.go | 37 + .../core/23-commitment/types/codec_test.go | 56 + .../core/23-commitment/types/commitment.pb.go | 685 + .../23-commitment/types/commitment_test.go | 41 + modules/core/23-commitment/types/errors.go | 15 + modules/core/23-commitment/types/merkle.go | 218 + .../core/23-commitment/types/merkle_test.go | 155 + modules/core/23-commitment/types/utils.go | 29 + .../core/23-commitment/types/utils_test.go | 105 + .../23-commitment/types/v2/commitment.pb.go | 353 + modules/core/23-commitment/types/v2/merkle.go | 73 + .../23-commitment/types/v2/merkle_test.go | 64 + modules/core/24-host/channel_keys.go | 20 + modules/core/24-host/client_keys.go | 52 + modules/core/24-host/connection_keys.go | 18 + modules/core/24-host/doc.go | 8 + modules/core/24-host/errors.go | 15 + modules/core/24-host/packet_keys.go | 72 + modules/core/24-host/parse.go | 120 + modules/core/24-host/parse_test.go | 106 + modules/core/24-host/port_keys.go | 8 + modules/core/24-host/v2/packet_key_test.go | 34 + modules/core/24-host/v2/packet_keys.go | 54 + modules/core/24-host/validate.go | 118 + modules/core/24-host/validate_test.go | 152 + modules/core/ante/ante.go | 208 + modules/core/ante/ante_test.go | 745 + modules/core/api/api_test.go | 15 + modules/core/api/module.go | 71 + modules/core/api/router.go | 129 + modules/core/api/router_test.go | 135 + modules/core/client/cli/cli.go | 52 + modules/core/client/query.go | 69 + modules/core/errors/errors.go | 63 + modules/core/exported/client.go | 186 + modules/core/exported/commitment.go | 30 + modules/core/exported/connection.go | 4 + modules/core/exported/module.go | 12 + modules/core/exported/packet.go | 52 + modules/core/genesis.go | 34 + modules/core/genesis_test.go | 476 + modules/core/internal/errors/errors.go | 25 + modules/core/internal/telemetry/client.go | 58 + modules/core/internal/telemetry/packet.go | 44 + modules/core/internal/v2/telemetry/packet.go | 56 + modules/core/keeper/events_test.go | 106 + modules/core/keeper/expected_keeper.go | 38 + modules/core/keeper/keeper.go | 111 + modules/core/keeper/keeper_test.go | 125 + modules/core/keeper/msg_server.go | 701 + modules/core/keeper/msg_server_test.go | 1378 ++ modules/core/metrics/metrics.go | 21 + modules/core/migrations/v7/genesis.go | 42 + modules/core/migrations/v7/genesis_test.go | 168 + modules/core/module.go | 237 + modules/core/simulation/decoder.go | 33 + modules/core/simulation/decoder_test.go | 80 + modules/core/simulation/genesis.go | 64 + modules/core/simulation/genesis_test.go | 54 + modules/core/simulation/proposals.go | 117 + modules/core/simulation/proposals_test.go | 83 + modules/core/types/codec.go | 23 + modules/core/types/events.go | 3 + modules/core/types/expected_interfaces.go | 11 + modules/core/types/genesis.go | 51 + modules/core/types/genesis.pb.go | 552 + .../06-solomachine/client_state.go | 194 + .../06-solomachine/client_state_test.go | 100 + modules/light-clients/06-solomachine/codec.go | 43 + .../06-solomachine/codec_test.go | 62 + .../06-solomachine/consensus_state.go | 57 + .../06-solomachine/consensus_state_test.go | 74 + modules/light-clients/06-solomachine/doc.go | 10 + .../light-clients/06-solomachine/errors.go | 13 + .../light-clients/06-solomachine/header.go | 61 + .../06-solomachine/header_test.go | 84 + modules/light-clients/06-solomachine/keys.go | 5 + .../06-solomachine/light_client_module.go | 224 + .../light_client_module_test.go | 1687 ++ .../06-solomachine/misbehaviour.go | 63 + .../06-solomachine/misbehaviour_handle.go | 72 + .../06-solomachine/misbehaviour_test.go | 134 + .../light-clients/06-solomachine/module.go | 87 + modules/light-clients/06-solomachine/proof.go | 44 + .../06-solomachine/proof_test.go | 68 + .../06-solomachine/proposal_handle.go | 54 + .../06-solomachine/solomachine.go | 32 + .../06-solomachine/solomachine.pb.go | 2230 ++ .../06-solomachine/solomachine_test.go | 207 + modules/light-clients/06-solomachine/store.go | 30 + .../light-clients/06-solomachine/update.go | 101 + .../07-tendermint/client_state.go | 326 + .../07-tendermint/client_state_test.go | 134 + modules/light-clients/07-tendermint/codec.go | 28 + .../light-clients/07-tendermint/codec_test.go | 62 + .../07-tendermint/consensus_state.go | 61 + .../07-tendermint/consensus_state_test.go | 88 + modules/light-clients/07-tendermint/doc.go | 10 + modules/light-clients/07-tendermint/errors.go | 23 + .../light-clients/07-tendermint/fraction.go | 25 + modules/light-clients/07-tendermint/header.go | 83 + .../07-tendermint/header_test.go | 82 + modules/light-clients/07-tendermint/keys.go | 5 + .../07-tendermint/light_client_module.go | 240 + .../07-tendermint/light_client_module_test.go | 1187 + .../migrations/expected_keepers.go | 18 + .../07-tendermint/migrations/migrations.go | 46 + .../migrations/migrations_test.go | 178 + .../07-tendermint/misbehaviour.go | 125 + .../07-tendermint/misbehaviour_handle.go | 172 + .../07-tendermint/misbehaviour_handle_test.go | 696 + .../07-tendermint/misbehaviour_test.go | 240 + modules/light-clients/07-tendermint/module.go | 87 + .../07-tendermint/proposal_handle.go | 103 + .../07-tendermint/proposal_handle_test.go | 236 + modules/light-clients/07-tendermint/store.go | 344 + .../light-clients/07-tendermint/store_test.go | 199 + .../07-tendermint/tendermint.pb.go | 1907 ++ .../07-tendermint/tendermint_test.go | 115 + modules/light-clients/07-tendermint/update.go | 235 + .../07-tendermint/update_test.go | 958 + .../light-clients/07-tendermint/upgrade.go | 188 + .../07-tendermint/upgrade_test.go | 697 + modules/light-clients/08-wasm/CHANGELOG.md | 154 + modules/light-clients/08-wasm/Dockerfile | 49 + modules/light-clients/08-wasm/README.md | 29 + .../08-wasm/blsverifier/crypto.go | 19 + .../08-wasm/blsverifier/handler.go | 67 + .../light-clients/08-wasm/client/cli/cli.go | 43 + .../light-clients/08-wasm/client/cli/query.go | 80 + .../light-clients/08-wasm/client/cli/tx.go | 128 + modules/light-clients/08-wasm/doc.go | 18 + modules/light-clients/08-wasm/go.mod | 242 + modules/light-clients/08-wasm/go.sum | 2533 ++ .../08-wasm/internal/types/store.go | 227 + .../08-wasm/internal/types/store_test.go | 438 + .../08-wasm/keeper/contract_keeper.go | 307 + .../08-wasm/keeper/contract_keeper_test.go | 560 + .../light-clients/08-wasm/keeper/events.go | 39 + .../08-wasm/keeper/export_test.go | 18 + .../light-clients/08-wasm/keeper/genesis.go | 49 + .../08-wasm/keeper/genesis_test.go | 89 + .../08-wasm/keeper/grpc_query.go | 64 + .../08-wasm/keeper/grpc_query_test.go | 130 + .../light-clients/08-wasm/keeper/keeper.go | 246 + .../08-wasm/keeper/keeper_no_vm.go | 43 + .../08-wasm/keeper/keeper_test.go | 549 + .../light-clients/08-wasm/keeper/keeper_vm.go | 97 + .../08-wasm/keeper/migrations.go | 72 + .../08-wasm/keeper/migrations_test.go | 60 + .../08-wasm/keeper/msg_server.go | 79 + .../08-wasm/keeper/msg_server_test.go | 429 + .../light-clients/08-wasm/keeper/options.go | 23 + .../08-wasm/keeper/options_test.go | 153 + .../light-clients/08-wasm/keeper/querier.go | 182 + .../08-wasm/keeper/querier_test.go | 352 + .../08-wasm/keeper/snapshotter.go | 146 + .../08-wasm/keeper/snapshotter_test.go | 121 + .../08-wasm/light_client_module.go | 483 + .../08-wasm/light_client_module_test.go | 1582 ++ modules/light-clients/08-wasm/module.go | 144 + .../08-wasm/simulation/proposals.go | 40 + .../08-wasm/simulation/proposals_test.go | 41 + .../08-wasm/testing/mock_engine.go | 284 + .../08-wasm/testing/simapp/README.md | 5 + .../08-wasm/testing/simapp/ante_handler.go | 50 + .../08-wasm/testing/simapp/app.go | 1064 + .../08-wasm/testing/simapp/encoding.go | 18 + .../08-wasm/testing/simapp/export.go | 246 + .../08-wasm/testing/simapp/genesis.go | 14 + .../08-wasm/testing/simapp/genesis_account.go | 47 + .../08-wasm/testing/simapp/params/amino.go | 27 + .../08-wasm/testing/simapp/params/doc.go | 19 + .../08-wasm/testing/simapp/params/encoding.go | 16 + .../08-wasm/testing/simapp/params/proto.go | 26 + .../08-wasm/testing/simapp/simd/cmd/root.go | 422 + .../08-wasm/testing/simapp/simd/main.go | 20 + .../08-wasm/testing/simapp/test_helpers.go | 112 + .../08-wasm/testing/simapp/upgrades.go | 45 + .../light-clients/08-wasm/testing/values.go | 59 + .../08-wasm/testing/wasm_endpoint.go | 52 + .../08-wasm/types/client_message.go | 23 + .../08-wasm/types/client_message_test.go | 53 + .../08-wasm/types/client_state.go | 37 + .../08-wasm/types/client_state_test.go | 69 + modules/light-clients/08-wasm/types/codec.go | 34 + .../light-clients/08-wasm/types/codec_test.go | 75 + modules/light-clients/08-wasm/types/config.go | 45 + .../08-wasm/types/consensus_state.go | 35 + .../08-wasm/types/consensus_state_test.go | 43 + .../08-wasm/types/contract_api.go | 125 + modules/light-clients/08-wasm/types/errors.go | 23 + modules/light-clients/08-wasm/types/events.go | 18 + .../08-wasm/types/expected_interfaces.go | 124 + .../08-wasm/types/expected_keepers.go | 16 + .../08-wasm/types/gas_register.go | 268 + .../08-wasm/types/gas_register_custom.go | 62 + .../light-clients/08-wasm/types/genesis.go | 22 + .../light-clients/08-wasm/types/genesis.pb.go | 504 + .../08-wasm/types/genesis_test.go | 41 + modules/light-clients/08-wasm/types/keys.go | 21 + modules/light-clients/08-wasm/types/msgs.go | 94 + .../light-clients/08-wasm/types/msgs_test.go | 270 + .../light-clients/08-wasm/types/query.pb.go | 1054 + .../08-wasm/types/query.pb.gw.go | 272 + modules/light-clients/08-wasm/types/store.go | 44 + modules/light-clients/08-wasm/types/tx.pb.go | 1524 ++ .../light-clients/08-wasm/types/types_test.go | 54 + modules/light-clients/08-wasm/types/utils.go | 71 + .../light-clients/08-wasm/types/validation.go | 53 + .../08-wasm/types/validation_test.go | 160 + .../light-clients/08-wasm/types/wasm.pb.go | 934 + .../light-clients/08-wasm/types/wasm_vm.go | 7 + modules/light-clients/08-wasm/wasm_test.go | 118 + modules/light-clients/09-localhost/doc.go | 10 + .../09-localhost/light_client_module.go | 181 + .../09-localhost/light_client_module_test.go | 369 + package-lock.json | 6 + proto/buf.gen.gogo.yaml | 8 + proto/buf.gen.swagger.yaml | 5 + proto/buf.lock | 28 + proto/buf.yaml | 23 + .../controller/v1/controller.proto | 12 + .../controller/v1/query.proto | 42 + .../controller/v1/tx.proto | 82 + .../genesis/v1/genesis.proto | 47 + .../interchain_accounts/host/v1/host.proto | 25 + .../interchain_accounts/host/v1/query.proto | 25 + .../interchain_accounts/host/v1/tx.proto | 60 + .../interchain_accounts/v1/account.proto | 19 + .../interchain_accounts/v1/metadata.proto | 23 + .../interchain_accounts/v1/packet.proto | 31 + .../ibc/applications/transfer/v1/authz.proto | 34 + .../applications/transfer/v1/denomtrace.proto | 16 + .../applications/transfer/v1/genesis.proto | 21 + .../ibc/applications/transfer/v1/packet.proto | 21 + .../ibc/applications/transfer/v1/query.proto | 122 + .../ibc/applications/transfer/v1/token.proto | 30 + .../applications/transfer/v1/transfer.proto | 18 + proto/ibc/applications/transfer/v1/tx.proto | 83 + proto/ibc/core/channel/v1/channel.proto | 171 + proto/ibc/core/channel/v1/genesis.proto | 29 + proto/ibc/core/channel/v1/query.proto | 402 + proto/ibc/core/channel/v1/tx.proto | 257 + proto/ibc/core/channel/v2/genesis.proto | 39 + proto/ibc/core/channel/v2/packet.proto | 68 + proto/ibc/core/channel/v2/query.proto | 199 + proto/ibc/core/channel/v2/tx.proto | 117 + proto/ibc/core/client/v1/client.proto | 66 + proto/ibc/core/client/v1/genesis.proto | 44 + proto/ibc/core/client/v1/query.proto | 263 + proto/ibc/core/client/v1/tx.proto | 199 + proto/ibc/core/client/v2/config.proto | 14 + proto/ibc/core/client/v2/counterparty.proto | 13 + proto/ibc/core/client/v2/genesis.proto | 23 + proto/ibc/core/client/v2/query.proto | 46 + proto/ibc/core/client/v2/tx.proto | 58 + proto/ibc/core/commitment/v1/commitment.proto | 32 + proto/ibc/core/commitment/v2/commitment.proto | 40 + proto/ibc/core/connection/v1/connection.proto | 114 + proto/ibc/core/connection/v1/genesis.proto | 17 + proto/ibc/core/connection/v1/query.proto | 152 + proto/ibc/core/connection/v1/tx.proto | 150 + proto/ibc/core/types/v1/genesis.proto | 26 + .../solomachine/v2/solomachine.proto | 189 + .../solomachine/v3/solomachine.proto | 99 + .../tendermint/v1/tendermint.proto | 101 + proto/ibc/lightclients/wasm/v1/genesis.proto | 20 + proto/ibc/lightclients/wasm/v1/query.proto | 46 + proto/ibc/lightclients/wasm/v1/tx.proto | 66 + proto/ibc/lightclients/wasm/v1/wasm.proto | 43 + releases-decision-tree.png | Bin 0 -> 90013 bytes requirements.txt | 6 + scripts/README.md | 3 + scripts/build-wasm-simapp-docker.sh | 16 + scripts/compatibility.md | 40 + scripts/generate-compatibility-json.py | 347 + scripts/get-libwasm-version.py | 97 + scripts/go-lint-all.sh | 18 + scripts/go-mod-tidy-all.sh | 9 + scripts/go-test-all.py | 60 + scripts/init-simapp.sh | 17 + scripts/linkify_changelog.py | 15 + scripts/protoc-swagger-gen.sh | 24 + scripts/protocgen.sh | 21 + simapp/README.md | 110 + simapp/ante.go | 56 + simapp/app.go | 883 + simapp/export.go | 249 + simapp/genesis.go | 14 + simapp/go.mod | 230 + simapp/go.sum | 2457 ++ simapp/params/doc.go | 19 + simapp/params/encoding.go | 16 + simapp/params/params.go | 7 + simapp/params/weights.go | 28 + simapp/simd/cmd/cmd_test.go | 25 + simapp/simd/cmd/root.go | 367 + simapp/simd/main.go | 20 + simapp/upgrades.go | 83 + simapp/upgrades/upgrades.go | 86 + testing/README.md | 330 + testing/chain.go | 630 + testing/chain_test.go | 77 + testing/config.go | 61 + testing/coordinator.go | 161 + testing/endpoint.go | 709 + testing/endpoint_v2.go | 105 + testing/events.go | 341 + testing/events_test.go | 390 + testing/mock/README.md | 6 + testing/mock/ack.go | 23 + testing/mock/address_codec.go | 27 + testing/mock/doc.go | 9 + testing/mock/events.go | 40 + testing/mock/ibc_app.go | 125 + testing/mock/ibc_module.go | 152 + testing/mock/middleware.go | 157 + testing/mock/mock.go | 159 + testing/mock/v2/ibc_app.go | 14 + testing/mock/v2/ibc_module.go | 75 + testing/mock/v2/mock.go | 36 + testing/path.go | 245 + testing/simapp/README.md | 47 + testing/simapp/ante.go | 51 + testing/simapp/app.go | 873 + testing/simapp/genesis.go | 14 + testing/simapp/test_helpers.go | 136 + testing/solomachine.go | 679 + testing/testing_app.go | 141 + testing/utils.go | 96 + testing/values.go | 79 + 1709 files changed, 334985 insertions(+) create mode 100644 .clang-format create mode 100644 .github/.codespellignore create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/epic-tracker.md create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md create mode 100644 .github/ISSUE_TEMPLATE/release-tracker.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/mergify.yml create mode 100644 .github/workflows/build-simd-image-from-tag.yml create mode 100644 .github/workflows/build-wasm-simd-image-from-tag.yml create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 .github/workflows/docker.yml create mode 100644 .github/workflows/docs-check.yml create mode 100644 .github/workflows/docs-deploy.yml create mode 100644 .github/workflows/e2e-compatibility-workflow-call.yaml create mode 100644 .github/workflows/e2e-compatibility.yaml create mode 100644 .github/workflows/e2e-test-workflow-call.yml create mode 100644 .github/workflows/e2e-upgrade.yaml create mode 100644 .github/workflows/e2e.yaml create mode 100644 .github/workflows/golangci.yml create mode 100644 .github/workflows/proto-breaking-check.yml create mode 100644 .github/workflows/proto-registry.yml create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 .golangci.yml create mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 RELEASES.md create mode 100644 SECURITY.md create mode 100644 buf.work.yaml create mode 100644 cmd/build_test_matrix/main.go create mode 100644 cmd/build_test_matrix/main_test.go create mode 100644 codecov.yml create mode 100644 contrib/devtools/Makefile create mode 100644 contrib/test_cover.sh create mode 100644 docs/.gitignore create mode 100644 docs/.markdownlint-cli2.jsonc create mode 100644 docs/.markdownlint.jsonc create mode 100644 docs/README.md create mode 100644 docs/architecture/README.md create mode 100644 docs/architecture/adr-001-coin-source-tracing.md create mode 100644 docs/architecture/adr-002-go-module-versioning.md create mode 100644 docs/architecture/adr-003-ics27-acknowledgement.md create mode 100644 docs/architecture/adr-004-ics29-lock-fee-module.md create mode 100644 docs/architecture/adr-005-consensus-height-events.md create mode 100644 docs/architecture/adr-006-02-client-refactor.md create mode 100644 docs/architecture/adr-007-solomachine-signbytes.md create mode 100644 docs/architecture/adr-008-app-caller-cbs.md create mode 100644 docs/architecture/adr-009-v6-ics27-msgserver.md create mode 100644 docs/architecture/adr-010-light-clients-as-sdk-modules.md create mode 100644 docs/architecture/adr-011-transfer-total-escrow-state-entry.md create mode 100644 docs/architecture/adr-015-ibc-packet-receiver.md create mode 100644 docs/architecture/adr-025-ibc-passive-channels.md create mode 100644 docs/architecture/adr-026-ibc-client-recovery-mechanisms.md create mode 100644 docs/architecture/adr-027-ibc-wasm.md create mode 100644 docs/architecture/adr.template.md create mode 100644 docs/audits/04-channel-upgrades/Atredis Partners - Interchain Foundation IBC-Go Channel Upgrade Feature Assessment - Report v1.1.pdf create mode 100644 docs/audits/08-wasm/Ethan Frey - Wasm Client Review.pdf create mode 100644 docs/audits/08-wasm/Halborn audit report.pdf create mode 100644 docs/audits/20-token-transfer/Atredis Partners - Interchain ICS20 v2 New Features Assessment - Report v1.0.pdf create mode 100644 docs/audits/27-interchain-accounts/Trail of Bits audit - Final Report.pdf create mode 100644 docs/audits/IBC-v2/IBC-v2-April-2025-Collaborative-Audit-Report.pdf create mode 100644 docs/babel.config.js create mode 100644 docs/client/config.json create mode 100644 docs/client/swagger-ui/swagger.yaml create mode 100644 docs/dev/development-setup.md create mode 100644 docs/dev/go-style-guide.md create mode 100644 docs/dev/project-structure.md create mode 100644 docs/dev/pull-requests.md create mode 100644 docs/dev/release-management.md create mode 100644 docs/docs/00-intro.md create mode 100644 docs/docs/01-ibc/01-overview.md create mode 100644 docs/docs/01-ibc/02-integration.md create mode 100644 docs/docs/01-ibc/03-apps/00-ibcv2apps.md create mode 100644 docs/docs/01-ibc/03-apps/01-apps.md create mode 100644 docs/docs/01-ibc/03-apps/02-ibcmodule.md create mode 100644 docs/docs/01-ibc/03-apps/03-bindports.md create mode 100644 docs/docs/01-ibc/03-apps/04-keeper.md create mode 100644 docs/docs/01-ibc/03-apps/05-packets_acks.md create mode 100644 docs/docs/01-ibc/03-apps/06-routing.md create mode 100644 docs/docs/01-ibc/03-apps/_category_.json create mode 100644 docs/docs/01-ibc/03-apps/images/packet_flow.png create mode 100644 docs/docs/01-ibc/03-apps/images/packet_flow_v2.png create mode 100644 docs/docs/01-ibc/04-middleware/01-overview.md create mode 100644 docs/docs/01-ibc/04-middleware/02-develop.md create mode 100644 docs/docs/01-ibc/04-middleware/02-developIBCv2.md create mode 100644 docs/docs/01-ibc/04-middleware/03-integration.md create mode 100644 docs/docs/01-ibc/04-middleware/_category_.json create mode 100644 docs/docs/01-ibc/04-middleware/images/middleware-stack.png create mode 100644 docs/docs/01-ibc/05-upgrades/00-intro.md create mode 100644 docs/docs/01-ibc/05-upgrades/01-quick-guide.md create mode 100644 docs/docs/01-ibc/05-upgrades/02-developer-guide.md create mode 100644 docs/docs/01-ibc/05-upgrades/03-genesis-restart.md create mode 100644 docs/docs/01-ibc/05-upgrades/_category_.json create mode 100644 docs/docs/01-ibc/07-relayer.md create mode 100644 docs/docs/01-ibc/08-best-practices.md create mode 100644 docs/docs/01-ibc/09-permissioning.md create mode 100644 docs/docs/01-ibc/_category_.json create mode 100644 docs/docs/02-apps/01-transfer/01-overview.md create mode 100644 docs/docs/02-apps/01-transfer/02-state.md create mode 100644 docs/docs/02-apps/01-transfer/03-state-transitions.md create mode 100644 docs/docs/02-apps/01-transfer/04-messages.md create mode 100644 docs/docs/02-apps/01-transfer/05-events.md create mode 100644 docs/docs/02-apps/01-transfer/06-metrics.md create mode 100644 docs/docs/02-apps/01-transfer/07-params.md create mode 100644 docs/docs/02-apps/01-transfer/08-authorizations.md create mode 100644 docs/docs/02-apps/01-transfer/09-client.md create mode 100644 docs/docs/02-apps/01-transfer/10-IBCv2-transfer.md create mode 100644 docs/docs/02-apps/01-transfer/_category_.json create mode 100644 docs/docs/02-apps/01-transfer/images/forwarding-3-chains-dark.png create mode 100644 docs/docs/02-apps/01-transfer/images/forwarding-3-chains-light.png create mode 100644 docs/docs/02-apps/02-interchain-accounts/01-overview.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/02-development.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/03-auth-modules.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/04-integration.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/05-messages.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/06-parameters.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/07-tx-encoding.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/08-client.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/09-active-channels.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/10-legacy/02-integration.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md create mode 100644 docs/docs/02-apps/02-interchain-accounts/10-legacy/_category_.json create mode 100644 docs/docs/02-apps/02-interchain-accounts/10-legacy/images/ica-pre-v6.png create mode 100644 docs/docs/02-apps/02-interchain-accounts/_category_.json create mode 100644 docs/docs/02-apps/02-interchain-accounts/images/ica-v6.png create mode 100644 docs/docs/02-apps/_category_.json create mode 100644 docs/docs/03-light-clients/01-developer-guide/01-overview.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/02-light-client-module.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/03-client-state.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/04-consensus-state.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/05-updates-and-misbehaviour.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/06-upgrades.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/07-proofs.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/08-proposals.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/09-setup.md create mode 100644 docs/docs/03-light-clients/01-developer-guide/_category_.json create mode 100644 docs/docs/03-light-clients/02-localhost/01-overview.md create mode 100644 docs/docs/03-light-clients/02-localhost/02-integration.md create mode 100644 docs/docs/03-light-clients/02-localhost/03-client-state.md create mode 100644 docs/docs/03-light-clients/02-localhost/04-connection.md create mode 100644 docs/docs/03-light-clients/02-localhost/05-state-verification.md create mode 100644 docs/docs/03-light-clients/02-localhost/_category_.json create mode 100644 docs/docs/03-light-clients/03-solomachine/01-solomachine.md create mode 100644 docs/docs/03-light-clients/03-solomachine/02-concepts.md create mode 100644 docs/docs/03-light-clients/03-solomachine/03-state.md create mode 100644 docs/docs/03-light-clients/03-solomachine/04-state_transitions.md create mode 100644 docs/docs/03-light-clients/03-solomachine/_category_.json create mode 100644 docs/docs/03-light-clients/04-wasm/01-overview.md create mode 100644 docs/docs/03-light-clients/04-wasm/02-concepts.md create mode 100644 docs/docs/03-light-clients/04-wasm/03-integration.md create mode 100644 docs/docs/03-light-clients/04-wasm/04-messages.md create mode 100644 docs/docs/03-light-clients/04-wasm/05-governance.md create mode 100644 docs/docs/03-light-clients/04-wasm/06-events.md create mode 100644 docs/docs/03-light-clients/04-wasm/07-contracts.md create mode 100644 docs/docs/03-light-clients/04-wasm/08-client.md create mode 100644 docs/docs/03-light-clients/04-wasm/09-migrations.md create mode 100644 docs/docs/03-light-clients/04-wasm/_category_.json create mode 100644 docs/docs/03-light-clients/05-tendermint/01-overview.md create mode 100644 docs/docs/03-light-clients/05-tendermint/_category_.json create mode 100644 docs/docs/03-light-clients/06-proposals.md create mode 100644 docs/docs/03-light-clients/_category_.json create mode 100644 docs/docs/04-middleware/01-callbacks/01-overview.md create mode 100644 docs/docs/04-middleware/01-callbacks/02-integration.md create mode 100644 docs/docs/04-middleware/01-callbacks/03-interfaces.md create mode 100644 docs/docs/04-middleware/01-callbacks/04-events.md create mode 100644 docs/docs/04-middleware/01-callbacks/05-end-users.md create mode 100644 docs/docs/04-middleware/01-callbacks/06-gas.md create mode 100644 docs/docs/04-middleware/01-callbacks/07-callbacks-IBCv2.md create mode 100644 docs/docs/04-middleware/01-callbacks/_category_.json create mode 100644 docs/docs/04-middleware/01-callbacks/images/callbackflow.svg create mode 100644 docs/docs/04-middleware/01-callbacks/images/ics4-callbackflow.svg create mode 100644 docs/docs/04-middleware/_category_.json create mode 100644 docs/docs/05-migrations/01-support-denoms-with-slashes.md create mode 100644 docs/docs/05-migrations/02-sdk-to-v1.md create mode 100644 docs/docs/05-migrations/03-v1-to-v2.md create mode 100644 docs/docs/05-migrations/04-v2-to-v3.md create mode 100644 docs/docs/05-migrations/05-v3-to-v4.md create mode 100644 docs/docs/05-migrations/06-v4-to-v5.md create mode 100644 docs/docs/05-migrations/07-v5-to-v6.md create mode 100644 docs/docs/05-migrations/08-v6-to-v7.md create mode 100644 docs/docs/05-migrations/09-v7-to-v7_1.md create mode 100644 docs/docs/05-migrations/10-v7_2-to-v7_3.md create mode 100644 docs/docs/05-migrations/11-v7-to-v8.md create mode 100644 docs/docs/05-migrations/12-v8-to-v8_1.md create mode 100644 docs/docs/05-migrations/13-v8_1-to-v10.md create mode 100644 docs/docs/05-migrations/_category_.json create mode 100644 docs/docs/05-migrations/images/auth-module-decision-tree.png create mode 100644 docs/docs/05-migrations/migration.template.md create mode 100644 docs/docs/images/ibcoverview-dark.svg create mode 100644 docs/docs/images/ibcoverview-light.svg create mode 100644 docs/docusaurus.config.js create mode 100644 docs/events/events.md create mode 100644 docs/package-lock.json create mode 100644 docs/package.json create mode 100644 docs/params/params.md create mode 100644 docs/requirements/ics08-requirements.md create mode 100644 docs/requirements/ics27-multiplexed-requirements.md create mode 100644 docs/requirements/ics27-requirements.md create mode 100644 docs/requirements/ics27-v2-requirements.md create mode 100644 docs/requirements/ics29-v1-requirements.md create mode 100644 docs/requirements/localhost-requirements.md create mode 100644 docs/requirements/path-unwinding-forwarding-requirements.md create mode 100644 docs/requirements/requirements-template.md create mode 100644 docs/sidebars.js create mode 100644 docs/src/components/HighlightBox.jsx create mode 100644 docs/src/components/HighlightTag.jsx create mode 100644 docs/src/css/base.css create mode 100644 docs/src/css/custom.css create mode 100644 docs/src/css/fonts.css create mode 100644 docs/src/theme/CodeBlock/index.js create mode 100644 docs/static/.nojekyll create mode 100644 docs/static/CNAME create mode 100644 docs/static/fonts/inter/Inter-Black.woff create mode 100644 docs/static/fonts/inter/Inter-Black.woff2 create mode 100644 docs/static/fonts/inter/Inter-BlackItalic.woff create mode 100644 docs/static/fonts/inter/Inter-BlackItalic.woff2 create mode 100644 docs/static/fonts/inter/Inter-Bold.woff create mode 100644 docs/static/fonts/inter/Inter-Bold.woff2 create mode 100644 docs/static/fonts/inter/Inter-BoldItalic.woff create mode 100644 docs/static/fonts/inter/Inter-BoldItalic.woff2 create mode 100644 docs/static/fonts/inter/Inter-ExtraBold.woff create mode 100644 docs/static/fonts/inter/Inter-ExtraBold.woff2 create mode 100644 docs/static/fonts/inter/Inter-ExtraBoldItalic.woff create mode 100644 docs/static/fonts/inter/Inter-ExtraBoldItalic.woff2 create mode 100644 docs/static/fonts/inter/Inter-ExtraLight.woff create mode 100644 docs/static/fonts/inter/Inter-ExtraLight.woff2 create mode 100644 docs/static/fonts/inter/Inter-ExtraLightItalic.woff create mode 100644 docs/static/fonts/inter/Inter-ExtraLightItalic.woff2 create mode 100644 docs/static/fonts/inter/Inter-Italic.woff create mode 100644 docs/static/fonts/inter/Inter-Italic.woff2 create mode 100644 docs/static/fonts/inter/Inter-Light.woff create mode 100644 docs/static/fonts/inter/Inter-Light.woff2 create mode 100644 docs/static/fonts/inter/Inter-LightItalic.woff create mode 100644 docs/static/fonts/inter/Inter-LightItalic.woff2 create mode 100644 docs/static/fonts/inter/Inter-Medium.woff create mode 100644 docs/static/fonts/inter/Inter-Medium.woff2 create mode 100644 docs/static/fonts/inter/Inter-MediumItalic.woff create mode 100644 docs/static/fonts/inter/Inter-MediumItalic.woff2 create mode 100644 docs/static/fonts/inter/Inter-Regular.woff create mode 100644 docs/static/fonts/inter/Inter-Regular.woff2 create mode 100644 docs/static/fonts/inter/Inter-SemiBold.woff create mode 100644 docs/static/fonts/inter/Inter-SemiBold.woff2 create mode 100644 docs/static/fonts/inter/Inter-SemiBoldItalic.woff create mode 100644 docs/static/fonts/inter/Inter-SemiBoldItalic.woff2 create mode 100644 docs/static/fonts/inter/Inter-Thin.woff create mode 100644 docs/static/fonts/inter/Inter-Thin.woff2 create mode 100644 docs/static/fonts/inter/Inter-ThinItalic.woff create mode 100644 docs/static/fonts/inter/Inter-ThinItalic.woff2 create mode 100644 docs/static/fonts/inter/Inter-italic.var.woff2 create mode 100644 docs/static/fonts/inter/Inter-roman.var.woff2 create mode 100644 docs/static/fonts/intervar/Inter.var.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-Bold.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-BoldItalic.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraBold.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraBoldItalic.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraLight.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraLightItalic.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-Italic.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-Light.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-LightItalic.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-Medium.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-MediumItalic.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-Regular.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-SemiBold.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-SemiBoldItalic.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-Thin.woff2 create mode 100644 docs/static/fonts/jetbrainsmono/JetBrainsMono-ThinItalic.woff2 create mode 100644 docs/static/img/IBC-go-cover.svg create mode 100644 docs/static/img/black-ibc-logo-400x400.svg create mode 100644 docs/static/img/black-ibc-logo.svg create mode 100644 docs/static/img/black-large-ibc-logo.svg create mode 100644 docs/static/img/cosmos-logo-bw.svg create mode 100644 docs/static/img/ibc-go-docs-social-card.png create mode 100644 docs/static/img/ico-chevron.svg create mode 100644 docs/static/img/icons/hi-coffee-icon.svg create mode 100644 docs/static/img/icons/hi-info-icon.svg create mode 100644 docs/static/img/icons/hi-note-icon.svg create mode 100644 docs/static/img/icons/hi-prerequisite-icon.svg create mode 100644 docs/static/img/icons/hi-reading-icon.svg create mode 100644 docs/static/img/icons/hi-star-icon.svg create mode 100644 docs/static/img/icons/hi-target-icon.svg create mode 100644 docs/static/img/icons/hi-tip-icon.svg create mode 100644 docs/static/img/icons/hi-warn-icon.svg create mode 100644 docs/static/img/spirograph-white.svg create mode 100644 docs/static/img/white-cosmos-icon.svg create mode 100644 docs/static/img/white-ibc-logo-400x400.svg create mode 100644 docs/static/img/white-ibc-logo.svg create mode 100644 docs/static/img/white-large-ibc-logo.svg create mode 100644 docs/tailwind.config.js create mode 100644 docs/versioned_docs/version-v10.1.x/00-intro.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/02-integration.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/00-ibcv2apps.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/01-apps.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/02-ibcmodule.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/03-bindports.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/04-keeper.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/05-packets_acks.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/06-routing.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/images/packet_flow.png create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/03-apps/images/packet_flow_v2.png create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/04-middleware/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/04-middleware/02-develop.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/04-middleware/02-developIBCv2.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/04-middleware/03-integration.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/04-middleware/images/middleware-stack.png create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/05-upgrades/00-intro.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/05-upgrades/01-quick-guide.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/05-upgrades/02-developer-guide.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/05-upgrades/03-genesis-restart.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/05-upgrades/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/07-relayer.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/08-best-practices.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/09-permissioning.md create mode 100644 docs/versioned_docs/version-v10.1.x/01-ibc/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/02-state.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/03-state-transitions.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/04-messages.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/05-events.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/06-metrics.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/07-params.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/08-authorizations.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/09-client.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/10-IBCv2-transfer.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/images/forwarding-3-chains-dark.png create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/01-transfer/images/forwarding-3-chains-light.png create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/02-development.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/03-auth-modules.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/04-integration.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/05-messages.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/06-parameters.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/07-tx-encoding.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/08-client.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/09-active-channels.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/10-legacy/02-integration.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/10-legacy/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/10-legacy/images/ica-pre-v6.png create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/02-interchain-accounts/images/ica-v6.png create mode 100644 docs/versioned_docs/version-v10.1.x/02-apps/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/02-light-client-module.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/03-client-state.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/04-consensus-state.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/05-updates-and-misbehaviour.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/06-upgrades.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/07-proofs.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/08-proposals.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/09-setup.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/01-developer-guide/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/02-localhost/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/02-localhost/02-integration.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/02-localhost/03-client-state.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/02-localhost/04-connection.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/02-localhost/05-state-verification.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/02-localhost/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/03-solomachine/01-solomachine.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/03-solomachine/02-concepts.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/03-solomachine/03-state.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/03-solomachine/04-state_transitions.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/03-solomachine/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/02-concepts.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/03-integration.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/04-messages.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/05-governance.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/06-events.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/07-contracts.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/08-client.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/09-migrations.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/04-wasm/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/05-tendermint/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/05-tendermint/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/06-proposals.md create mode 100644 docs/versioned_docs/version-v10.1.x/03-light-clients/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/01-overview.md create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/02-integration.md create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/03-interfaces.md create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/04-events.md create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/05-end-users.md create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/06-gas.md create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/07-callbacks-IBCv2.md create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/images/callbackflow.svg create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/01-callbacks/images/ics4-callbackflow.svg create mode 100644 docs/versioned_docs/version-v10.1.x/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/01-support-denoms-with-slashes.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/02-sdk-to-v1.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/03-v1-to-v2.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/04-v2-to-v3.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/05-v3-to-v4.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/06-v4-to-v5.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/07-v5-to-v6.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/08-v6-to-v7.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/09-v7-to-v7_1.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/10-v7_2-to-v7_3.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/11-v7-to-v8.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/12-v8-to-v8_1.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/13-v8_1-to-v10.md create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/_category_.json create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/images/auth-module-decision-tree.png create mode 100644 docs/versioned_docs/version-v10.1.x/05-migrations/migration.template.md create mode 100644 docs/versioned_docs/version-v10.1.x/images/ibcoverview-dark.svg create mode 100644 docs/versioned_docs/version-v10.1.x/images/ibcoverview-light.svg create mode 100644 docs/versioned_docs/version-v4.6.x/00-intro.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/01-overview.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/02-integration.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/03-apps/01-apps.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/03-apps/02-ibcmodule.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/03-apps/03-bindports.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/03-apps/04-keeper.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/03-apps/05-packets_acks.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/03-apps/06-routing.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/03-apps/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/03-apps/images/packet_flow.png create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/04-middleware/01-develop.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/04-middleware/02-integration.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/05-upgrades/00-intro.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/05-upgrades/01-quick-guide.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/05-upgrades/02-developer-guide.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/05-upgrades/03-genesis-restart.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/05-upgrades/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/06-proposals.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/07-relayer.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/08-proto-docs.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/09-roadmap.md create mode 100644 docs/versioned_docs/version-v4.6.x/01-ibc/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/01-transfer/01-overview.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/01-transfer/02-state.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/01-transfer/03-state-transitions.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/01-transfer/04-messages.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/01-transfer/05-events.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/01-transfer/06-metrics.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/01-transfer/07-params.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/01-transfer/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/02-interchain-accounts/01-overview.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/02-interchain-accounts/02-auth-modules.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/02-interchain-accounts/03-active-channels.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/02-interchain-accounts/04-integration.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/02-interchain-accounts/05-parameters.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/02-interchain-accounts/06-transactions.md create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/02-interchain-accounts/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/02-interchain-accounts/images/send-interchain-tx.png create mode 100644 docs/versioned_docs/version-v4.6.x/02-apps/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/01-overview.md create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/02-integration.md create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/03-msgs.md create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/04-fee-distribution.md create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/05-events.md create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/06-end-users.md create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/images/feeflow.png create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/images/msgpaypacket.png create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/01-ics29-fee/images/paypacketfeeasync.png create mode 100644 docs/versioned_docs/version-v4.6.x/03-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v4.6.x/04-migrations/01-support-denoms-with-slashes.md create mode 100644 docs/versioned_docs/version-v4.6.x/04-migrations/02-sdk-to-v1.md create mode 100644 docs/versioned_docs/version-v4.6.x/04-migrations/03-v1-to-v2.md create mode 100644 docs/versioned_docs/version-v4.6.x/04-migrations/04-v2-to-v3.md create mode 100644 docs/versioned_docs/version-v4.6.x/04-migrations/05-v3-to-v4.md create mode 100644 docs/versioned_docs/version-v4.6.x/04-migrations/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/00-intro.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/01-overview.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/02-integration.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/03-apps/01-apps.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/03-apps/02-ibcmodule.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/03-apps/03-bindports.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/03-apps/04-keeper.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/03-apps/05-packets_acks.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/03-apps/06-routing.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/03-apps/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/03-apps/images/packet_flow.png create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/04-middleware/01-develop.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/04-middleware/02-integration.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/05-upgrades/00-intro.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/05-upgrades/01-quick-guide.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/05-upgrades/02-developer-guide.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/05-upgrades/03-genesis-restart.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/05-upgrades/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/06-proposals.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/07-relayer.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/08-proto-docs.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/09-roadmap.md create mode 100644 docs/versioned_docs/version-v5.4.x/01-ibc/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/01-transfer/01-overview.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/01-transfer/02-state.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/01-transfer/03-state-transitions.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/01-transfer/04-messages.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/01-transfer/05-events.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/01-transfer/06-metrics.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/01-transfer/07-params.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/01-transfer/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/02-interchain-accounts/01-overview.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/02-interchain-accounts/02-auth-modules.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/02-interchain-accounts/03-active-channels.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/02-interchain-accounts/04-integration.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/02-interchain-accounts/05-parameters.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/02-interchain-accounts/06-transactions.md create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/02-interchain-accounts/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/02-interchain-accounts/images/send-interchain-tx.png create mode 100644 docs/versioned_docs/version-v5.4.x/02-apps/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/01-overview.md create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/02-integration.md create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/03-msgs.md create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/04-fee-distribution.md create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/05-events.md create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/06-end-users.md create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/images/feeflow.png create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/images/msgpaypacket.png create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/01-ics29-fee/images/paypacketfeeasync.png create mode 100644 docs/versioned_docs/version-v5.4.x/03-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v5.4.x/04-migrations/01-support-denoms-with-slashes.md create mode 100644 docs/versioned_docs/version-v5.4.x/04-migrations/02-sdk-to-v1.md create mode 100644 docs/versioned_docs/version-v5.4.x/04-migrations/03-v1-to-v2.md create mode 100644 docs/versioned_docs/version-v5.4.x/04-migrations/04-v2-to-v3.md create mode 100644 docs/versioned_docs/version-v5.4.x/04-migrations/05-v3-to-v4.md create mode 100644 docs/versioned_docs/version-v5.4.x/04-migrations/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/00-intro.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/01-overview.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/02-integration.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/03-apps/01-apps.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/03-apps/02-ibcmodule.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/03-apps/03-bindports.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/03-apps/04-keeper.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/03-apps/05-packets_acks.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/03-apps/06-routing.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/03-apps/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/03-apps/images/packet_flow.png create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/04-middleware/01-develop.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/04-middleware/02-integration.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/05-upgrades/00-intro.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/05-upgrades/01-quick-guide.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/05-upgrades/02-developer-guide.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/05-upgrades/03-genesis-restart.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/05-upgrades/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/06-proposals.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/07-relayer.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/08-proto-docs.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/09-roadmap.md create mode 100644 docs/versioned_docs/version-v6.3.x/01-ibc/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/01-overview.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/02-state.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/03-state-transitions.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/04-messages.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/05-events.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/06-metrics.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/07-params.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/08-authorizations.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/01-transfer/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/01-overview.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/02-development.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/03-auth-modules.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/04-integration.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/05-messages.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/06-parameters.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/07-client.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/08-active-channels.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/09-legacy/01-auth-modules.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/09-legacy/02-integration.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/09-legacy/03-keeper-api.md create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/09-legacy/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/09-legacy/images/ica-pre-v6.png create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/02-interchain-accounts/images/ica-v6.png create mode 100644 docs/versioned_docs/version-v6.3.x/02-apps/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/01-overview.md create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/02-integration.md create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/03-msgs.md create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/04-fee-distribution.md create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/05-events.md create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/06-end-users.md create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/images/feeflow.png create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/images/msgpaypacket.png create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/01-ics29-fee/images/paypacketfeeasync.png create mode 100644 docs/versioned_docs/version-v6.3.x/03-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/01-support-denoms-with-slashes.md create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/02-sdk-to-v1.md create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/03-v1-to-v2.md create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/04-v2-to-v3.md create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/05-v3-to-v4.md create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/06-v4-to-v5.md create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/07-v5-to-v6.md create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/_category_.json create mode 100644 docs/versioned_docs/version-v6.3.x/04-migrations/images/auth-module-decision-tree.png create mode 100644 docs/versioned_docs/version-v7.8.x/00-intro.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/01-overview.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/02-integration.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/03-apps/01-apps.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/03-apps/02-ibcmodule.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/03-apps/03-bindports.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/03-apps/04-keeper.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/03-apps/05-packets_acks.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/03-apps/06-routing.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/03-apps/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/03-apps/images/packet_flow.png create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/04-middleware/01-develop.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/04-middleware/02-integration.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/05-upgrades/00-intro.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/05-upgrades/01-quick-guide.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/05-upgrades/02-developer-guide.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/05-upgrades/03-genesis-restart.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/05-upgrades/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/06-proposals.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/07-relayer.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/08-proto-docs.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/09-roadmap.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/10-troubleshooting.md create mode 100644 docs/versioned_docs/version-v7.8.x/01-ibc/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/01-overview.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/02-state.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/03-state-transitions.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/04-messages.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/05-events.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/06-metrics.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/07-params.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/08-authorizations.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/09-client.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/01-transfer/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/01-overview.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/02-development.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/03-auth-modules.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/04-integration.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/05-messages.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/06-parameters.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/07-tx-encoding.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/08-client.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/09-active-channels.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/10-legacy/02-integration.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/10-legacy/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/10-legacy/images/ica-pre-v6.png create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/02-interchain-accounts/images/ica-v6.png create mode 100644 docs/versioned_docs/version-v7.8.x/02-apps/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/01-overview.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/02-client-state.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/03-consensus-state.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/04-updates-and-misbehaviour.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/05-upgrades.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/06-proofs.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/07-proposals.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/08-genesis.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/09-setup.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/01-developer-guide/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/02-solomachine/01-solomachine.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/02-solomachine/02-concepts.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/02-solomachine/03-state.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/02-solomachine/04-state_transitions.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/02-solomachine/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/03-localhost/01-overview.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/03-localhost/02-integration.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/03-localhost/03-client-state.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/03-localhost/04-connection.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/03-localhost/05-state-verification.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/03-localhost/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/01-overview.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/02-concepts.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/03-integration.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/04-messages.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/05-governance.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/06-events.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/07-contracts.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/08-client.md create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/04-wasm/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/03-light-clients/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/01-overview.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/02-integration.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/03-msgs.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/04-fee-distribution.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/05-events.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/06-end-users.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/images/feeflow.png create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/images/msgpaypacket.png create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/01-ics29-fee/images/paypacketfeeasync.png create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/01-overview.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/02-integration.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/03-interfaces.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/04-events.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/05-end-users.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/06-gas.md create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/images/callbackflow.svg create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/02-callbacks/images/ics4-callbackflow.svg create mode 100644 docs/versioned_docs/version-v7.8.x/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/01-support-denoms-with-slashes.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/02-sdk-to-v1.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/03-v1-to-v2.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/04-v2-to-v3.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/05-v3-to-v4.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/06-v4-to-v5.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/07-v5-to-v6.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/08-v6-to-v7.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/09-v7-to-v7_1.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/10-v7_2-to-v7_3.md create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/_category_.json create mode 100644 docs/versioned_docs/version-v7.8.x/05-migrations/images/auth-module-decision-tree.png create mode 100644 docs/versioned_docs/version-v8.5.x/00-intro.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/02-integration.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/03-apps/01-apps.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/03-apps/02-ibcmodule.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/03-apps/03-bindports.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/03-apps/04-keeper.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/03-apps/05-packets_acks.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/03-apps/06-routing.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/03-apps/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/03-apps/images/packet_flow.png create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/04-middleware/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/04-middleware/02-develop.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/04-middleware/03-integration.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/04-middleware/images/middleware-stack.png create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/05-upgrades/00-intro.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/05-upgrades/01-quick-guide.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/05-upgrades/02-developer-guide.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/05-upgrades/03-genesis-restart.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/05-upgrades/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/06-channel-upgrades.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/07-proposals.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/08-relayer.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/09-proto-docs.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/10-roadmap.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/11-troubleshooting.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/12-capability-module.md create mode 100644 docs/versioned_docs/version-v8.5.x/01-ibc/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/02-state.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/03-state-transitions.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/04-messages.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/05-events.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/06-metrics.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/07-params.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/08-authorizations.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/09-client.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/01-transfer/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/02-development.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/03-auth-modules.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/04-integration.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/05-messages.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/06-parameters.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/07-tx-encoding.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/08-client.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/09-active-channels.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/10-legacy/02-integration.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/10-legacy/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/10-legacy/images/ica-pre-v6.png create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/02-interchain-accounts/images/ica-v6.png create mode 100644 docs/versioned_docs/version-v8.5.x/02-apps/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/02-client-state.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/03-consensus-state.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/04-updates-and-misbehaviour.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/05-upgrades.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/06-proofs.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/07-proposals.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/08-genesis.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/09-setup.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/01-developer-guide/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/02-localhost/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/02-localhost/02-integration.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/02-localhost/03-client-state.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/02-localhost/04-connection.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/02-localhost/05-state-verification.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/02-localhost/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/03-solomachine/01-solomachine.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/03-solomachine/02-concepts.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/03-solomachine/03-state.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/03-solomachine/04-state_transitions.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/03-solomachine/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/02-concepts.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/03-integration.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/04-messages.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/05-governance.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/06-events.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/07-contracts.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/08-client.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/09-migrations.md create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/04-wasm/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/03-light-clients/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/02-integration.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/03-msgs.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/04-fee-distribution.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/05-events.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/06-end-users.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/images/feeflow.png create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/images/msgpaypacket.png create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/01-ics29-fee/images/paypacketfeeasync.png create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/01-overview.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/02-integration.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/03-interfaces.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/04-events.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/05-end-users.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/06-gas.md create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/images/callbackflow.svg create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/02-callbacks/images/ics4-callbackflow.svg create mode 100644 docs/versioned_docs/version-v8.5.x/04-middleware/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/01-support-denoms-with-slashes.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/02-sdk-to-v1.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/03-v1-to-v2.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/04-v2-to-v3.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/05-v3-to-v4.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/06-v4-to-v5.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/07-v5-to-v6.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/08-v6-to-v7.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/09-v7-to-v7_1.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/10-v7_2-to-v7_3.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/11-v7-to-v8.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/12-v8-to-v8_1.md create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/_category_.json create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/images/auth-module-decision-tree.png create mode 100644 docs/versioned_docs/version-v8.5.x/05-migrations/migration.template.md create mode 100644 docs/versioned_docs/version-v8.5.x/images/ibcoverview-dark.svg create mode 100644 docs/versioned_docs/version-v8.5.x/images/ibcoverview-light.svg create mode 100644 docs/versioned_sidebars/version-v10.1.x-sidebars.json create mode 100644 docs/versioned_sidebars/version-v4.6.x-sidebars.json create mode 100644 docs/versioned_sidebars/version-v5.4.x-sidebars.json create mode 100644 docs/versioned_sidebars/version-v6.3.x-sidebars.json create mode 100644 docs/versioned_sidebars/version-v7.8.x-sidebars.json create mode 100644 docs/versioned_sidebars/version-v8.5.x-sidebars.json create mode 100644 docs/versions.json create mode 100644 e2e/Makefile create mode 100644 e2e/README.md create mode 100644 e2e/ci-e2e-config.yaml create mode 100644 e2e/dockerutil/dockerutil.go create mode 100644 e2e/go.mod create mode 100644 e2e/go.sum create mode 100644 e2e/internal/directories/directories.go create mode 100644 e2e/relayer/relayer.go create mode 100644 e2e/sample.config.extended.yaml create mode 100644 e2e/sample.config.yaml create mode 100755 e2e/scripts/init.sh create mode 100755 e2e/scripts/run-e2e.sh create mode 100644 e2e/semverutil/semver.go create mode 100644 e2e/semverutil/semver_test.go create mode 100644 e2e/tests/core/02-client/client_test.go create mode 100644 e2e/tests/core/03-connection/connection_test.go create mode 100644 e2e/tests/interchain_accounts/base_test.go create mode 100644 e2e/tests/interchain_accounts/gov_test.go create mode 100644 e2e/tests/interchain_accounts/groups_test.go create mode 100644 e2e/tests/interchain_accounts/localhost_test.go create mode 100644 e2e/tests/interchain_accounts/params_test.go create mode 100644 e2e/tests/interchain_accounts/query_test.go create mode 100644 e2e/tests/transfer/authz_test.go create mode 100644 e2e/tests/transfer/base_test.go create mode 100644 e2e/tests/transfer/localhost_test.go create mode 100644 e2e/tests/transfer/send_enabled_test.go create mode 100644 e2e/tests/transfer/send_receive_test.go create mode 100644 e2e/tests/upgrades/genesis_test.go create mode 100644 e2e/tests/upgrades/upgrade_test.go create mode 100644 e2e/testsuite/codec.go create mode 100644 e2e/testsuite/diagnostics/diagnostics.go create mode 100644 e2e/testsuite/events.go create mode 100644 e2e/testsuite/query/grpc_query.go create mode 100644 e2e/testsuite/query/queries.go create mode 100644 e2e/testsuite/sanitize/messages.go create mode 100644 e2e/testsuite/testconfig.go create mode 100644 e2e/testsuite/testsuite.go create mode 100644 e2e/testsuite/tx.go create mode 100644 e2e/testvalues/values.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 go.work.example create mode 100644 internal/logging/logging.go create mode 100644 internal/validate/validate.go create mode 100644 internal/validate/validate_test.go create mode 100644 maintainership.png create mode 100644 modules/apps/27-interchain-accounts/client/cli/cli.go create mode 100644 modules/apps/27-interchain-accounts/controller/client/cli/cli.go create mode 100644 modules/apps/27-interchain-accounts/controller/client/cli/query.go create mode 100644 modules/apps/27-interchain-accounts/controller/client/cli/tx.go create mode 100644 modules/apps/27-interchain-accounts/controller/ibc_middleware.go create mode 100644 modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/account.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/account_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/events.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/export_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/genesis.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/grpc_query.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/handshake.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/keeper.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/migrations.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/msg_server.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/relay.go create mode 100644 modules/apps/27-interchain-accounts/controller/keeper/relay_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/codec.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/codec_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/controller.pb.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/errors.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/keys.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/msgs.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/msgs_test.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/params.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/params_legacy.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/query.pb.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/query.pb.gw.go create mode 100644 modules/apps/27-interchain-accounts/controller/types/tx.pb.go create mode 100644 modules/apps/27-interchain-accounts/doc.go create mode 100644 modules/apps/27-interchain-accounts/genesis/types/genesis.go create mode 100644 modules/apps/27-interchain-accounts/genesis/types/genesis.pb.go create mode 100644 modules/apps/27-interchain-accounts/genesis/types/genesis_test.go create mode 100644 modules/apps/27-interchain-accounts/host/client/cli/cli.go create mode 100644 modules/apps/27-interchain-accounts/host/client/cli/query.go create mode 100644 modules/apps/27-interchain-accounts/host/client/cli/tx.go create mode 100644 modules/apps/27-interchain-accounts/host/client/cli/tx_test.go create mode 100644 modules/apps/27-interchain-accounts/host/ibc_module.go create mode 100644 modules/apps/27-interchain-accounts/host/ibc_module_test.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/account.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/events.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/export_test.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/genesis.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/genesis_test.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/grpc_query.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/grpc_query_test.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/handshake.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/handshake_test.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/keeper.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/keeper_test.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/migrations.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/migrations_test.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/msg_server.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/msg_server_test.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/relay.go create mode 100644 modules/apps/27-interchain-accounts/host/keeper/relay_test.go create mode 100644 modules/apps/27-interchain-accounts/host/types/codec.go create mode 100644 modules/apps/27-interchain-accounts/host/types/codec_test.go create mode 100644 modules/apps/27-interchain-accounts/host/types/errors.go create mode 100644 modules/apps/27-interchain-accounts/host/types/host.pb.go create mode 100644 modules/apps/27-interchain-accounts/host/types/keys.go create mode 100644 modules/apps/27-interchain-accounts/host/types/msgs.go create mode 100644 modules/apps/27-interchain-accounts/host/types/msgs_test.go create mode 100644 modules/apps/27-interchain-accounts/host/types/params.go create mode 100644 modules/apps/27-interchain-accounts/host/types/params_legacy.go create mode 100644 modules/apps/27-interchain-accounts/host/types/params_test.go create mode 100644 modules/apps/27-interchain-accounts/host/types/query.pb.go create mode 100644 modules/apps/27-interchain-accounts/host/types/query.pb.gw.go create mode 100644 modules/apps/27-interchain-accounts/host/types/tx.pb.go create mode 100644 modules/apps/27-interchain-accounts/module.go create mode 100644 modules/apps/27-interchain-accounts/module_test.go create mode 100644 modules/apps/27-interchain-accounts/simulation/decoder.go create mode 100644 modules/apps/27-interchain-accounts/simulation/decoder_test.go create mode 100644 modules/apps/27-interchain-accounts/simulation/genesis.go create mode 100644 modules/apps/27-interchain-accounts/simulation/genesis_test.go create mode 100644 modules/apps/27-interchain-accounts/simulation/proposals.go create mode 100644 modules/apps/27-interchain-accounts/simulation/proposals_test.go create mode 100644 modules/apps/27-interchain-accounts/types/account.go create mode 100644 modules/apps/27-interchain-accounts/types/account.pb.go create mode 100644 modules/apps/27-interchain-accounts/types/account_test.go create mode 100644 modules/apps/27-interchain-accounts/types/codec.go create mode 100644 modules/apps/27-interchain-accounts/types/codec_test.go create mode 100644 modules/apps/27-interchain-accounts/types/errors.go create mode 100644 modules/apps/27-interchain-accounts/types/events.go create mode 100644 modules/apps/27-interchain-accounts/types/expected_keepers.go create mode 100644 modules/apps/27-interchain-accounts/types/keys.go create mode 100644 modules/apps/27-interchain-accounts/types/keys_test.go create mode 100644 modules/apps/27-interchain-accounts/types/metadata.go create mode 100644 modules/apps/27-interchain-accounts/types/metadata.pb.go create mode 100644 modules/apps/27-interchain-accounts/types/metadata_test.go create mode 100644 modules/apps/27-interchain-accounts/types/packet.go create mode 100644 modules/apps/27-interchain-accounts/types/packet.pb.go create mode 100644 modules/apps/27-interchain-accounts/types/packet_test.go create mode 100644 modules/apps/27-interchain-accounts/types/port.go create mode 100644 modules/apps/27-interchain-accounts/types/port_test.go create mode 100644 modules/apps/27-interchain-accounts/types/router.go create mode 100644 modules/apps/callbacks/CHANGELOG.md create mode 100644 modules/apps/callbacks/README.md create mode 100644 modules/apps/callbacks/callbacks_test.go create mode 100644 modules/apps/callbacks/ibc_middleware.go create mode 100644 modules/apps/callbacks/ibc_middleware_test.go create mode 100644 modules/apps/callbacks/ica_test.go create mode 100644 modules/apps/callbacks/internal/process.go create mode 100644 modules/apps/callbacks/replay_test.go create mode 100644 modules/apps/callbacks/testing/simapp/README.md create mode 100644 modules/apps/callbacks/testing/simapp/ante_handler.go create mode 100644 modules/apps/callbacks/testing/simapp/app.go create mode 100644 modules/apps/callbacks/testing/simapp/contract_keeper.go create mode 100644 modules/apps/callbacks/testing/simapp/encoding.go create mode 100644 modules/apps/callbacks/testing/simapp/export.go create mode 100644 modules/apps/callbacks/testing/simapp/genesis.go create mode 100644 modules/apps/callbacks/testing/simapp/genesis_account.go create mode 100644 modules/apps/callbacks/testing/simapp/params/amino.go create mode 100644 modules/apps/callbacks/testing/simapp/params/doc.go create mode 100644 modules/apps/callbacks/testing/simapp/params/encoding.go create mode 100644 modules/apps/callbacks/testing/simapp/params/proto.go create mode 100644 modules/apps/callbacks/transfer_test.go create mode 100644 modules/apps/callbacks/types/callbacks.go create mode 100644 modules/apps/callbacks/types/callbacks_test.go create mode 100644 modules/apps/callbacks/types/errors.go create mode 100644 modules/apps/callbacks/types/events.go create mode 100644 modules/apps/callbacks/types/events_test.go create mode 100644 modules/apps/callbacks/types/expected_keepers.go create mode 100644 modules/apps/callbacks/types/export_test.go create mode 100644 modules/apps/callbacks/types/keys.go create mode 100644 modules/apps/callbacks/types/types_test.go create mode 100644 modules/apps/callbacks/v2/ibc_middleware.go create mode 100644 modules/apps/callbacks/v2/ibc_middleware_test.go create mode 100644 modules/apps/callbacks/v2/v2_test.go create mode 100644 modules/apps/transfer/client/cli/cli.go create mode 100644 modules/apps/transfer/client/cli/query.go create mode 100644 modules/apps/transfer/client/cli/tx.go create mode 100644 modules/apps/transfer/doc.go create mode 100644 modules/apps/transfer/ibc_module.go create mode 100644 modules/apps/transfer/ibc_module_test.go create mode 100644 modules/apps/transfer/internal/events/events.go create mode 100644 modules/apps/transfer/internal/telemetry/telemetry.go create mode 100644 modules/apps/transfer/internal/types/denomtrace.pb.go create mode 100644 modules/apps/transfer/internal/types/legacy_denomtrace.go create mode 100644 modules/apps/transfer/internal/types/legacy_denomtrace_test.go create mode 100644 modules/apps/transfer/keeper/MBT_README.md create mode 100644 modules/apps/transfer/keeper/export_test.go create mode 100644 modules/apps/transfer/keeper/genesis.go create mode 100644 modules/apps/transfer/keeper/genesis_test.go create mode 100644 modules/apps/transfer/keeper/grpc_query.go create mode 100644 modules/apps/transfer/keeper/grpc_query_test.go create mode 100644 modules/apps/transfer/keeper/keeper.go create mode 100644 modules/apps/transfer/keeper/keeper_test.go create mode 100644 modules/apps/transfer/keeper/mbt_relay_test.go create mode 100644 modules/apps/transfer/keeper/migrations.go create mode 100644 modules/apps/transfer/keeper/migrations_test.go create mode 100644 modules/apps/transfer/keeper/model_based_tests/Test5Packets.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/Test5Packets.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/Test5PacketsAllDifferentPass.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/Test5PacketsAllDifferentPass.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvAcknowledgementErrorFail.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvAcknowledgementErrorFail.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvAcknowledgementErrorPass.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvAcknowledgementErrorPass.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvAcknowledgementResultFail.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvAcknowledgementResultFail.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvAcknowledgementResultPass.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvAcknowledgementResultPass.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvPacketFail.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvPacketFail.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvPacketPass.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnRecvPacketPass.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnTimeoutFail.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnTimeoutFail.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnTimeoutPass.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestOnTimeoutPass.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestSendTransferFail.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestSendTransferFail.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestSendTransferPass.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestSendTransferPass.tla create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestUnescrowTokens.json create mode 100644 modules/apps/transfer/keeper/model_based_tests/TestUnescrowTokens.tla create mode 100644 modules/apps/transfer/keeper/msg_server.go create mode 100644 modules/apps/transfer/keeper/msg_server_test.go create mode 100644 modules/apps/transfer/keeper/relay.go create mode 100644 modules/apps/transfer/keeper/relay_model/account.tla create mode 100644 modules/apps/transfer/keeper/relay_model/account_record.tla create mode 100644 modules/apps/transfer/keeper/relay_model/apalache-to-relay-test.json create mode 100644 modules/apps/transfer/keeper/relay_model/apalache-to-relay-test2.json create mode 100644 modules/apps/transfer/keeper/relay_model/denom.tla create mode 100644 modules/apps/transfer/keeper/relay_model/denom_record.tla create mode 100644 modules/apps/transfer/keeper/relay_model/denom_record2.tla create mode 100644 modules/apps/transfer/keeper/relay_model/denom_sequence.tla create mode 100644 modules/apps/transfer/keeper/relay_model/identifiers.tla create mode 100644 modules/apps/transfer/keeper/relay_model/relay.tla create mode 100644 modules/apps/transfer/keeper/relay_model/relay_tests.tla create mode 100644 modules/apps/transfer/keeper/relay_test.go create mode 100644 modules/apps/transfer/module.go create mode 100644 modules/apps/transfer/simulation/decoder.go create mode 100644 modules/apps/transfer/simulation/decoder_test.go create mode 100644 modules/apps/transfer/simulation/genesis.go create mode 100644 modules/apps/transfer/simulation/genesis_test.go create mode 100644 modules/apps/transfer/simulation/proposals.go create mode 100644 modules/apps/transfer/simulation/proposals_test.go create mode 100644 modules/apps/transfer/transfer_test.go create mode 100644 modules/apps/transfer/types/authz.pb.go create mode 100644 modules/apps/transfer/types/codec.go create mode 100644 modules/apps/transfer/types/codec_test.go create mode 100644 modules/apps/transfer/types/denom.go create mode 100644 modules/apps/transfer/types/denom_test.go create mode 100644 modules/apps/transfer/types/deprecated.go create mode 100644 modules/apps/transfer/types/encoding.go create mode 100644 modules/apps/transfer/types/errors.go create mode 100644 modules/apps/transfer/types/events.go create mode 100644 modules/apps/transfer/types/expected_keepers.go create mode 100644 modules/apps/transfer/types/export_test.go create mode 100644 modules/apps/transfer/types/genesis.go create mode 100644 modules/apps/transfer/types/genesis.pb.go create mode 100644 modules/apps/transfer/types/genesis_test.go create mode 100644 modules/apps/transfer/types/hop.go create mode 100644 modules/apps/transfer/types/hop_test.go create mode 100644 modules/apps/transfer/types/keys.go create mode 100644 modules/apps/transfer/types/keys_test.go create mode 100644 modules/apps/transfer/types/msgs.go create mode 100644 modules/apps/transfer/types/msgs_test.go create mode 100644 modules/apps/transfer/types/packet.go create mode 100644 modules/apps/transfer/types/packet.pb.go create mode 100644 modules/apps/transfer/types/packet_test.go create mode 100644 modules/apps/transfer/types/params.go create mode 100644 modules/apps/transfer/types/params_legacy.go create mode 100644 modules/apps/transfer/types/query.pb.go create mode 100644 modules/apps/transfer/types/query.pb.gw.go create mode 100644 modules/apps/transfer/types/solidity_abi.go create mode 100644 modules/apps/transfer/types/solidity_abi_test.go create mode 100644 modules/apps/transfer/types/token.go create mode 100644 modules/apps/transfer/types/token.pb.go create mode 100644 modules/apps/transfer/types/token_test.go create mode 100644 modules/apps/transfer/types/transfer.pb.go create mode 100644 modules/apps/transfer/types/transfer_authorization.go create mode 100644 modules/apps/transfer/types/transfer_authorization_test.go create mode 100644 modules/apps/transfer/types/tx.pb.go create mode 100644 modules/apps/transfer/types/types_test.go create mode 100644 modules/apps/transfer/v2/ibc_module.go create mode 100644 modules/apps/transfer/v2/ibc_module_test.go create mode 100644 modules/core/02-client/abci.go create mode 100644 modules/core/02-client/abci_test.go create mode 100644 modules/core/02-client/client/cli/cli.go create mode 100644 modules/core/02-client/client/cli/query.go create mode 100644 modules/core/02-client/client/cli/tx.go create mode 100644 modules/core/02-client/client/utils/utils.go create mode 100644 modules/core/02-client/doc.go create mode 100644 modules/core/02-client/genesis.go create mode 100644 modules/core/02-client/keeper/client.go create mode 100644 modules/core/02-client/keeper/client_test.go create mode 100644 modules/core/02-client/keeper/events.go create mode 100644 modules/core/02-client/keeper/events_test.go create mode 100644 modules/core/02-client/keeper/grpc_query.go create mode 100644 modules/core/02-client/keeper/grpc_query_test.go create mode 100644 modules/core/02-client/keeper/keeper.go create mode 100644 modules/core/02-client/keeper/keeper_test.go create mode 100644 modules/core/02-client/keeper/migrations.go create mode 100644 modules/core/02-client/keeper/migrations_test.go create mode 100644 modules/core/02-client/migrations/v7/expected_keepers.go create mode 100644 modules/core/02-client/migrations/v7/genesis.go create mode 100644 modules/core/02-client/migrations/v7/genesis_test.go create mode 100644 modules/core/02-client/migrations/v7/solomachine.go create mode 100644 modules/core/02-client/migrations/v7/solomachine.pb.go create mode 100644 modules/core/02-client/migrations/v7/store.go create mode 100644 modules/core/02-client/migrations/v7/store_test.go create mode 100644 modules/core/02-client/module.go create mode 100644 modules/core/02-client/simulation/decoder.go create mode 100644 modules/core/02-client/simulation/decoder_test.go create mode 100644 modules/core/02-client/simulation/genesis.go create mode 100644 modules/core/02-client/types/client.go create mode 100644 modules/core/02-client/types/client.pb.go create mode 100644 modules/core/02-client/types/client_test.go create mode 100644 modules/core/02-client/types/codec.go create mode 100644 modules/core/02-client/types/codec_test.go create mode 100644 modules/core/02-client/types/encoding.go create mode 100644 modules/core/02-client/types/encoding_test.go create mode 100644 modules/core/02-client/types/errors.go create mode 100644 modules/core/02-client/types/events.go create mode 100644 modules/core/02-client/types/expected_keepers.go create mode 100644 modules/core/02-client/types/genesis.go create mode 100644 modules/core/02-client/types/genesis.pb.go create mode 100644 modules/core/02-client/types/genesis_test.go create mode 100644 modules/core/02-client/types/height.go create mode 100644 modules/core/02-client/types/height_test.go create mode 100644 modules/core/02-client/types/keys.go create mode 100644 modules/core/02-client/types/keys_test.go create mode 100644 modules/core/02-client/types/legacy_proposal.go create mode 100644 modules/core/02-client/types/legacy_proposal_test.go create mode 100644 modules/core/02-client/types/legacy_upgrade_proposal.pb.go create mode 100644 modules/core/02-client/types/msgs.go create mode 100644 modules/core/02-client/types/msgs_test.go create mode 100644 modules/core/02-client/types/params.go create mode 100644 modules/core/02-client/types/params_legacy.go create mode 100644 modules/core/02-client/types/params_test.go create mode 100644 modules/core/02-client/types/query.go create mode 100644 modules/core/02-client/types/query.pb.go create mode 100644 modules/core/02-client/types/query.pb.gw.go create mode 100644 modules/core/02-client/types/router.go create mode 100644 modules/core/02-client/types/router_test.go create mode 100644 modules/core/02-client/types/store.go create mode 100644 modules/core/02-client/types/tx.pb.go create mode 100644 modules/core/02-client/v2/genesis.go create mode 100644 modules/core/02-client/v2/genesis_test.go create mode 100644 modules/core/02-client/v2/keeper/grpc_query.go create mode 100644 modules/core/02-client/v2/keeper/grpc_query_test.go create mode 100644 modules/core/02-client/v2/keeper/keeper.go create mode 100644 modules/core/02-client/v2/keeper/keeper_test.go create mode 100644 modules/core/02-client/v2/module.go create mode 100644 modules/core/02-client/v2/module_test.go create mode 100644 modules/core/02-client/v2/types/codec.go create mode 100644 modules/core/02-client/v2/types/config.go create mode 100644 modules/core/02-client/v2/types/config.pb.go create mode 100644 modules/core/02-client/v2/types/config_test.go create mode 100644 modules/core/02-client/v2/types/counterparty.go create mode 100644 modules/core/02-client/v2/types/counterparty.pb.go create mode 100644 modules/core/02-client/v2/types/errors.go create mode 100644 modules/core/02-client/v2/types/genesis.go create mode 100644 modules/core/02-client/v2/types/genesis.pb.go create mode 100644 modules/core/02-client/v2/types/genesis_test.go create mode 100644 modules/core/02-client/v2/types/keys.go create mode 100644 modules/core/02-client/v2/types/msgs.go create mode 100644 modules/core/02-client/v2/types/msgs_test.go create mode 100644 modules/core/02-client/v2/types/query.pb.go create mode 100644 modules/core/02-client/v2/types/query.pb.gw.go create mode 100644 modules/core/02-client/v2/types/tx.pb.go create mode 100644 modules/core/03-connection/client/cli/cli.go create mode 100644 modules/core/03-connection/client/cli/query.go create mode 100644 modules/core/03-connection/client/utils/utils.go create mode 100644 modules/core/03-connection/doc.go create mode 100644 modules/core/03-connection/genesis.go create mode 100644 modules/core/03-connection/keeper/events.go create mode 100644 modules/core/03-connection/keeper/events_test.go create mode 100644 modules/core/03-connection/keeper/grpc_query.go create mode 100644 modules/core/03-connection/keeper/grpc_query_test.go create mode 100644 modules/core/03-connection/keeper/handshake.go create mode 100644 modules/core/03-connection/keeper/handshake_test.go create mode 100644 modules/core/03-connection/keeper/keeper.go create mode 100644 modules/core/03-connection/keeper/keeper_test.go create mode 100644 modules/core/03-connection/keeper/migrations.go create mode 100644 modules/core/03-connection/keeper/migrations_test.go create mode 100644 modules/core/03-connection/keeper/verify.go create mode 100644 modules/core/03-connection/keeper/verify_test.go create mode 100644 modules/core/03-connection/migrations/v7/expected_keepers.go create mode 100644 modules/core/03-connection/migrations/v7/localhost.go create mode 100644 modules/core/03-connection/module.go create mode 100644 modules/core/03-connection/simulation/decoder.go create mode 100644 modules/core/03-connection/simulation/decoder_test.go create mode 100644 modules/core/03-connection/simulation/genesis.go create mode 100644 modules/core/03-connection/types/codec.go create mode 100644 modules/core/03-connection/types/codec_test.go create mode 100644 modules/core/03-connection/types/connection.go create mode 100644 modules/core/03-connection/types/connection.pb.go create mode 100644 modules/core/03-connection/types/connection_test.go create mode 100644 modules/core/03-connection/types/errors.go create mode 100644 modules/core/03-connection/types/events.go create mode 100644 modules/core/03-connection/types/expected_keepers.go create mode 100644 modules/core/03-connection/types/genesis.go create mode 100644 modules/core/03-connection/types/genesis.pb.go create mode 100644 modules/core/03-connection/types/genesis_test.go create mode 100644 modules/core/03-connection/types/keys.go create mode 100644 modules/core/03-connection/types/keys_test.go create mode 100644 modules/core/03-connection/types/msgs.go create mode 100644 modules/core/03-connection/types/msgs_test.go create mode 100644 modules/core/03-connection/types/params.go create mode 100644 modules/core/03-connection/types/params_legacy.go create mode 100644 modules/core/03-connection/types/params_test.go create mode 100644 modules/core/03-connection/types/query.go create mode 100644 modules/core/03-connection/types/query.pb.go create mode 100644 modules/core/03-connection/types/query.pb.gw.go create mode 100644 modules/core/03-connection/types/tx.pb.go create mode 100644 modules/core/03-connection/types/version.go create mode 100644 modules/core/03-connection/types/version_test.go create mode 100644 modules/core/04-channel/client/cli/cli.go create mode 100644 modules/core/04-channel/client/cli/query.go create mode 100644 modules/core/04-channel/client/utils/utils.go create mode 100644 modules/core/04-channel/doc.go create mode 100644 modules/core/04-channel/genesis.go create mode 100644 modules/core/04-channel/keeper/ante.go create mode 100644 modules/core/04-channel/keeper/ante_test.go create mode 100644 modules/core/04-channel/keeper/events.go create mode 100644 modules/core/04-channel/keeper/export_test.go create mode 100644 modules/core/04-channel/keeper/grpc_query.go create mode 100644 modules/core/04-channel/keeper/grpc_query_test.go create mode 100644 modules/core/04-channel/keeper/handshake.go create mode 100644 modules/core/04-channel/keeper/handshake_test.go create mode 100644 modules/core/04-channel/keeper/keeper.go create mode 100644 modules/core/04-channel/keeper/keeper_test.go create mode 100644 modules/core/04-channel/keeper/migrations.go create mode 100644 modules/core/04-channel/keeper/packet.go create mode 100644 modules/core/04-channel/keeper/packet_test.go create mode 100644 modules/core/04-channel/keeper/timeout.go create mode 100644 modules/core/04-channel/keeper/timeout_test.go create mode 100644 modules/core/04-channel/migrations/v10/channel.pb.go create mode 100644 modules/core/04-channel/migrations/v10/expected_keepers.go create mode 100644 modules/core/04-channel/migrations/v10/store.go create mode 100644 modules/core/04-channel/migrations/v10/store_test.go create mode 100644 modules/core/04-channel/migrations/v10/upgrade.pb.go create mode 100644 modules/core/04-channel/module.go create mode 100644 modules/core/04-channel/simulation/decoder.go create mode 100644 modules/core/04-channel/simulation/decoder_test.go create mode 100644 modules/core/04-channel/simulation/genesis.go create mode 100644 modules/core/04-channel/types/acknowledgement.go create mode 100644 modules/core/04-channel/types/acknowledgement_test.go create mode 100644 modules/core/04-channel/types/channel.go create mode 100644 modules/core/04-channel/types/channel.pb.go create mode 100644 modules/core/04-channel/types/channel_test.go create mode 100644 modules/core/04-channel/types/codec.go create mode 100644 modules/core/04-channel/types/codec_test.go create mode 100644 modules/core/04-channel/types/errors.go create mode 100644 modules/core/04-channel/types/events.go create mode 100644 modules/core/04-channel/types/expected_keepers.go create mode 100644 modules/core/04-channel/types/genesis.go create mode 100644 modules/core/04-channel/types/genesis.pb.go create mode 100644 modules/core/04-channel/types/genesis_test.go create mode 100644 modules/core/04-channel/types/keys.go create mode 100644 modules/core/04-channel/types/keys_test.go create mode 100644 modules/core/04-channel/types/msgs.go create mode 100644 modules/core/04-channel/types/msgs_test.go create mode 100644 modules/core/04-channel/types/packet.go create mode 100644 modules/core/04-channel/types/packet_test.go create mode 100644 modules/core/04-channel/types/query.go create mode 100644 modules/core/04-channel/types/query.pb.go create mode 100644 modules/core/04-channel/types/query.pb.gw.go create mode 100644 modules/core/04-channel/types/timeout.go create mode 100644 modules/core/04-channel/types/timeout_test.go create mode 100644 modules/core/04-channel/types/tx.pb.go create mode 100644 modules/core/04-channel/v2/client/cli/abci.go create mode 100644 modules/core/04-channel/v2/client/cli/cli.go create mode 100644 modules/core/04-channel/v2/client/cli/query.go create mode 100644 modules/core/04-channel/v2/genesis.go create mode 100644 modules/core/04-channel/v2/genesis_test.go create mode 100644 modules/core/04-channel/v2/keeper/events.go create mode 100644 modules/core/04-channel/v2/keeper/export_test.go create mode 100644 modules/core/04-channel/v2/keeper/grpc_query.go create mode 100644 modules/core/04-channel/v2/keeper/grpc_query_test.go create mode 100644 modules/core/04-channel/v2/keeper/keeper.go create mode 100644 modules/core/04-channel/v2/keeper/keeper_test.go create mode 100644 modules/core/04-channel/v2/keeper/msg_server.go create mode 100644 modules/core/04-channel/v2/keeper/msg_server_test.go create mode 100644 modules/core/04-channel/v2/keeper/packet.go create mode 100644 modules/core/04-channel/v2/keeper/packet_test.go create mode 100644 modules/core/04-channel/v2/module.go create mode 100644 modules/core/04-channel/v2/module_test.go create mode 100644 modules/core/04-channel/v2/types/acknowledgement.go create mode 100644 modules/core/04-channel/v2/types/acknowledgement_test.go create mode 100644 modules/core/04-channel/v2/types/codec.go create mode 100644 modules/core/04-channel/v2/types/commitment.go create mode 100644 modules/core/04-channel/v2/types/commitment_test.go create mode 100644 modules/core/04-channel/v2/types/errors.go create mode 100644 modules/core/04-channel/v2/types/events.go create mode 100644 modules/core/04-channel/v2/types/expected_keepers.go create mode 100644 modules/core/04-channel/v2/types/genesis.go create mode 100644 modules/core/04-channel/v2/types/genesis.pb.go create mode 100644 modules/core/04-channel/v2/types/genesis_test.go create mode 100644 modules/core/04-channel/v2/types/keys.go create mode 100644 modules/core/04-channel/v2/types/merkle.go create mode 100644 modules/core/04-channel/v2/types/merkle_test.go create mode 100644 modules/core/04-channel/v2/types/msgs.go create mode 100644 modules/core/04-channel/v2/types/msgs_test.go create mode 100644 modules/core/04-channel/v2/types/packet.go create mode 100644 modules/core/04-channel/v2/types/packet.pb.go create mode 100644 modules/core/04-channel/v2/types/packet_test.go create mode 100644 modules/core/04-channel/v2/types/query.go create mode 100644 modules/core/04-channel/v2/types/query.pb.go create mode 100644 modules/core/04-channel/v2/types/query.pb.gw.go create mode 100644 modules/core/04-channel/v2/types/tx.pb.go create mode 100644 modules/core/05-port/doc.go create mode 100644 modules/core/05-port/keeper/keeper.go create mode 100644 modules/core/05-port/keeper/keeper_test.go create mode 100644 modules/core/05-port/module.go create mode 100644 modules/core/05-port/types/errors.go create mode 100644 modules/core/05-port/types/keys.go create mode 100644 modules/core/05-port/types/module.go create mode 100644 modules/core/05-port/types/router.go create mode 100644 modules/core/23-commitment/types/codec.go create mode 100644 modules/core/23-commitment/types/codec_test.go create mode 100644 modules/core/23-commitment/types/commitment.pb.go create mode 100644 modules/core/23-commitment/types/commitment_test.go create mode 100644 modules/core/23-commitment/types/errors.go create mode 100644 modules/core/23-commitment/types/merkle.go create mode 100644 modules/core/23-commitment/types/merkle_test.go create mode 100644 modules/core/23-commitment/types/utils.go create mode 100644 modules/core/23-commitment/types/utils_test.go create mode 100644 modules/core/23-commitment/types/v2/commitment.pb.go create mode 100644 modules/core/23-commitment/types/v2/merkle.go create mode 100644 modules/core/23-commitment/types/v2/merkle_test.go create mode 100644 modules/core/24-host/channel_keys.go create mode 100644 modules/core/24-host/client_keys.go create mode 100644 modules/core/24-host/connection_keys.go create mode 100644 modules/core/24-host/doc.go create mode 100644 modules/core/24-host/errors.go create mode 100644 modules/core/24-host/packet_keys.go create mode 100644 modules/core/24-host/parse.go create mode 100644 modules/core/24-host/parse_test.go create mode 100644 modules/core/24-host/port_keys.go create mode 100644 modules/core/24-host/v2/packet_key_test.go create mode 100644 modules/core/24-host/v2/packet_keys.go create mode 100644 modules/core/24-host/validate.go create mode 100644 modules/core/24-host/validate_test.go create mode 100644 modules/core/ante/ante.go create mode 100644 modules/core/ante/ante_test.go create mode 100644 modules/core/api/api_test.go create mode 100644 modules/core/api/module.go create mode 100644 modules/core/api/router.go create mode 100644 modules/core/api/router_test.go create mode 100644 modules/core/client/cli/cli.go create mode 100644 modules/core/client/query.go create mode 100644 modules/core/errors/errors.go create mode 100644 modules/core/exported/client.go create mode 100644 modules/core/exported/commitment.go create mode 100644 modules/core/exported/connection.go create mode 100644 modules/core/exported/module.go create mode 100644 modules/core/exported/packet.go create mode 100644 modules/core/genesis.go create mode 100644 modules/core/genesis_test.go create mode 100644 modules/core/internal/errors/errors.go create mode 100644 modules/core/internal/telemetry/client.go create mode 100644 modules/core/internal/telemetry/packet.go create mode 100644 modules/core/internal/v2/telemetry/packet.go create mode 100644 modules/core/keeper/events_test.go create mode 100644 modules/core/keeper/expected_keeper.go create mode 100644 modules/core/keeper/keeper.go create mode 100644 modules/core/keeper/keeper_test.go create mode 100644 modules/core/keeper/msg_server.go create mode 100644 modules/core/keeper/msg_server_test.go create mode 100644 modules/core/metrics/metrics.go create mode 100644 modules/core/migrations/v7/genesis.go create mode 100644 modules/core/migrations/v7/genesis_test.go create mode 100644 modules/core/module.go create mode 100644 modules/core/simulation/decoder.go create mode 100644 modules/core/simulation/decoder_test.go create mode 100644 modules/core/simulation/genesis.go create mode 100644 modules/core/simulation/genesis_test.go create mode 100644 modules/core/simulation/proposals.go create mode 100644 modules/core/simulation/proposals_test.go create mode 100644 modules/core/types/codec.go create mode 100644 modules/core/types/events.go create mode 100644 modules/core/types/expected_interfaces.go create mode 100644 modules/core/types/genesis.go create mode 100644 modules/core/types/genesis.pb.go create mode 100644 modules/light-clients/06-solomachine/client_state.go create mode 100644 modules/light-clients/06-solomachine/client_state_test.go create mode 100644 modules/light-clients/06-solomachine/codec.go create mode 100644 modules/light-clients/06-solomachine/codec_test.go create mode 100644 modules/light-clients/06-solomachine/consensus_state.go create mode 100644 modules/light-clients/06-solomachine/consensus_state_test.go create mode 100644 modules/light-clients/06-solomachine/doc.go create mode 100644 modules/light-clients/06-solomachine/errors.go create mode 100644 modules/light-clients/06-solomachine/header.go create mode 100644 modules/light-clients/06-solomachine/header_test.go create mode 100644 modules/light-clients/06-solomachine/keys.go create mode 100644 modules/light-clients/06-solomachine/light_client_module.go create mode 100644 modules/light-clients/06-solomachine/light_client_module_test.go create mode 100644 modules/light-clients/06-solomachine/misbehaviour.go create mode 100644 modules/light-clients/06-solomachine/misbehaviour_handle.go create mode 100644 modules/light-clients/06-solomachine/misbehaviour_test.go create mode 100644 modules/light-clients/06-solomachine/module.go create mode 100644 modules/light-clients/06-solomachine/proof.go create mode 100644 modules/light-clients/06-solomachine/proof_test.go create mode 100644 modules/light-clients/06-solomachine/proposal_handle.go create mode 100644 modules/light-clients/06-solomachine/solomachine.go create mode 100644 modules/light-clients/06-solomachine/solomachine.pb.go create mode 100644 modules/light-clients/06-solomachine/solomachine_test.go create mode 100644 modules/light-clients/06-solomachine/store.go create mode 100644 modules/light-clients/06-solomachine/update.go create mode 100644 modules/light-clients/07-tendermint/client_state.go create mode 100644 modules/light-clients/07-tendermint/client_state_test.go create mode 100644 modules/light-clients/07-tendermint/codec.go create mode 100644 modules/light-clients/07-tendermint/codec_test.go create mode 100644 modules/light-clients/07-tendermint/consensus_state.go create mode 100644 modules/light-clients/07-tendermint/consensus_state_test.go create mode 100644 modules/light-clients/07-tendermint/doc.go create mode 100644 modules/light-clients/07-tendermint/errors.go create mode 100644 modules/light-clients/07-tendermint/fraction.go create mode 100644 modules/light-clients/07-tendermint/header.go create mode 100644 modules/light-clients/07-tendermint/header_test.go create mode 100644 modules/light-clients/07-tendermint/keys.go create mode 100644 modules/light-clients/07-tendermint/light_client_module.go create mode 100644 modules/light-clients/07-tendermint/light_client_module_test.go create mode 100644 modules/light-clients/07-tendermint/migrations/expected_keepers.go create mode 100644 modules/light-clients/07-tendermint/migrations/migrations.go create mode 100644 modules/light-clients/07-tendermint/migrations/migrations_test.go create mode 100644 modules/light-clients/07-tendermint/misbehaviour.go create mode 100644 modules/light-clients/07-tendermint/misbehaviour_handle.go create mode 100644 modules/light-clients/07-tendermint/misbehaviour_handle_test.go create mode 100644 modules/light-clients/07-tendermint/misbehaviour_test.go create mode 100644 modules/light-clients/07-tendermint/module.go create mode 100644 modules/light-clients/07-tendermint/proposal_handle.go create mode 100644 modules/light-clients/07-tendermint/proposal_handle_test.go create mode 100644 modules/light-clients/07-tendermint/store.go create mode 100644 modules/light-clients/07-tendermint/store_test.go create mode 100644 modules/light-clients/07-tendermint/tendermint.pb.go create mode 100644 modules/light-clients/07-tendermint/tendermint_test.go create mode 100644 modules/light-clients/07-tendermint/update.go create mode 100644 modules/light-clients/07-tendermint/update_test.go create mode 100644 modules/light-clients/07-tendermint/upgrade.go create mode 100644 modules/light-clients/07-tendermint/upgrade_test.go create mode 100644 modules/light-clients/08-wasm/CHANGELOG.md create mode 100644 modules/light-clients/08-wasm/Dockerfile create mode 100644 modules/light-clients/08-wasm/README.md create mode 100644 modules/light-clients/08-wasm/blsverifier/crypto.go create mode 100644 modules/light-clients/08-wasm/blsverifier/handler.go create mode 100644 modules/light-clients/08-wasm/client/cli/cli.go create mode 100644 modules/light-clients/08-wasm/client/cli/query.go create mode 100644 modules/light-clients/08-wasm/client/cli/tx.go create mode 100644 modules/light-clients/08-wasm/doc.go create mode 100644 modules/light-clients/08-wasm/go.mod create mode 100644 modules/light-clients/08-wasm/go.sum create mode 100644 modules/light-clients/08-wasm/internal/types/store.go create mode 100644 modules/light-clients/08-wasm/internal/types/store_test.go create mode 100644 modules/light-clients/08-wasm/keeper/contract_keeper.go create mode 100644 modules/light-clients/08-wasm/keeper/contract_keeper_test.go create mode 100644 modules/light-clients/08-wasm/keeper/events.go create mode 100644 modules/light-clients/08-wasm/keeper/export_test.go create mode 100644 modules/light-clients/08-wasm/keeper/genesis.go create mode 100644 modules/light-clients/08-wasm/keeper/genesis_test.go create mode 100644 modules/light-clients/08-wasm/keeper/grpc_query.go create mode 100644 modules/light-clients/08-wasm/keeper/grpc_query_test.go create mode 100644 modules/light-clients/08-wasm/keeper/keeper.go create mode 100644 modules/light-clients/08-wasm/keeper/keeper_no_vm.go create mode 100644 modules/light-clients/08-wasm/keeper/keeper_test.go create mode 100644 modules/light-clients/08-wasm/keeper/keeper_vm.go create mode 100644 modules/light-clients/08-wasm/keeper/migrations.go create mode 100644 modules/light-clients/08-wasm/keeper/migrations_test.go create mode 100644 modules/light-clients/08-wasm/keeper/msg_server.go create mode 100644 modules/light-clients/08-wasm/keeper/msg_server_test.go create mode 100644 modules/light-clients/08-wasm/keeper/options.go create mode 100644 modules/light-clients/08-wasm/keeper/options_test.go create mode 100644 modules/light-clients/08-wasm/keeper/querier.go create mode 100644 modules/light-clients/08-wasm/keeper/querier_test.go create mode 100644 modules/light-clients/08-wasm/keeper/snapshotter.go create mode 100644 modules/light-clients/08-wasm/keeper/snapshotter_test.go create mode 100644 modules/light-clients/08-wasm/light_client_module.go create mode 100644 modules/light-clients/08-wasm/light_client_module_test.go create mode 100644 modules/light-clients/08-wasm/module.go create mode 100644 modules/light-clients/08-wasm/simulation/proposals.go create mode 100644 modules/light-clients/08-wasm/simulation/proposals_test.go create mode 100644 modules/light-clients/08-wasm/testing/mock_engine.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/README.md create mode 100644 modules/light-clients/08-wasm/testing/simapp/ante_handler.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/app.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/encoding.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/export.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/genesis.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/genesis_account.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/params/amino.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/params/doc.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/params/encoding.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/params/proto.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/simd/cmd/root.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/simd/main.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/test_helpers.go create mode 100644 modules/light-clients/08-wasm/testing/simapp/upgrades.go create mode 100644 modules/light-clients/08-wasm/testing/values.go create mode 100644 modules/light-clients/08-wasm/testing/wasm_endpoint.go create mode 100644 modules/light-clients/08-wasm/types/client_message.go create mode 100644 modules/light-clients/08-wasm/types/client_message_test.go create mode 100644 modules/light-clients/08-wasm/types/client_state.go create mode 100644 modules/light-clients/08-wasm/types/client_state_test.go create mode 100644 modules/light-clients/08-wasm/types/codec.go create mode 100644 modules/light-clients/08-wasm/types/codec_test.go create mode 100644 modules/light-clients/08-wasm/types/config.go create mode 100644 modules/light-clients/08-wasm/types/consensus_state.go create mode 100644 modules/light-clients/08-wasm/types/consensus_state_test.go create mode 100644 modules/light-clients/08-wasm/types/contract_api.go create mode 100644 modules/light-clients/08-wasm/types/errors.go create mode 100644 modules/light-clients/08-wasm/types/events.go create mode 100644 modules/light-clients/08-wasm/types/expected_interfaces.go create mode 100644 modules/light-clients/08-wasm/types/expected_keepers.go create mode 100644 modules/light-clients/08-wasm/types/gas_register.go create mode 100644 modules/light-clients/08-wasm/types/gas_register_custom.go create mode 100644 modules/light-clients/08-wasm/types/genesis.go create mode 100644 modules/light-clients/08-wasm/types/genesis.pb.go create mode 100644 modules/light-clients/08-wasm/types/genesis_test.go create mode 100644 modules/light-clients/08-wasm/types/keys.go create mode 100644 modules/light-clients/08-wasm/types/msgs.go create mode 100644 modules/light-clients/08-wasm/types/msgs_test.go create mode 100644 modules/light-clients/08-wasm/types/query.pb.go create mode 100644 modules/light-clients/08-wasm/types/query.pb.gw.go create mode 100644 modules/light-clients/08-wasm/types/store.go create mode 100644 modules/light-clients/08-wasm/types/tx.pb.go create mode 100644 modules/light-clients/08-wasm/types/types_test.go create mode 100644 modules/light-clients/08-wasm/types/utils.go create mode 100644 modules/light-clients/08-wasm/types/validation.go create mode 100644 modules/light-clients/08-wasm/types/validation_test.go create mode 100644 modules/light-clients/08-wasm/types/wasm.pb.go create mode 100644 modules/light-clients/08-wasm/types/wasm_vm.go create mode 100644 modules/light-clients/08-wasm/wasm_test.go create mode 100644 modules/light-clients/09-localhost/doc.go create mode 100644 modules/light-clients/09-localhost/light_client_module.go create mode 100644 modules/light-clients/09-localhost/light_client_module_test.go create mode 100644 package-lock.json create mode 100644 proto/buf.gen.gogo.yaml create mode 100644 proto/buf.gen.swagger.yaml create mode 100644 proto/buf.lock create mode 100644 proto/buf.yaml create mode 100644 proto/ibc/applications/interchain_accounts/controller/v1/controller.proto create mode 100644 proto/ibc/applications/interchain_accounts/controller/v1/query.proto create mode 100644 proto/ibc/applications/interchain_accounts/controller/v1/tx.proto create mode 100644 proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto create mode 100644 proto/ibc/applications/interchain_accounts/host/v1/host.proto create mode 100644 proto/ibc/applications/interchain_accounts/host/v1/query.proto create mode 100644 proto/ibc/applications/interchain_accounts/host/v1/tx.proto create mode 100644 proto/ibc/applications/interchain_accounts/v1/account.proto create mode 100644 proto/ibc/applications/interchain_accounts/v1/metadata.proto create mode 100644 proto/ibc/applications/interchain_accounts/v1/packet.proto create mode 100644 proto/ibc/applications/transfer/v1/authz.proto create mode 100644 proto/ibc/applications/transfer/v1/denomtrace.proto create mode 100644 proto/ibc/applications/transfer/v1/genesis.proto create mode 100644 proto/ibc/applications/transfer/v1/packet.proto create mode 100644 proto/ibc/applications/transfer/v1/query.proto create mode 100644 proto/ibc/applications/transfer/v1/token.proto create mode 100644 proto/ibc/applications/transfer/v1/transfer.proto create mode 100644 proto/ibc/applications/transfer/v1/tx.proto create mode 100644 proto/ibc/core/channel/v1/channel.proto create mode 100644 proto/ibc/core/channel/v1/genesis.proto create mode 100644 proto/ibc/core/channel/v1/query.proto create mode 100644 proto/ibc/core/channel/v1/tx.proto create mode 100644 proto/ibc/core/channel/v2/genesis.proto create mode 100644 proto/ibc/core/channel/v2/packet.proto create mode 100644 proto/ibc/core/channel/v2/query.proto create mode 100644 proto/ibc/core/channel/v2/tx.proto create mode 100644 proto/ibc/core/client/v1/client.proto create mode 100644 proto/ibc/core/client/v1/genesis.proto create mode 100644 proto/ibc/core/client/v1/query.proto create mode 100644 proto/ibc/core/client/v1/tx.proto create mode 100644 proto/ibc/core/client/v2/config.proto create mode 100644 proto/ibc/core/client/v2/counterparty.proto create mode 100644 proto/ibc/core/client/v2/genesis.proto create mode 100644 proto/ibc/core/client/v2/query.proto create mode 100644 proto/ibc/core/client/v2/tx.proto create mode 100644 proto/ibc/core/commitment/v1/commitment.proto create mode 100644 proto/ibc/core/commitment/v2/commitment.proto create mode 100644 proto/ibc/core/connection/v1/connection.proto create mode 100644 proto/ibc/core/connection/v1/genesis.proto create mode 100644 proto/ibc/core/connection/v1/query.proto create mode 100644 proto/ibc/core/connection/v1/tx.proto create mode 100644 proto/ibc/core/types/v1/genesis.proto create mode 100644 proto/ibc/lightclients/solomachine/v2/solomachine.proto create mode 100644 proto/ibc/lightclients/solomachine/v3/solomachine.proto create mode 100644 proto/ibc/lightclients/tendermint/v1/tendermint.proto create mode 100644 proto/ibc/lightclients/wasm/v1/genesis.proto create mode 100644 proto/ibc/lightclients/wasm/v1/query.proto create mode 100644 proto/ibc/lightclients/wasm/v1/tx.proto create mode 100644 proto/ibc/lightclients/wasm/v1/wasm.proto create mode 100644 releases-decision-tree.png create mode 100644 requirements.txt create mode 100644 scripts/README.md create mode 100755 scripts/build-wasm-simapp-docker.sh create mode 100644 scripts/compatibility.md create mode 100755 scripts/generate-compatibility-json.py create mode 100755 scripts/get-libwasm-version.py create mode 100755 scripts/go-lint-all.sh create mode 100755 scripts/go-mod-tidy-all.sh create mode 100755 scripts/go-test-all.py create mode 100755 scripts/init-simapp.sh create mode 100644 scripts/linkify_changelog.py create mode 100755 scripts/protoc-swagger-gen.sh create mode 100755 scripts/protocgen.sh create mode 100644 simapp/README.md create mode 100644 simapp/ante.go create mode 100644 simapp/app.go create mode 100644 simapp/export.go create mode 100644 simapp/genesis.go create mode 100644 simapp/go.mod create mode 100644 simapp/go.sum create mode 100644 simapp/params/doc.go create mode 100644 simapp/params/encoding.go create mode 100644 simapp/params/params.go create mode 100644 simapp/params/weights.go create mode 100644 simapp/simd/cmd/cmd_test.go create mode 100644 simapp/simd/cmd/root.go create mode 100644 simapp/simd/main.go create mode 100644 simapp/upgrades.go create mode 100644 simapp/upgrades/upgrades.go create mode 100644 testing/README.md create mode 100644 testing/chain.go create mode 100644 testing/chain_test.go create mode 100644 testing/config.go create mode 100644 testing/coordinator.go create mode 100644 testing/endpoint.go create mode 100644 testing/endpoint_v2.go create mode 100644 testing/events.go create mode 100644 testing/events_test.go create mode 100644 testing/mock/README.md create mode 100644 testing/mock/ack.go create mode 100644 testing/mock/address_codec.go create mode 100644 testing/mock/doc.go create mode 100644 testing/mock/events.go create mode 100644 testing/mock/ibc_app.go create mode 100644 testing/mock/ibc_module.go create mode 100644 testing/mock/middleware.go create mode 100644 testing/mock/mock.go create mode 100644 testing/mock/v2/ibc_app.go create mode 100644 testing/mock/v2/ibc_module.go create mode 100644 testing/mock/v2/mock.go create mode 100644 testing/path.go create mode 100644 testing/simapp/README.md create mode 100644 testing/simapp/ante.go create mode 100644 testing/simapp/app.go create mode 100644 testing/simapp/genesis.go create mode 100644 testing/simapp/test_helpers.go create mode 100644 testing/solomachine.go create mode 100644 testing/testing_app.go create mode 100644 testing/utils.go create mode 100644 testing/values.go diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..4c437c3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,116 @@ +--- +Language: Proto +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +RawStringFormats: + - Delimiters: + - pb + Language: TextProto + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never +... + diff --git a/.github/.codespellignore b/.github/.codespellignore new file mode 100644 index 0000000..24fd5c6 --- /dev/null +++ b/.github/.codespellignore @@ -0,0 +1,2 @@ +clientA +connectionA diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000..6ada633 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,42 @@ +--- +name: Bug Report +about: Create a report to help us squash bugs! + +--- + + + + + +## Summary of Bug + + + +## Expected Behaviour + + + +## Version + + + +## Steps to Reproduce + + + +____ + +#### For Admin Use + +- [ ] Not duplicate issue +- [ ] Appropriate labels applied +- [ ] Appropriate contributors tagged/assigned +- [ ] Estimate provided diff --git a/.github/ISSUE_TEMPLATE/epic-tracker.md b/.github/ISSUE_TEMPLATE/epic-tracker.md new file mode 100644 index 0000000..d143f8b --- /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/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 0000000..96c2fe1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,40 @@ +--- +name: Feature Request +about: Create a proposal to request a feature + +--- + + + +## Summary + + + +## Problem Definition + + + +## Use cases + + + +## Proposal + + + +____ + +#### For Admin Use + +- [ ] Not duplicate issue +- [ ] Appropriate labels applied +- [ ] Appropriate contributors tagged/assigned +- [ ] Estimate provided diff --git a/.github/ISSUE_TEMPLATE/release-tracker.md b/.github/ISSUE_TEMPLATE/release-tracker.md new file mode 100644 index 0000000..611a4d8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release-tracker.md @@ -0,0 +1,83 @@ +--- +name: Release tracker +about: Create an issue to track release progress +--- + + + +## Milestones + + + +## IBC spec compatibility + + + +## QA + +### Backwards compatibility + + + +- [ ] [Compatibility tests](https://github.com/cosmos/ibc-go/actions/workflows/e2e-compatibility.yaml) pass for the release branch. +- [ ] [Upgrade tests](https://github.com/cosmos/ibc-go/actions/workflows/e2e-upgrade.yaml) pass. +- [ ] Manual test with ledger signing. + +### Other testing + +## 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` and add branch protection rules. +- [ ] 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 [interchaintest](https://github.com/cosmos/interchaintest). +- [ ] 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): + - Add the new release line. + - Remove any release lines that might have become discontinued. +- [ ] Update [version matrix](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md#version-matrix) in `RELEASES.md`: + - Add the new release. + - Remove any tags that might not be recommended anymore. +- [ ] Update the list of [supported release lines in README.md](https://github.com/cosmos/ibc-go#releases), if necessary. +- [ ] Update docs site: + - [ ] Update permalinks with links of the released tag. + - [ ] If the release is occurring on the main branch, on the latest version, then run `npm run docusaurus docs:version vX.Y.Z` in the `docs/` directory. (where `X.Y.Z` is the new version number) + - [ ] If the release is occurring on an older release branch, then make a PR to the main branch called `docs: new release vX.Y.Z` doing the following: + - [ ] Update the content of the docs found in `docs/versioned_docs/version-vx.y.z` if needed. (where `x.y.z` is the previous version number) + - [ ] Update the version number of the older release branch by changing the version number of the older release branch in: + - [ ] In `docs/versions.json`. + - [ ] Rename `docs/versioned_sidebars/version-vx.y.z-sidebars.json` + - [ ] Rename `docs/versioned_docs/version-vx.y.z` +- [ ] Ensure annotations on tests are correct as per the [compatibility test tool](../../scripts/compatibility.md): + - Add the new release. + - Remove any tags that might not be recommended anymore. +- [ ] Update the manual [e2e `simd`](https://github.com/cosmos/ibc-go/blob/main/.github/workflows/e2e-manual-simd.yaml) test workflow: + - Remove any tags that might not be recommended anymore. +- [ ] After changes to docs site are deployed, check [ibc.cosmos.network](https://ibc.cosmos.network) is updated. +- [ ] Open issue in [SDK tutorials repo](https://github.com/cosmos/sdk-tutorials) to update tutorials to the released version of ibc-go. + +--- + +#### For Admin Use + +- [ ] Not duplicate issue +- [ ] Appropriate labels applied +- [ ] Appropriate contributors tagged/assigned diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..c7431fe --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,41 @@ + + +## Description + + + +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. + +- [ ] Linked to GitHub issue with discussion and accepted design, OR link to spec that describes this work. +- [ ] Include changelog entry when appropriate (e.g. chores should be omitted from changelog). +- [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/main/testing/README.md#ibc-testing-package) if relevant. +- [ ] Updated documentation (`docs/`) if anything is changed. +- [ ] Added `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code) if relevant. +- [ ] Self-reviewed `Files changed` in the GitHub PR explorer. +- [ ] Provide a [conventional commit message](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) to follow the repository standards. + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b6fc6c8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,39 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 + + - package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + + - package-ecosystem: gomod + directory: "/e2e" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + + - package-ecosystem: gomod + directory: "/modules/light-clients/08-wasm" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies + + - package-ecosystem: gomod + directory: "/simapp" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - dependencies diff --git a/.github/mergify.yml b/.github/mergify.yml new file mode 100644 index 0000000..9286f34 --- /dev/null +++ b/.github/mergify.yml @@ -0,0 +1,84 @@ +queue_rules: + - name: default + queue_conditions: + - "#approved-reviews-by>=1" + - base=main + - label=automerge + commit_message_template: | + {{ title }} (#{{ number }}) + {{ body }} + merge_conditions: + - "#approved-reviews-by>=1" + - base=main + - label=automerge + merge_method: squash + +pull_request_rules: + - name: backport patches to v0.2.x callbacks ibc-go v7.3.x branch + conditions: + - base=main + - label=backport-callbacks-to-v0.2.x+ibc-go-v7.3.x + actions: + backport: + branches: + - callbacks/release/v0.2.x+ibc-go-v7.3.x + - name: backport patches to v0.2.x callbacks ibc-go v8.0.x branch + conditions: + - base=main + - label=backport-callbacks-to-v0.2.x+ibc-go-v8.0.x + actions: + backport: + branches: + - callbacks/release/v0.2.x+ibc-go-v8.0.x + - name: backport patches to v0.4.x wasm ibc-go v7.4.x & wasmvm 1.5.x branch + conditions: + - base=main + - label=backport-wasm-v0.4.x+ibc-go-v7.4.x-wasmvm-v1.5.x + actions: + backport: + branches: + - 08-wasm/release/v0.4.x+ibc-go-v7.4.x-wasmvm-v1.5.x + - name: backport patches to v0.5.x wasm ibc-go v8.4.x & wasmvm 2.1.x branch + conditions: + - base=main + - label=backport-wasm-v0.5.x+ibc-go-v8.4.x-wasmvm-v2.1.x + actions: + backport: + branches: + - 08-wasm/release/v0.5.x+ibc-go-v8.4.x-wasmvm-v2.1.x + - name: backport patches to v7.10.x branch + conditions: + - base=main + - label=backport-to-v7.10.x + actions: + backport: + branches: + - release/v7.10.x + - name: backport patches to v8.7.x branch + conditions: + - base=main + - label=backport-to-v8.7.x + actions: + backport: + branches: + - release/v8.7.x + - name: backport patches to v10.2.x branch + conditions: + - base=main + - label=backport-to-v10.2.x + actions: + backport: + branches: + - release/v10.2.x + - name: backport patches to v10.3.x branch + conditions: + - base=main + - label=backport-to-v10.3.x + actions: + backport: + branches: + - release/v10.3.x + - name: automerge to main with label automerge and branch protection passing + conditions: [] + actions: + queue: diff --git a/.github/workflows/build-simd-image-from-tag.yml b/.github/workflows/build-simd-image-from-tag.yml new file mode 100644 index 0000000..228704d --- /dev/null +++ b/.github/workflows/build-simd-image-from-tag.yml @@ -0,0 +1,42 @@ +name: Build Simd Image +on: + workflow_dispatch: + inputs: + tag: + description: 'The tag of the image to build' + required: true + type: string + ibc-go-version: + description: 'The ibc-go version to be added as a label' + required: true + type: string + +env: + REGISTRY: ghcr.io + ORG: cosmos + IMAGE_NAME: ibc-go-simd + GIT_TAG: "${{ inputs.tag }}" + +jobs: + build-image-at-tag: + runs-on: depot-ubuntu-22.04-4 + permissions: + packages: write + contents: read + steps: + - uses: actions/checkout@v4 + with: + ref: "${{ env.GIT_TAG }}" + fetch-depth: 0 + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push image + run: | + # remove any `/` characters from the docker tag and replace them with a - + docker_tag="$(echo $GIT_TAG | sed 's/[^a-zA-Z0-9\.]/-/g')" + docker build . -t "${REGISTRY}/${ORG}/${IMAGE_NAME}:${docker_tag}" --build-arg IBC_GO_VERSION=${{ inputs.ibc-go-version }} + docker push "${REGISTRY}/${ORG}/${IMAGE_NAME}:${docker_tag}" diff --git a/.github/workflows/build-wasm-simd-image-from-tag.yml b/.github/workflows/build-wasm-simd-image-from-tag.yml new file mode 100644 index 0000000..43e4289 --- /dev/null +++ b/.github/workflows/build-wasm-simd-image-from-tag.yml @@ -0,0 +1,108 @@ +name: Build Wasm Simd Image +on: + workflow_dispatch: + inputs: + tag: + description: 'The tag of the image to build' + required: true + type: string + +env: + REGISTRY: ghcr.io + ORG: cosmos + IMAGE_NAME: ibc-go-wasm-simd + GIT_TAG: "${{ inputs.tag }}" + +jobs: + build-image-at-tag: + permissions: + packages: write + contents: read + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-24.04 + platform: linux/amd64 + - os: ubuntu-24.04-arm + platform: linux/arm64 + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + with: + ref: "${{ env.GIT_TAG }}" + fetch-depth: 0 + + # TODO: #7885 Get rid of this script, it is super unecessary and can probably be done in the Dockerfile or a bash script + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Install dependencies + run: make python-install-deps + - name: Get arguments + run: echo "LIBWASM_VERSION=$(scripts/get-libwasm-version.py --get-version)" >> $GITHUB_ENV + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + id: build + uses: docker/build-push-action@v6 + with: + platforms: ${{ matrix.platform }} + file: modules/light-clients/08-wasm/Dockerfile + build-args: LIBWASM_VERSION=${{ env.LIBWASM_VERSION }} + outputs: type=image,"name=${{ env.REGISTRY }}/${{ env.ORG }}/${{ env.IMAGE_NAME }}",push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p ${{ runner.temp }}/digests + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ matrix.os }} # If we end up running more builds on the same OS, we need to differentiate more here + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: depot-ubuntu-22.04-4 + permissions: + packages: write + contents: read + needs: + - build-image-at-tag + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digests-* + merge-multiple: true + + - name: Get docker tag + # remove all `/` or `+` characters from the docker tag and replace them with a -. + # this ensures the docker tag is valid. + run: echo "DOCKER_TAG=$(echo $GIT_TAG | sed 's/[^a-zA-Z0-9\.]/-/g')" >> $GITHUB_ENV + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create --tag ${{ env.REGISTRY }}/${{ env.ORG }}/${{ env.IMAGE_NAME }}:${{ env.DOCKER_TAG }} $(printf '${{ env.REGISTRY }}/${{ env.ORG }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..db22f8c --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,81 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + schedule: + - cron: '37 21 * * 4' + +jobs: + analyze: + name: Analyze + runs-on: depot-ubuntu-22.04-4 + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'go' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - uses: technote-space/get-diff-action@v6.1.2 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # 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) + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + 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@v3 + if: env.GIT_DIFF diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..030a4a3 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,70 @@ +name: Docker Build & Push Simapp (main) +# Build & Push builds the simapp docker image on every push to main and +# and pushes the image to https://ghcr.io/cosmos/ibc-go-simd +on: + workflow_dispatch: + push: + branches: + - main + - release/v* + paths: + - '.github/workflows/docker.yml' + - '**.go' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ibc-go-simd + +jobs: + docker-build: + runs-on: depot-ubuntu-22.04-4 + permissions: + packages: write + contents: read + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }} + + - name: Compute release branch tag + id: reltag + if: startsWith(github.ref_name, 'release/v') + shell: bash + run: | + RAW="${GITHUB_REF_NAME}" + SANITIZED="${RAW//\//-}" + echo "full_tag=${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }}:branch-${SANITIZED}" >> "$GITHUB_OUTPUT" + + - name: Build Docker image + uses: docker/build-push-action@v6 + with: + context: . + tags: ${{ steps.meta.outputs.tags }} + build-args: | + IBC_GO_VERSION=${{ github.ref_name }} + + - name: Test simd is runnable + run: | + docker run --rm ${{ steps.meta.outputs.tags }} + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: | + ${{ steps.meta.outputs.tags }} + ${{ steps.reltag.outputs.full_tag }} + build-args: | + IBC_GO_VERSION=${{ github.ref_name }} diff --git a/.github/workflows/docs-check.yml b/.github/workflows/docs-check.yml new file mode 100644 index 0000000..b94aa70 --- /dev/null +++ b/.github/workflows/docs-check.yml @@ -0,0 +1,36 @@ +name: Check docs build +on: + merge_group: + pull_request: + branches: + - main + paths: + - 'docs/**' + - '.github/workflows/check-docs.yml' + +jobs: + build: + runs-on: depot-ubuntu-22.04-4 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + cache-dependency-path: docs/package-lock.json + + - name: Install dependencies + run: cd docs && npm ci + - name: Test build website + run: cd docs && npm run build + + lint: + runs-on: depot-ubuntu-22.04-4 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: DavidAnson/markdownlint-cli2-action@v20 + with: + globs: ./docs/docs/**/*.md + diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml new file mode 100644 index 0000000..2b0be24 --- /dev/null +++ b/.github/workflows/docs-deploy.yml @@ -0,0 +1,34 @@ +# This deploy-docs workflow was created based on instructions from: +# https://docusaurus.io/docs/deployment +name: Deploy to GitHub Pages + +on: + workflow_dispatch: + push: + branches: + - main + paths: + - "docs/**" + - .github/workflows/deploy-docs.yml + +jobs: + deploy: + name: Deploy to GitHub Pages + runs-on: depot-ubuntu-22.04-4 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + cache-dependency-path: docs/package-lock.json + + - name: Build website + run: make build-docs + + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@v4.7.3 + with: + branch: gh-pages + folder: docs/build + single-commit: true diff --git a/.github/workflows/e2e-compatibility-workflow-call.yaml b/.github/workflows/e2e-compatibility-workflow-call.yaml new file mode 100644 index 0000000..f2c494b --- /dev/null +++ b/.github/workflows/e2e-compatibility-workflow-call.yaml @@ -0,0 +1,74 @@ +on: + workflow_call: + inputs: + test-file: + description: 'The test file' + required: true + type: string + release-version: + description: 'the release tag, e.g. release-v7.3.0' + required: true + type: string + chain: + description: 'Should be one of chain-a, chain-b or all. Split up workflows into multiple (chain-a and chain-b) versions if the job limit is exceeded.' + required: false + type: string + default: all + +jobs: + load-test-matrix: + outputs: + test-matrix: ${{ steps.set-test-matrix.outputs.test-matrix }} + runs-on: depot-ubuntu-22.04-4 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + - run: pip install -r requirements.txt + - run: | + # use jq -c to compact the full json contents into a single line. This is required when using the json body + # to create the matrix in the following job. + test_matrix="$(python scripts/generate-compatibility-json.py --file ${{ inputs.test-file }} --release-version ${{ inputs.release-version }} --chain ${{ inputs.chain }})" + echo "test-matrix=$test_matrix" >> $GITHUB_OUTPUT + id: set-test-matrix + + e2e: + runs-on: depot-ubuntu-22.04-4 + needs: load-test-matrix + # this job is skipped if the test-matrix generated is empty. i.e. if the file was not present. + # this allows us to not have to handle special case versions which may not have certain tests run against them. + if: needs.load-test-matrix.outputs.test-matrix + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.load-test-matrix.outputs.test-matrix) }} + steps: + - name: Checkout the ibc-go repo + uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache-dependency-path: 'e2e/go.sum' + - name: Run e2e Test + run: | + cd e2e + make e2e-test test=${{ matrix.test }} + env: + # each test has its own set of variables to specify which images are used. + # Note: this is significant as the standard behaviour when running e2es on PRs + # is that there is a set of env vars that are the same for each run. e.g. the same docker image is used + # for every test. With compatibility tests, each test may be running different combinations of images. + CHAIN_A_TAG: '${{ matrix.chain-a }}' + CHAIN_B_TAG: '${{ matrix.chain-b }}' + RELAYER_ID: '${{ matrix.relayer-type }}' + - name: Upload Diagnostics + uses: actions/upload-artifact@v4 + # we only want to upload logs on test failures. + if: ${{ failure() }} + continue-on-error: true + with: + name: '${{ matrix.entrypoint }}-${{ matrix.test }}' + path: e2e/diagnostics + retention-days: 5 diff --git a/.github/workflows/e2e-compatibility.yaml b/.github/workflows/e2e-compatibility.yaml new file mode 100644 index 0000000..b63ca9c --- /dev/null +++ b/.github/workflows/e2e-compatibility.yaml @@ -0,0 +1,230 @@ +# Runs compatibility tests for ibc-go. +# Can be triggered manually by setting values for release-branch and ibc-go-version. +# On a weekly schedule with default values of 'main' for release-branch and 'main-cron-job' for ibc-go-version. +name: Compatibility E2E +on: + schedule: + # run on 20:00 on Sunday. + - cron: '0 20 * * 6' + workflow_dispatch: + inputs: + release-branch: + description: 'Release branch to test' + required: true + type: choice + options: + - release/v7.10.x + - release/v8.7.x + - release/v10.3.x + - main + ibc-go-version: + description: 'The version of ibc-go that is going to be released' + required: true + type: string + +env: + REGISTRY: ghcr.io + ORG: cosmos + IMAGE_NAME: ibc-go-simd + RELEASE_BRANCH: ${{ inputs.release-branch || 'main' }} + IBC_GO_VERSION: ${{ inputs.ibc-go-version || 'latest' }} + +jobs: + determine-image-tag: + runs-on: depot-ubuntu-22.04-4 + outputs: + release-version: ${{ steps.set-release-version.outputs.release-version }} + steps: + - run: | + # we sanitize the release branch name. Docker images cannot contain "/" + # characters so we replace them with a "-". + release_version="$(echo $RELEASE_BRANCH | sed 's/\//-/')" + echo "release-version=$release_version" >> $GITHUB_OUTPUT + id: set-release-version + + # build-release-images builds all docker images that are relevant for the compatibility tests. If a single release + # branch is specified, only that image will be built, e.g. release-v6.0.x. + build-release-images: + runs-on: depot-ubuntu-22.04-4 + permissions: + packages: write + contents: read + strategy: + matrix: + release-branch: + - release/v7.10.x + - release/v8.7.x + - release/v10.3.x + - main + steps: + - uses: actions/checkout@v4 + if: env.RELEASE_BRANCH == matrix.release-branch + with: + ref: "${{ matrix.release-branch }}" + fetch-depth: 0 + - name: Log in to the Container registry + if: env.RELEASE_BRANCH == matrix.release-branch + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build image + if: env.RELEASE_BRANCH == matrix.release-branch + run: | + docker_tag="$(echo ${{ matrix.release-branch }} | sed 's/[^a-zA-Z0-9\.]/-/g')" + docker build . -t "${REGISTRY}/${ORG}/${IMAGE_NAME}:$docker_tag" --build-arg IBC_GO_VERSION=${{ env.IBC_GO_VERSION }} + docker push "${REGISTRY}/${ORG}/${IMAGE_NAME}:$docker_tag" + - name: Display image details + if: env.RELEASE_BRANCH == matrix.release-branch + run: | + docker_tag="$(echo ${{ matrix.release-branch }} | sed 's/[^a-zA-Z0-9\.]/-/g')" + docker inspect "${REGISTRY}/${ORG}/${IMAGE_NAME}:$docker_tag" + + client-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/core/02-client/client_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + connection-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/core/03-connection/connection_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + ica-base-test-a: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/interchain_accounts/base_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + chain: "chain-a" + + ica-base-test-b: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/interchain_accounts/base_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + chain: "chain-b" + + ica-gov-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/interchain_accounts/gov_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + ica-groups-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/interchain_accounts/groups_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + ica-localhost-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/interchain_accounts/localhost_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + ica-params-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/interchain_accounts/params_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + ica-query-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/interchain_accounts/query_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + transfer-base-test-a: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/transfer/base_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + chain: "chain-a" + + transfer-base-test-b: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/transfer/base_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + chain: "chain-b" + + transfer-authz-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/transfer/authz_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + transfer-localhost-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/transfer/localhost_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + transfer-send-enabled-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/transfer/send_enabled_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + transfer-receive-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/transfer/send_receive_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" + + upgrade-genesis-test: + needs: + - build-release-images + - determine-image-tag + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file: "e2e/tests/upgrades/genesis_test.go" + release-version: "${{ needs.determine-image-tag.outputs.release-version }}" diff --git a/.github/workflows/e2e-test-workflow-call.yml b/.github/workflows/e2e-test-workflow-call.yml new file mode 100644 index 0000000..b171633 --- /dev/null +++ b/.github/workflows/e2e-test-workflow-call.yml @@ -0,0 +1,279 @@ +on: + workflow_call: + inputs: + test-entry-point: + description: 'Test entry point' + required: false + type: string + default: '' # empty string means run all tests + temp-run-full-suite: + description: 'This flag exists to run a hard coded set of tests and will be phased out' + required: false + type: boolean + default: false + test: + description: 'test name to run as standalone' + required: false + type: string + default: '' + test-exclusions: + description: 'Comma separated list of tests to skip' + required: false + type: string + default: '' # empty string means don't skip any test. + chain-image: + description: 'The image to use for chains' + required: false + type: string + default: 'ghcr.io/cosmos/ibc-go-simd' + chain-a-tag: + description: 'The tag to use for chain A' + required: true + type: string + default: main + chain-b-tag: + default: main + description: 'The tag to use for chain B' + required: true + type: string + # upgrade-plan-name is only required during upgrade tests, and is otherwise ignored. + upgrade-plan-name: + default: '' + description: 'The upgrade plan name' + required: false + type: string + build-and-push-docker-image: + description: 'Flag to specify if the docker image should be built and pushed beforehand' + required: false + type: boolean + default: false + build-and-push-docker-image-wasm: + description: 'Flag to specify if the wasm docker image should be built and pushed beforehand' + required: false + type: boolean + default: false + upload-logs: + description: 'Specify flag to indicate that logs should be uploaded on failure' + required: false + type: boolean + default: false + e2e-config-path: + description: 'Specify relative or absolute path of config file for test' + required: false + type: string + default: 'ci-e2e-config.yaml' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ibc-go-simd + IMAGE_NAME_WASM: ibc-go-wasm-simd + +jobs: + # test-details exists to provide an easy way to see the inputs for the e2e test. + test-details: + runs-on: depot-ubuntu-22.04-4 + steps: + - name: Display Inputs + run: | + echo "Chain Image: ${{ inputs.chain-image }}" + echo "Chain A Tag: ${{ inputs.chain-a-tag }}" + echo "Chain B Tag: ${{ inputs.chain-b-tag }}" + echo "Upgrade Plan Name: ${{ inputs.upgrade-plan-name }}" + echo "Test Entry Point: ${{ inputs.test-entry-point }}" + echo "Test: ${{ inputs.test }}" + echo "Github Ref Name: ${{ github.ref_name }}" + + # we skip individual steps rather than the full job as e2e-tests will not run if this task + # is skipped. But will run if every individual task is skipped. There is no current way of conditionally needing + # a job. + docker-build: + runs-on: depot-ubuntu-22.04-4 + steps: + - uses: actions/checkout@v4 + if: ${{ inputs.build-and-push-docker-image }} + - name: Log in to the Container registry + if: ${{ inputs.build-and-push-docker-image }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + if: ${{ inputs.build-and-push-docker-image }} + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + if: ${{ inputs.build-and-push-docker-image }} + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + build-args: | + IBC_GO_VERSION=${{ github.ref_name }} + + docker-build-wasm: + runs-on: depot-ubuntu-22.04-4 + steps: + - uses: actions/checkout@v4 + if: ${{ inputs.build-and-push-docker-image-wasm }} + + - uses: actions/setup-python@v5 + if: ${{ inputs.build-and-push-docker-image-wasm }} + with: + python-version: '3.10' + + - name: Install dependencies + if: ${{ inputs.build-and-push-docker-image-wasm }} + run: make python-install-deps + + - name: Determine Build arguments + if: ${{ inputs.build-and-push-docker-image-wasm }} + id: build-args + run: | + echo "version=$(scripts/get-libwasm-version.py --get-version)" >> $GITHUB_OUTPUT + echo "checksum=$(scripts/get-libwasm-version.py --get-checksum)" >> $GITHUB_OUTPUT + + - name: Log in to the Container registry + if: ${{ inputs.build-and-push-docker-image-wasm }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + if: ${{ inputs.build-and-push-docker-image-wasm }} + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME_WASM }} + + - name: Build and push Docker image + if: ${{ inputs.build-and-push-docker-image-wasm }} + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + file: modules/light-clients/08-wasm/Dockerfile + build-args: | + LIBWASM_VERSION=${{ steps.build-args.outputs.version }} + LIBWASM_CHECKSUM=${{ steps.build-args.outputs.checksum }} + + + # dynamically build a matrix of test/test suite pairs to run. + # this job runs a go tool located at cmd/build_test_matrix/main.go. + # it walks the e2e/test directory in order to locate all test suite / test name + # pairs. The output of this job can be fed in as input to a workflow matrix and + # will expand to jobs which will run all tests present. + build-test-matrix: + runs-on: depot-ubuntu-22.04-4 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + - id: set-matrix + run: | + output=$(go run cmd/build_test_matrix/main.go) + echo "matrix=$output" >> $GITHUB_OUTPUT + env: + TEST_ENTRYPOINT: '${{ inputs.test-entry-point }}' + TEST_EXCLUSIONS: '${{ inputs.test-exclusions }}' + TEST_NAME: '${{ inputs.test }}' + + # e2e-tests runs the actual go test command to trigger the test. + # the tests themselves are configured via environment variables to specify + # things like chain and relayer images and tags. + e2e-tests: + runs-on: depot-ubuntu-22.04-4 + needs: + - build-test-matrix + - docker-build + - docker-build-wasm + env: + CHAIN_IMAGE: '${{ inputs.chain-image }}' + CHAIN_UPGRADE_PLAN: '${{ inputs.upgrade-plan-name }}' + CHAIN_A_TAG: '${{ inputs.chain-a-tag }}' + CHAIN_B_TAG: '${{ inputs.chain-b-tag }}' + E2E_CONFIG_PATH: '${{ inputs.e2e-config-path }}' + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.build-test-matrix.outputs.matrix) }} + steps: + - uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache-dependency-path: 'e2e/go.sum' + - name: Run e2e Test + id: e2e_test + run: | + cd e2e + make e2e-test test=${{ matrix.test }} + - name: Upload Diagnostics + uses: actions/upload-artifact@v4 + if: ${{ failure() && inputs.upload-logs }} + continue-on-error: true + with: + name: '${{ matrix.entrypoint }}-${{ matrix.test }}' + path: e2e/diagnostics + retention-days: 5 + + e2e-test-suites: + # temporary flag. eventually this field will not exist and this will be the default. + if: ${{ inputs.temp-run-full-suite }} + runs-on: depot-ubuntu-22.04-4 + needs: + - build-test-matrix + - docker-build + - docker-build-wasm + env: + CHAIN_IMAGE: '${{ inputs.chain-image }}' + CHAIN_A_TAG: '${{ inputs.chain-a-tag }}' + CHAIN_B_TAG: '${{ inputs.chain-b-tag }}' + E2E_CONFIG_PATH: '${{ inputs.e2e-config-path }}' + strategy: + fail-fast: false + matrix: + include: + # for now we explicitly specify this test suite. + - entrypoint: TestTransferTestSuite + - entrypoint: TestAuthzTransferTestSuite + - entrypoint: TestTransferTestSuiteSendReceive + - entrypoint: TestTransferTestSuiteSendEnabled + - entrypoint: TestTransferLocalhostTestSuite + - entrypoint: TestConnectionTestSuite + - entrypoint: TestInterchainAccountsGovTestSuite + steps: + - uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache-dependency-path: 'e2e/go.sum' + - name: Run e2e Test + id: e2e_test + run: | + cd e2e + make e2e-suite entrypoint=${{ matrix.entrypoint }} + - name: Upload Diagnostics + uses: actions/upload-artifact@v4 + if: ${{ failure() && inputs.upload-logs }} + continue-on-error: true + with: + name: '${{ matrix.entrypoint }}-${{ matrix.test }}' + path: e2e/diagnostics + retention-days: 5 diff --git a/.github/workflows/e2e-upgrade.yaml b/.github/workflows/e2e-upgrade.yaml new file mode 100644 index 0000000..f4899dd --- /dev/null +++ b/.github/workflows/e2e-upgrade.yaml @@ -0,0 +1,82 @@ +name: Tests / E2E Upgrade +on: + workflow_dispatch: + pull_request: + branches: + - main + paths: + # upgrade tests will run on any changes to the upgrade_test.go file, + # and changes to the workflow itself. + - 'e2e/tests/upgrades/*.go' + - '.github/workflows/e2e-upgrade.yaml' + schedule: + - cron: '0 0 * * *' + +env: + DOCKER_IMAGE_NAME: ghcr.io/cosmos/ibc-go-simd + +jobs: + e2e-upgrade-tests: + runs-on: depot-ubuntu-22.04-4 + strategy: + fail-fast: false + matrix: + test-config: [ + { + tag: v6.1.0, + upgrade-plan: v7, + test: TestV6ToV7ChainUpgrade + }, + { + tag: v7.0.0, + upgrade-plan: v7.1, + test: TestV7ToV7_1ChainUpgrade + }, + { + tag: v7.10.0, + upgrade-plan: v8, + test: TestV7ToV8ChainUpgrade + }, + { + tag: v8.0.0, + upgrade-plan: v8.1, + test: TestV8ToV8_1ChainUpgrade + }, + { + tag: v8.7.0, + upgrade-plan: v10, + test: TestV8ToV10ChainUpgrade + }, + { + tag: v8.7.0, + upgrade-plan: v10, + test: TestV8ToV10ChainUpgrade_Localhost + }, + ] + steps: + - uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache-dependency-path: 'e2e/go.sum' + - name: Run e2e Test + id: e2e_test + env: + CHAIN_IMAGE: '${{ env.DOCKER_IMAGE_NAME }}' + CHAIN_A_TAG: "${{ matrix['test-config'].tag }}" + CHAIN_B_TAG: "${{ matrix['test-config'].tag }}" + CHAIN_UPGRADE_PLAN: "${{ matrix['test-config']['upgrade-plan'] }}" + E2E_CONFIG_PATH: 'ci-e2e-config.yaml' + run: | + cd e2e + make e2e-test test=${{ matrix['test-config'].test }} + - name: Upload Diagnostics + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + continue-on-error: true + with: + name: "${{ matrix['test-config'].test }}" + path: e2e/diagnostics + retention-days: 5 diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml new file mode 100644 index 0000000..a738fd3 --- /dev/null +++ b/.github/workflows/e2e.yaml @@ -0,0 +1,118 @@ +name: Tests / E2E +on: + workflow_dispatch: + pull_request: + paths: + - '**/*.go' + - '.github/workflows/e2e.yaml' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +env: + DOCKER_IMAGE_NAME: ghcr.io/cosmos/ibc-go-simd + +jobs: + determine-image-tag: + runs-on: depot-ubuntu-22.04-4 + outputs: + simd-tag: ${{ steps.get-tag.outputs.simd-tag }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + - id: get-tag + run: | + if [ -z "${{ github.event.pull_request.number }}" ] + then + echo "simd-tag=main" >> $GITHUB_OUTPUT + else + tag="pr-${{ github.event.pull_request.number }}" + echo "Using tag $tag" + echo "simd-tag=$tag" >> $GITHUB_OUTPUT + fi + + docker-build: + runs-on: depot-ubuntu-22.04-4 + permissions: + packages: write + contents: read + steps: + - uses: actions/checkout@v4 + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.DOCKER_IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + build-args: | + IBC_GO_VERSION=${{ github.ref_name }} + + build-test-matrix: + runs-on: depot-ubuntu-22.04-4 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache-dependency-path: 'go.sum' + - id: set-matrix + run: | + output=$(go run cmd/build_test_matrix/main.go) + echo "matrix=$output" >> $GITHUB_OUTPUT + env: + TEST_EXCLUSIONS: 'TestUpgradeTestSuite' + + e2e-tests: + runs-on: depot-ubuntu-22.04-4 + needs: + - determine-image-tag + - build-test-matrix + - docker-build + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.build-test-matrix.outputs.matrix) }} + steps: + - uses: actions/checkout@v4 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache-dependency-path: 'e2e/go.sum' + - name: Run e2e Test + id: e2e_test + env: + CHAIN_IMAGE: '${{ env.DOCKER_IMAGE_NAME }}' + CHAIN_A_TAG: '${{ needs.determine-image-tag.outputs.simd-tag }}' + CHAIN_B_TAG: '${{ needs.determine-image-tag.outputs.simd-tag }}' + E2E_CONFIG_PATH: 'ci-e2e-config.yaml' + run: | + cd e2e + make e2e-test test=${{ matrix.test }} + - name: Upload Diagnostics + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + continue-on-error: true + with: + name: '${{ matrix.entrypoint }}-${{ matrix.test }}' + path: e2e/diagnostics + retention-days: 5 diff --git a/.github/workflows/golangci.yml b/.github/workflows/golangci.yml new file mode 100644 index 0000000..a58ce6b --- /dev/null +++ b/.github/workflows/golangci.yml @@ -0,0 +1,31 @@ +name: golangci-lint +on: + push: + pull_request: +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + pull-requests: read + +jobs: + golangci: + name: lint + runs-on: depot-ubuntu-22.04-4 + strategy: + matrix: + working-directory: ['.', 'modules/light-clients/08-wasm', 'e2e'] + steps: + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: golangci-lint + uses: golangci/golangci-lint-action@v8.0.0 + with: + version: v2.1 + only-new-issues: true + args: --timeout 10m + working-directory: ${{ matrix.working-directory }} diff --git a/.github/workflows/proto-breaking-check.yml b/.github/workflows/proto-breaking-check.yml new file mode 100644 index 0000000..1ef5a81 --- /dev/null +++ b/.github/workflows/proto-breaking-check.yml @@ -0,0 +1,16 @@ +name: proto breaking check +# proto breaking check workflow checks if Protobuf file contains breaking changes. +# This workflow runs when a PR that targets Protobuf is opened. +on: + merge_group: + pull_request: + paths: + - "proto/**/*.proto" + +jobs: + proto-breaking-check: + runs-on: depot-ubuntu-22.04-4 + steps: + - uses: actions/checkout@v4 + - name: Run proto-breaking check + run: make proto-check-breaking \ No newline at end of file diff --git a/.github/workflows/proto-registry.yml b/.github/workflows/proto-registry.yml new file mode 100644 index 0000000..781978c --- /dev/null +++ b/.github/workflows/proto-registry.yml @@ -0,0 +1,28 @@ +name: Buf-Push +# Protobuf runs buf (https://buf.build/) push updated proto files to https://buf.build/cosmos/ibc +# This workflow is only run when a .proto file has been changed +on: + workflow_dispatch: + push: + branches: + - main + paths: + - "proto/**" + tags: + - 'v*.*.*' + +jobs: + push: + runs-on: depot-ubuntu-22.04-4 + steps: + - uses: actions/checkout@v4 + - uses: bufbuild/buf-action@v1 + with: + token: ${{ secrets.BUF_TOKEN }} + setup_only: false + github_token: ${{ secrets.GITHUB_TOKEN }} + input: "proto" + push: true + lint: false + format: false + breaking: false diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..133b99e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,86 @@ +name: Tests / Code Coverage +# Tests / Code Coverage workflow runs unit tests and uploads a code coverage report +# This workflow is run on pushes to main & every pull requests +on: + merge_group: + pull_request: + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: depot-ubuntu-22.04-4 + strategy: + matrix: + go-arch: ['amd64', 'arm64'] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + - name: Install compiler for arm64. + if: matrix.go-arch == 'arm64' + run: | + sudo apt-get update + sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu build-essential + echo "CC=aarch64-linux-gnu-gcc" >> $GITHUB_ENV + + - name: Build ibc-go + run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make build + + - name: Build 08-wasm + run: | + cd modules/light-clients/08-wasm + GOARCH=${{ matrix.go-arch }} CGO_ENABLED=1 go build ./... + + - name: Build e2e + run: | + cd e2e + find ./tests -type d | while IFS= read -r dir + do + if ls "${dir}"/*.go >/dev/null 2>&1; then + CGO_ENABLED=1 GOARCH=${{ matrix.go-arch }} go test -c "$dir" + fi + done + + unit-tests: + runs-on: depot-ubuntu-22.04-4 + strategy: + matrix: + module: [ + { + name: ibc-go, + path: . + }, + { + name: 08-wasm, + path: ./modules/light-clients/08-wasm + }, + { + name: e2e, + path: ./e2e, + additional-args: '-tags="test_e2e"' + } + ] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache-dependency-path: '${{ matrix.module.path }}/go.sum' + + - name: test & coverage report creation + run: | + cd ${{ matrix.module.path }} && go test -mod=readonly -coverprofile=profile.out -covermode=atomic ${{ matrix.module.additional-args }} ./... + + - uses: codecov/codecov-action@v5 + with: + fail_ci_if_error: true + files: ${{ matrix.module.path }}/profile.out + flags: ${{ matrix.module.name }} + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d3148b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build/ +*.test +*.bench +.DS_Store +*.log diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..8b06c71 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,139 @@ +version: "2" +run: + tests: true +linters: + default: none + enable: + - errcheck + - goconst + - gocritic + - gosec + - govet + - ineffassign + - misspell + - nakedret + - revive + - staticcheck + - thelper + - unconvert + - unparam + - unused + settings: + gocritic: + disabled-checks: + - appendAssign + gosec: + excludes: + - G101 + - G107 + - G115 + - G404 + confidence: medium + revive: + enable-all-rules: true + rules: + - name: redundant-import-alias + disabled: true + - name: use-any + disabled: true + - name: if-return + disabled: true + - name: max-public-structs + disabled: true + - name: cognitive-complexity + disabled: true + - name: argument-limit + disabled: true + - name: cyclomatic + disabled: true + - name: file-header + disabled: true + - name: function-length + disabled: true + - name: function-result-limit + disabled: true + - name: line-length-limit + disabled: true + - name: flag-parameter + disabled: true + - name: add-constant + disabled: true + - name: empty-lines + disabled: true + - name: banned-characters + disabled: true + - name: deep-exit + disabled: true + - name: confusing-results + disabled: true + - name: unused-parameter + disabled: true + - name: modifies-value-receiver + disabled: true + - name: early-return + disabled: true + - name: confusing-naming + disabled: true + - name: defer + disabled: true + - name: unused-parameter + disabled: true + - name: unhandled-error + arguments: + - fmt.Printf + - fmt.Print + - fmt.Println + - myFunction + disabled: false + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - revive + text: differs only by capitalization to method + - linters: + - gosec + text: Use of weak random number generator + - linters: + - gosec + text: 'G115: integer overflow conversion' + - linters: + - staticcheck + text: 'SA1019:' + - linters: + - gosec + text: 'G115: integer overflow conversion' + paths: + - third_party$ + - builtin$ + - examples$ +issues: + max-issues-per-linter: 10000 + max-same-issues: 10000 +formatters: + enable: + - gci + - gofumpt + settings: + gci: + sections: + - standard + - default + - blank + - dot + - prefix(cosmossdk.io) + - prefix(github.com/cosmos/cosmos-sdk) + - prefix(github.com/cometbft/cometbft) + - prefix(github.com/cosmos/ibc-go) + custom-order: true + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..4a570a8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,1829 @@ + + +# Changelog + +## [Unreleased] + +* [\#8573](https://github.com/cosmos/ibc-go/pull/8573) Support custom address codecs in transfer. + +## [v10.3.0](https://github.com/cosmos/ibc-go/releases/tag/v10.3.0) - 2025-06-06 + +### Features + +### Dependencies + +* [\#8369](https://github.com/cosmos/ibc-go/pull/8369) Bump **github.com/CosmWasm/wasmvm** to **2.2.4** +* [\#8369](https://github.com/cosmos/ibc-go/pull/8369) Bump **github.com/ethereum/go-ethereum** to **1.15.11** + +### API Breaking + +### State Machine Breaking + +### Improvements + +* (core/api) [\#8303](https://github.com/cosmos/ibc-go/pull/8303) Prefix-based routing in IBCv2 Router +- (apps/callbacks) [\#8353](https://github.com/cosmos/ibc-go/pull/8353) Add field in callbacks data for custom calldata + +### Bug Fixes + +### Testing API + +* [\#8371](https://github.com/cosmos/ibc-go/pull/8371) e2e: Create only necessary number of chains for e2e suite. +* [\#8375](https://github.com/cosmos/ibc-go/pull/8375) feat: parse IBC v2 packets from ABCI events + +## [v10.2.0](https://github.com/cosmos/ibc-go/releases/tag/v10.2.0) - 2025-04-30 + +### Features + +* (light-clients/07-tendermint) [\#8185](https://github.com/cosmos/ibc-go/pull/8185) Allow scaling of trusting period for client upgrades + +### Dependencies + +* [\#8254](https://github.com/cosmos/ibc-go/pull/8254) Bump **github.com/cosmos/cosmos-sdk** to **0.53.0** +* [\#8326](https://github.com/cosmos/ibc-go/pull/8329) Bump **cosmossdk.io/x/upgrade** to **0.2.0** +* [\#8326](https://github.com/cosmos/ibc-go/pull/8326) Bump **cosmossdk.io/api** to **0.9.2** +* [\#8293](https://github.com/cosmos/ibc-go/pull/8293) Bump **cosmossdk.io/math** to **1.5.3** +* [\#8254](https://github.com/cosmos/ibc-go/pull/8254) Bump **cosmossdk.io/core** to **0.11.3** +* [\#8254](https://github.com/cosmos/ibc-go/pull/8254) Bump **cosmossdk.io/store** to **1.1.2** +* [\#8254](https://github.com/cosmos/ibc-go/pull/8254) Bump **cosmossdk.io/x/tx** to **0.14.0** +* [\#8253](https://github.com/cosmos/ibc-go/pull/8253) Bump **cosmossdk.io/errors** to **1.0.2** +* [\#8253](https://github.com/cosmos/ibc-go/pull/8253) Bump **cosmossdk.io/log** to **1.5.1** +* [\#8253](https://github.com/cosmos/ibc-go/pull/8253) Bump **github.com/cometbft/cometbft** to **0.38.17** +* [\#8264](https://github.com/cosmos/ibc-go/pull/8264) Bump **github.com/prysmaticlabs/prysm** to **v5.3.0** + +### Bug Fixes + +* [\#8287](https://github.com/cosmos/ibc-go/pull/8287) rename total_escrow REST query from `denoms` to `total_escrow` + +## [v10.1.0](https://github.com/cosmos/ibc-go/releases/tag/v10.1.0) - 2025-03-14 + +### Security Fixes + +* Fix [ISA-2025-001](https://github.com/cosmos/ibc-go/security/advisories/GHSA-4wf3-5qj9-368v) security vulnerability. +* Fix [ASA-2025-004](https://github.com/cosmos/ibc-go/security/advisories/GHSA-jg6f-48ff-5xrw) security vulnerability. + +### Features + +* (core) [\#7505](https://github.com/cosmos/ibc-go/pull/7505) Add IBC Eureka (IBC v2) implementation, enabling more efficient IBC packet handling without channel dependencies, bringing significant performance improvements. +* (apps/transfer) [\#7650](https://github.com/cosmos/ibc-go/pull/7650) Add support for transfer of entire balance for vesting accounts. +* (apps/wasm) [\#5079](https://github.com/cosmos/ibc-go/pull/5079) 08-wasm light client proxy module for wasm clients by. +* (core/02-client) [\#7936](https://github.com/cosmos/ibc-go/pull/7936) Clientv2 module. +* (core/04-channel) [\#7933](https://github.com/cosmos/ibc-go/pull/7933) Channel-v2 genesis. +* (core/04-channel, core/api) [\#7934](https://github.com/cosmos/ibc-go/pull/7934) - Callbacks Eureka. +* (light-clients/09-localhost) [\#6683](https://github.com/cosmos/ibc-go/pull/6683) Make 09-localhost stateless. +* (core, app) [\#6902](https://github.com/cosmos/ibc-go/pull/6902) Add channel version to core app callbacks. + +### Dependencies + +* [\#8181](https://github.com/cosmos/ibc-go/pull/8181) Bump **github.com/cosmos/cosmos-sdk** to **0.50.13** +* [\#7932](https://github.com/cosmos/ibc-go/pull/7932) Bump **go** to **1.23** +* [\#7330](https://github.com/cosmos/ibc-go/pull/7330) Bump **cosmossdk.io/api** to **0.7.6** +* [\#6828](https://github.com/cosmos/ibc-go/pull/6828) Bump **cosmossdk.io/core** to **0.11.1** +* [\#7182](https://github.com/cosmos/ibc-go/pull/7182) Bump **cosmossdk.io/log** to **1.4.1** +* [\#7264](https://github.com/cosmos/ibc-go/pull/7264) Bump **cosmossdk.io/store** to **1.1.1** +* [\#7585](https://github.com/cosmos/ibc-go/pull/7585) Bump **cosmossdk.io/math** to **1.4.0** +* [\#7540](https://github.com/cosmos/ibc-go/pull/7540) Bump **github.com/cometbft/cometbft** to **0.38.15** +* [\#6828](https://github.com/cosmos/ibc-go/pull/6828) Bump **cosmossdk.io/x/upgrade** to **0.1.4** +* [\#8124](https://github.com/cosmos/ibc-go/pull/8124) Bump **cosmossdk.io/x/tx** to **0.13.7** +* [\#7942](https://github.com/cosmos/ibc-go/pull/7942) Bump **github.com/cosmos/cosmos-db** to **1.1.1** +* [\#7224](https://github.com/cosmos/ibc-go/pull/7224) Bump **github.com/cosmos/ics23/go** to **0.11.0** + +### API Breaking + +* (core, apps) [\#7213](https://github.com/cosmos/ibc-go/pull/7213) Remove capabilities from `SendPacket`. +* (core, apps) [\#7225](https://github.com/cosmos/ibc-go/pull/7225) Remove capabilities from `WriteAcknowledgement`. +* (core, apps) [\#7232](https://github.com/cosmos/ibc-go/pull/7232) Remove capabilities from channel handshake methods. +* (core, apps) [\#7270](https://github.com/cosmos/ibc-go/pull/7270) Remove remaining dependencies on capability module. +* (core, apps) [\#4811](https://github.com/cosmos/ibc-go/pull/4811) Use expected interface for legacy params subspace +* (core/04-channel) [\#7239](https://github.com/cosmos/ibc-go/pull/7239) Removed function `LookupModuleByChannel` +* (core/05-port) [\#7252](https://github.com/cosmos/ibc-go/pull/7252) Removed function `LookupModuleByPort` +* (core/24-host) [\#7239](https://github.com/cosmos/ibc-go/pull/7239) Removed function `ChannelCapabilityPath` +* (apps/27-interchain-accounts) [\#7239](https://github.com/cosmos/ibc-go/pull/7239) The following functions have been removed: `AuthenticateCapability`, `ClaimCapability` +* (apps/27-interchain-accounts) [\#7961](https://github.com/cosmos/ibc-go/pull/7961) Removed `absolute-timeouts` flag from `send-tx` in the ICA CLI. +* (apps/transfer) [\#7239](https://github.com/cosmos/ibc-go/pull/7239) The following functions have been removed: `BindPort`, `AuthenticateCapability`, `ClaimCapability` +* (capability) [\#7279](https://github.com/cosmos/ibc-go/pull/7279) The module `capability` has been removed. +* (testing) [\#7305](https://github.com/cosmos/ibc-go/pull/7305) Added `TrustedValidators` map to `TestChain`. This removes the dependency on the `x/staking` module for retrieving trusted validator sets at a given height, and removes the `GetTrustedValidators` method from the `TestChain` struct. +* (23-commitment) [\#7486](https://github.com/cosmos/ibc-go/pull/7486) Remove unimplemented `BatchVerifyMembership` and `BatchVerifyNonMembership` functions +* (core/02-client, light-clients) [\#5806](https://github.com/cosmos/ibc-go/pull/5806) Decouple light client routing from their encoding structure. +* (core/04-channel) [\#5991](https://github.com/cosmos/ibc-go/pull/5991) The client CLI `QueryLatestConsensusState` has been removed. +* (light-clients/06-solomachine) [\#6037](https://github.com/cosmos/ibc-go/pull/6037) Remove `Initialize` function from `ClientState` and move logic to `Initialize` function of `LightClientModule`. +* (light-clients/06-solomachine) [\#6230](https://github.com/cosmos/ibc-go/pull/6230) Remove `GetTimestampAtHeight`, `Status` and `UpdateStateOnMisbehaviour` functions from `ClientState` and move logic to functions of `LightClientModule`. +* (core/02-client) [\#6084](https://github.com/cosmos/ibc-go/pull/6084) Removed `stakingKeeper` as an argument to `NewKeeper` and replaced with a `ConsensusHost` implementation. +* (testing) [\#6070](https://github.com/cosmos/ibc-go/pull/6070) Remove `AssertEventsLegacy` function. +* (core) [\#6138](https://github.com/cosmos/ibc-go/pull/6138) Remove `Router` reference from IBC core keeper and use instead the router on the existing `PortKeeper` reference. +* (core/04-channel) [\#6023](https://github.com/cosmos/ibc-go/pull/6023) Remove emission of non-hexlified event attributes `packet_data` and `packet_ack`. +* (core) [\#6320](https://github.com/cosmos/ibc-go/pull/6320) Remove unnecessary `Proof` interface from `exported` package. +* (core/05-port) [\#6341](https://github.com/cosmos/ibc-go/pull/6341) Modify `UnmarshalPacketData` interface to take in the context, portID, and channelID. This allows for packet data's to be unmarshaled based on the channel version. +* (apps/27-interchain-accounts) [\#6433](https://github.com/cosmos/ibc-go/pull/6433) Use UNORDERED as the default ordering for new ICA channels. +* (apps/transfer) [\#6440](https://github.com/cosmos/ibc-go/pull/6440) Remove `GetPrefixedDenom`. +* (apps/transfer) [\#6508](https://github.com/cosmos/ibc-go/pull/6508) Remove the `DenomTrace` type. +* (apps/27-interchain-accounts) [\#6598](https://github.com/cosmos/ibc-go/pull/6598) Mark the `requests` repeated field of `MsgModuleQuerySafe` non-nullable. +* (23-commmitment) [\#6644](https://github.com/cosmos/ibc-go/pull/6644) Introduce `commitment.v2.MerklePath` to include `repeated bytes` in favour of `repeated string`. This supports using merkle path keys which include non UTF-8 encoded runes. +* (23-commmitment) [\#6870](https://github.com/cosmos/ibc-go/pull/6870) Remove `commitment.v1.MerklePath` in favour of `commitment.v2.MerklePath`. +* (apps/27-interchain-accounts) [\#6749](https://github.com/cosmos/ibc-go/pull/6749) The ICA controller `NewIBCMiddleware` constructor function sets by default the auth module to nil. +* (core, core/02-client) [\#6763](https://github.com/cosmos/ibc-go/pull/6763) Move prometheus metric labels for 02-client and core into a separate `metrics` package on core. +* (core/02-client) [\#6777](https://github.com/cosmos/ibc-go/pull/6777) The `NewClientProposalHandler` of `02-client` has been removed. +* (core/types) [\#6794](https://github.com/cosmos/ibc-go/pull/6794) The composite interface `QueryServer` has been removed from package `core/types`. Please use the granular `QueryServer` interfaces provided by each core submodule. +* (light-clients/06-solomachine) [\#6888](https://github.com/cosmos/ibc-go/pull/6888) Remove `TypeClientMisbehaviour` constant and the `Type` method on `Misbehaviour`. +* (light-clients/06-solomachine, light-clients/07-tendermint) [\#6891](https://github.com/cosmos/ibc-go/pull/6891) The `VerifyMembership` and `VerifyNonMembership` functions of solomachine's `ClientState` have been made private. The `VerifyMembership`, `VerifyNonMembership`, `GetTimestampAtHeight`, `Status` and `Initialize` functions of tendermint's `ClientState` have been made private. +* (core/04-channel) [\#6902](https://github.com/cosmos/ibc-go/pull/6902) Add channel version to core application callbacks. +* (core/03-connection, core/02-client) [\#6937](https://github.com/cosmos/ibc-go/pull/6937) Remove 'ConsensusHost' interface, also removing self client and consensus state validation in the connection handshake. +* (core/24-host) [\#6882](https://github.com/cosmos/ibc-go/issues/6882) All functions ending in `Path` have been removed from 24-host in favour of their sybling functions ending in `Key`. +* (23-commmitment) [\#6633](https://github.com/cosmos/ibc-go/pull/6633) MerklePath has been changed to use `repeated bytes` in favour of `repeated strings`. +* (23-commmitment) [\#6644](https://github.com/cosmos/ibc-go/pull/6644) Introduce `commitment.v2.MerklePath` to include `repeated bytes` in favour of `repeated string`. This supports using merkle path keys which include non UTF-8 encoded runes. +* (23-commmitment) [\#6870](https://github.com/cosmos/ibc-go/pull/6870) Remove `commitment.v1.MerklePath` in favour of `commitment.v2.MerklePath`. +* [\#6923](https://github.com/cosmos/ibc-go/pull/6923) The JSON msg API for `VerifyMembershipMsg` and `VerifyNonMembershipMsg` payloads for client contract `SudoMsg` has been updated. The field `path` has been changed to `merkle_path`. This change requires updates to 08-wasm client contracts for integration. +* (apps/callbacks) [\#7000](https://github.com/cosmos/ibc-go/pull/7000) Add base application version to contract keeper callbacks. +* (light-clients/08-wasm) [\#5154](https://github.com/cosmos/ibc-go/pull/5154) Use bytes in wasm contract api instead of wrapped. +* (core, core/08-wasm) [\#5397](https://github.com/cosmos/ibc-go/pull/5397) Add coordinator Setup functions to the Path type. +* (core/05-port) [\#6341](https://github.com/cosmos/ibc-go/pull/6341) Modify `UnmarshalPacketData` interface to take in the context, portID, and channelID. This allows for packet data's to be unmarshaled based on the channel version. +* (core/02-client) [\#6863](https://github.com/cosmos/ibc-go/pull/6863) remove ClientStoreProvider interface in favour of concrete type. +* (core/05-port) [\#6988](https://github.com/cosmos/ibc-go/pull/6988) Modify `UnmarshalPacketData` interface to return the underlying application version. +* (apps/27-interchain-accounts) [\#7053](https://github.com/cosmos/ibc-go/pull/7053) Remove ICS27 channel capability migration introduced in v6. +* (apps/27-interchain-accounts) [\#8002](https://github.com/cosmos/ibc-go/issues/8002) Remove ICS-29: fee middleware. +* (core/04-channel) [\#8053](https://github.com/cosmos/ibc-go/issues/8053) Remove channel upgradability. + +### State Machine Breaking + +* (light-clients/06-solomachine) [\#6313](https://github.com/cosmos/ibc-go/pull/6313) Fix: No-op to avoid panicking on `UpdateState` for invalid misbehaviour submissions. +* (apps/callbacks) [\#8014](https://github.com/cosmos/ibc-go/pull/8014) Callbacks will now return an error acknowledgement if the recvPacket callback fails. This reverts all app callback changes whereas before we only reverted the callback changes. We also error on all callbacks if the callback data is set but malformed whereas before we ignored the error and continued processing. +* (apps/callbacks) [\#5349](https://github.com/cosmos/ibc-go/pull/5349) Check if clients params are duplicates. +* (apps/transfer) [\#6268](https://github.com/cosmos/ibc-go/pull/6268) Use memo strings instead of JSON keys in `AllowedPacketData` of transfer authorization. +* (light-clients/07-tendermint) Fix: No-op to avoid panicking on `UpdateState` for invalid misbehaviour submissions. +* (light-clients/06-solomachine) [\#6313](https://github.com/cosmos/ibc-go/pull/6313) Fix: No-op to avoid panicking on `UpdateState` for invalid misbehaviour submissions. + +### Improvements + +* (testing)[\#7430](https://github.com/cosmos/ibc-go/pull/7430) Update the block proposer in test chains for each block. +* (apps/27-interchain-accounts) [\#5533](https://github.com/cosmos/ibc-go/pull/5533) ICA host sets the host connection ID on `OnChanOpenTry`, so that ICA controller implementations are not obliged to set the value on `OnChanOpenInit` if they are not able. +* (core/02-client, core/03-connection, apps/27-interchain-accounts) [\#6256](https://github.com/cosmos/ibc-go/pull/6256) Add length checking of array fields in messages. +* (light-clients/08-wasm) [\#5146](https://github.com/cosmos/ibc-go/pull/5146) Use global wasm VM instead of keeping an additional reference in keeper. +* (core/04-channels) [\#7935](https://github.com/cosmos/ibc-go/pull/7935) Limit payload size for both v1 and v2 packet. +* (core/runtime) [\#7601](https://github.com/cosmos/ibc-go/pull/7601) - IBC core runtime env. +* (core/08-wasm) [\#5294](https://github.com/cosmos/ibc-go/pull/5294) Don't panic during any store operations. +* (apps) [\#5305](https://github.com/cosmos/ibc-go/pull/5305)- Remove GetSigners from `sdk.Msg` implementations. +* (apps) [\#/5778](https://github.com/cosmos/ibc-go/pull/5778) Use json for marshalling/unmarshalling transfer packet data. +* (core/08-wasm) [\#5785](https://github.com/cosmos/ibc-go/pull/5785) Allow module safe queries in ICA. +* (core/ante) [\#6278](https://github.com/cosmos/ibc-go/pull/6278) Performance: Exclude pruning from tendermint client updates in ante handler executions. +* (core/ante) [\#6302](https://github.com/cosmos/ibc-go/pull/6302) Performance: Skip app callbacks during RecvPacket execution in checkTx within the redundant relay ante handler. +* (core/ante) [\#6280](https://github.com/cosmos/ibc-go/pull/6280) Performance: Skip redundant proof checking in RecvPacket execution in reCheckTx within the redundant relay ante handler. +* [\#6716](https://github.com/cosmos/ibc-go/pull/6716) Add `HasModule` to capability keeper to allow checking if a scoped module already exists. + +### Bug Fixes + +* (apps/27-interchain-accounts) [\#7277](https://github.com/cosmos/ibc-go/pull/7277) Use `GogoResolver` when populating module query safe allow list to avoid panics from unresolvable protobuf dependencies. +* (core/04-channel) [\#7342](https://github.com/cosmos/ibc-go/pull/7342) Read Tx cmd flags including from address to avoid Address cannot be empty error when upgrade-channels via cli. +* (core/03-connection) [\#7397](https://github.com/cosmos/ibc-go/pull/7397) Skip the genesis validation connectionID for localhost client. +* (apps/27-interchain-accounts) [\#6377](https://github.com/cosmos/ibc-go/pull/6377) Generate ICA simtest proposals only for provided keepers. + +### Testing API + +* [\#7688](https://github.com/cosmos/ibc-go/pull/7688) Added `SendMsgsWithSender` to `TestChain`. +* [\#7430](https://github.com/cosmos/ibc-go/pull/7430) Update block proposer in testing +* [\#5493](https://github.com/cosmos/ibc-go/pull/5493) Add IBCClientHeader func for endpoint and update tests +* [\#6685](https://github.com/cosmos/ibc-go/pull/6685) Configure relayers to watch only channels associated with an individual test +* [\#6758](https://github.com/cosmos/ibc-go/pull/6758) Tokens are successfully forwarded from A to C through B + +## [v8.5.0](https://github.com/cosmos/ibc-go/releases/tag/v8.5.0) - 2024-08-30 + +### Dependencies + +* [\#6828](https://github.com/cosmos/ibc-go/pull/6828) Bump Cosmos SDK to v0.50.9. +* [\#7222](https://github.com/cosmos/ibc-go/pull/7221) Update ics23 to v0.11.0. + +### State Machine Breaking + +* (core/03-connection) [\#7129](https://github.com/cosmos/ibc-go/pull/7129) Remove verification of self client and consensus state from connection handshake. + +## [v8.4.0](https://github.com/cosmos/ibc-go/releases/tag/v8.4.0) - 2024-07-29 + +### Improvements + +* (core/04-channel) [\#6871](https://github.com/cosmos/ibc-go/pull/6871) Add channel ordering to write acknowledgement event. + +### Features + +* (apps/transfer) [\#6877](https://github.com/cosmos/ibc-go/pull/6877) Added the possibility to transfer the entire user balance of a particular denomination by using [`UnboundedSpendLimit`](https://github.com/cosmos/ibc-go/blob/beb2d93b58835ddb9ed8e7624988f1e66b849251/modules/apps/transfer/types/token.go#L56-L58) as the token amount. + +### Bug Fixes + +* (core/04-channel) [\#6935](https://github.com/cosmos/ibc-go/pull/6935) Check upgrade compatibility in `ChanUpgradeConfirm`. + +## [v8.3.2](https://github.com/cosmos/ibc-go/releases/tag/v8.3.2) - 2024-06-20 + +### Dependencies + +* [\#6614](https://github.com/cosmos/ibc-go/pull/6614) Bump Cosmos SDK to v0.50.7. + +### Improvements + +* (apps/27-interchain-accounts) [\#6436](https://github.com/cosmos/ibc-go/pull/6436) Refactor ICA host keeper instantiation method to avoid panic related to proto files. + +## [v8.3.1](https://github.com/cosmos/ibc-go/releases/tag/v8.3.1) - 2024-05-22 + +### Improvements + +* (core/ante) [\#6302](https://github.com/cosmos/ibc-go/pull/6302) Performance: Skip app callbacks during RecvPacket execution in checkTx within the redundant relay ante handler. +* (core/ante) [\#6280](https://github.com/cosmos/ibc-go/pull/6280) Performance: Skip redundant proof checking in RecvPacket execution in reCheckTx within the redundant relay ante handler. +* (core/ante) [\#6306](https://github.com/cosmos/ibc-go/pull/6306) Performance: Skip misbehaviour checks in UpdateClient flow and skip signature checks in reCheckTx mode. + +## [v8.3.0](https://github.com/cosmos/ibc-go/releases/tag/v8.3.0) - 2024-05-16 + +### Dependencies + +* [\#6300](https://github.com/cosmos/ibc-go/pull/6300) Bump Cosmos SDK to v0.50.6 and CometBFT to v0.38.7. + +### State Machine Breaking + +* (light-clients/07-tendermint) [\#6276](https://github.com/cosmos/ibc-go/pull/6276) Fix: No-op to avoid panicking on `UpdateState` for invalid misbehaviour submissions. + +### Improvements + +* (apps/27-interchain-accounts, apps/transfer, apps/29-fee) [\#6253](https://github.com/cosmos/ibc-go/pull/6253) Allow channel handshake to succeed if fee middleware is wired up on one side, but not the other. +* (apps/27-interchain-accounts) [\#6251](https://github.com/cosmos/ibc-go/pull/6251) Use `UNORDERED` as the default ordering for new ICA channels. +* (apps/transfer) [\#6268](https://github.com/cosmos/ibc-go/pull/6268) Use memo strings instead of JSON keys in `AllowedPacketData` of transfer authorization. +* (core/ante) [\#6278](https://github.com/cosmos/ibc-go/pull/6278) Performance: Exclude pruning from tendermint client updates in ante handler executions. +* (core/ante) [\#6302](https://github.com/cosmos/ibc-go/pull/6302) Performance: Skip app callbacks during RecvPacket execution in checkTx within the redundant relay ante handler. +* (core/ante) [\#6280](https://github.com/cosmos/ibc-go/pull/6280) Performance: Skip redundant proof checking in RecvPacket execution in reCheckTx within the redundant relay ante handler. + +### Features + +* (core) [\#6055](https://github.com/cosmos/ibc-go/pull/6055) Introduce a new interface `ConsensusHost` used to validate an IBC `ClientState` and `ConsensusState` against the host chain's underlying consensus parameters. +* (core/02-client) [\#5821](https://github.com/cosmos/ibc-go/pull/5821) Add rpc `VerifyMembershipProof` (querier approach for conditional clients). +* (core/04-channel) [\#5788](https://github.com/cosmos/ibc-go/pull/5788) Add `NewErrorAcknowledgementWithCodespace` to allow codespaces in ack errors. +* (apps/27-interchain-accounts) [\#5785](https://github.com/cosmos/ibc-go/pull/5785) Introduce a new tx message that ICA host submodule can use to query the chain (only those marked with `module_query_safe`) and write the responses to the acknowledgement. + +### Bug Fixes + +* (apps/27-interchain-accounts) [\#6167](https://github.com/cosmos/ibc-go/pull/6167) Fixed an edge case bug where migrating params for a pre-existing ica module which implemented controller functionality only could panic when migrating params for newly added host, and align controller param migration with host. +* (app/29-fee) [\#6255](https://github.com/cosmos/ibc-go/pull/6255) Delete refunded fees from state if some fee(s) cannot be refunded on channel closure. + +## [v8.2.0](https://github.com/cosmos/ibc-go/releases/tag/v8.2.0) - 2024-04-05 + +### Dependencies + +* [\#5975](https://github.com/cosmos/ibc-go/pull/5975) Bump Cosmos SDK to v0.50.5. + +### Improvements + +* (proto) [\#5987](https://github.com/cosmos/ibc-go/pull/5987) Add wasm proto files. + +## [v8.1.0](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0) - 2024-01-31 + +### Dependencies + +* [\#5663](https://github.com/cosmos/ibc-go/pull/5663) Bump Cosmos SDK to v0.50.3 and CometBFT to v0.38.2. + +### State Machine Breaking + +* (apps/27-interchain-accounts) [\#5442](https://github.com/cosmos/ibc-go/pull/5442) Increase the maximum allowed length for the memo field of `InterchainAccountPacketData`. + +### Improvements + +* (core/02-client) [\#5429](https://github.com/cosmos/ibc-go/pull/5429) Add wildcard `"*"` to allow all clients in `AllowedClients` param. +* (core) [\#5541](https://github.com/cosmos/ibc-go/pull/5541) Enable emission of events on erroneous IBC application callbacks by appending a prefix to all event type and attribute keys. + +### Features + +* (core/04-channel) [\#1613](https://github.com/cosmos/ibc-go/pull/1613) Channel upgradability. +* (apps/transfer) [\#5280](https://github.com/cosmos/ibc-go/pull/5280) Add list of allowed packet data keys to `Allocation` of `TransferAuthorization`. +* (apps/27-interchain-accounts) [\#5633](https://github.com/cosmos/ibc-go/pull/5633) Allow setting new and upgrading existing ICA (ordered) channels to use unordered ordering. + +### Bug Fixes + +* (apps/27-interchain-accounts) [\#5343](https://github.com/cosmos/ibc-go/pull/5343) Add check if controller is enabled in `sendTx` before sending packet to host. +* (apps/29-fee) [\#5441](https://github.com/cosmos/ibc-go/pull/5441) Allow setting the relayer address as payee. + +## [v8.0.1](https://github.com/cosmos/ibc-go/releases/tag/v8.0.1) - 2024-01-31 + +### Dependencies + +* [\#5718](https://github.com/cosmos/ibc-go/pull/5718) Update Cosmos SDK to v0.50.3 and CometBFT to v0.38.2. + +### Improvements + +* (core) [\#5541](https://github.com/cosmos/ibc-go/pull/5541) Enable emission of events on erroneous IBC application callbacks by appending a prefix to all event type and attribute keys. + +## [v8.0.0](https://github.com/cosmos/ibc-go/releases/tag/v8.0.0) - 2023-11-10 + +### Dependencies + +* [\#5038](https://github.com/cosmos/ibc-go/pull/5038) Bump SDK v0.50.1 and cometBFT v0.38. +* [\#4398](https://github.com/cosmos/ibc-go/pull/4398) Update all modules to go 1.21. + +### API Breaking + +* (core) [\#4703](https://github.com/cosmos/ibc-go/pull/4703) Make `PortKeeper` field of `IBCKeeper` a pointer. +* (core/23-commitment) [\#4459](https://github.com/cosmos/ibc-go/pull/4459) Remove `Pretty` and `String` custom implementations of `MerklePath`. +* [\#3205](https://github.com/cosmos/ibc-go/pull/3205) Make event emission functions unexported. +* (apps/27-interchain-accounts, apps/transfer) [\#3253](https://github.com/cosmos/ibc-go/pull/3253) Rename `IsBound` to `HasCapability`. +* (apps/27-interchain-accounts, apps/transfer) [\#3303](https://github.com/cosmos/ibc-go/pull/3303) Make `HasCapability` private. +* [\#3303](https://github.com/cosmos/ibc-go/pull/3856) Add missing/remove unnecessary gogoproto directive. +* (apps/27-interchain-accounts) [\#3967](https://github.com/cosmos/ibc-go/pull/3967) Add encoding type as argument to ICA encoding/decoding functions. +* (core) [\#3867](https://github.com/cosmos/ibc-go/pull/3867) Remove unnecessary event attribute from INIT handshake msgs. +* (core/04-channel) [\#3806](https://github.com/cosmos/ibc-go/pull/3806) Remove unused `EventTypeTimeoutPacketOnClose`. +* (testing) [\#4018](https://github.com/cosmos/ibc-go/pull/4018) Allow failure expectations when using `chain.SendMsgs`. + +### State Machine Breaking + +* (apps/transfer, apps/27-interchain-accounts, app/29-fee) [\#4992](https://github.com/cosmos/ibc-go/pull/4992) Set validation for length of string fields. + +### Improvements + +* [\#3304](https://github.com/cosmos/ibc-go/pull/3304) Remove unnecessary defer func statements. +* (apps/29-fee) [\#3054](https://github.com/cosmos/ibc-go/pull/3054) Add page result to ics29-fee queries. +* (apps/27-interchain-accounts, apps/transfer) [\#3077](https://github.com/cosmos/ibc-go/pull/3077) Add debug level logging for the error message which is discarded when generating a failed acknowledgement. +* (core/03-connection) [\#3244](https://github.com/cosmos/ibc-go/pull/3244) Cleanup 03-connection msg validate basic test. +* (core/02-client) [\#3514](https://github.com/cosmos/ibc-go/pull/3514) Add check for the client status in `CreateClient`. +* (apps/29-fee) [\#4100](https://github.com/cosmos/ibc-go/pull/4100) Adding `MetadataFromVersion` to `29-fee` package `types`. +* (apps/29-fee) [\#4290](https://github.com/cosmos/ibc-go/pull/4290) Use `types.MetadataFromVersion` helper function for callback handlers. +* (core/04-channel) [\#4155](https://github.com/cosmos/ibc-go/pull/4155) Adding `IsOpen` and `IsClosed` methods to `Channel` type. +* (core/03-connection) [\#4110](https://github.com/cosmos/ibc-go/pull/4110) Remove `Version` interface and casting functions from 03-connection. +* (core) [\#4835](https://github.com/cosmos/ibc-go/pull/4835) Use expected interface for legacy params subspace parameter of keeper constructor functions. + +### Features + +* (capability) [\#3097](https://github.com/cosmos/ibc-go/pull/3097) Migrate capability module from Cosmos SDK to ibc-go. +* (core/02-client) [\#3640](https://github.com/cosmos/ibc-go/pull/3640) Migrate client params to be self managed. +* (core/03-connection) [\#3650](https://github.com/cosmos/ibc-go/pull/3650) Migrate connection params to be self managed. +* (apps/transfer) [\#3553](https://github.com/cosmos/ibc-go/pull/3553) Migrate transfer parameters to be self managed (#3553) +* (apps/27-interchain-accounts) [\#3520](https://github.com/cosmos/ibc-go/pull/3590) Migrate ica/controller parameters to be self managed (#3590) +* (apps/27-interchain-accounts) [\#3520](https://github.com/cosmos/ibc-go/pull/3520) Migrate ica/host to params to be self managed. +* (apps/transfer) [\#3104](https://github.com/cosmos/ibc-go/pull/3104) Add metadata for IBC tokens. +* [\#4620](https://github.com/cosmos/ibc-go/pull/4620) Migrate to gov v1 via the additions of `MsgRecoverClient` and `MsgIBCSoftwareUpgrade`. The legacy proposal types `ClientUpdateProposal` and `UpgradeProposal` have been deprecated and will be removed in the next major release. + +### Bug Fixes + +* (apps/transfer) [\#4709](https://github.com/cosmos/ibc-go/pull/4709) Order query service RPCs to fix availability of denom traces endpoint when no args are provided. +* (core/04-channel) [\#3357](https://github.com/cosmos/ibc-go/pull/3357) Handle unordered channels in `NextSequenceReceive` query. +* (e2e) [\#3402](https://github.com/cosmos/ibc-go/pull/3402) Allow retries for messages signed by relayer. +* (core/04-channel) [\#3417](https://github.com/cosmos/ibc-go/pull/3417) Add missing query for next sequence send. +* (testing) [\#4630](https://github.com/cosmos/ibc-go/pull/4630) Update `testconfig` to use revision formatted chain IDs. +* (core/04-channel) [\#4706](https://github.com/cosmos/ibc-go/pull/4706) Retrieve correct next send sequence for packets in unordered channels. +* (core/02-client) [\#4746](https://github.com/cosmos/ibc-go/pull/4746) Register implementations against `govtypes.Content` interface. +* (apps/27-interchain-accounts) [\#4944](https://github.com/cosmos/ibc-go/pull/4944) Add missing proto interface registration. +* (core/02-client) [\#5020](https://github.com/cosmos/ibc-go/pull/5020) Fix expect pointer error when unmarshalling misbehaviour file. + +### Documentation + +* [\#3133](https://github.com/cosmos/ibc-go/pull/3133) Add linter for markdown documents. +* [\#4693](https://github.com/cosmos/ibc-go/pull/4693) Migrate docs to docusaurus. + +### Testing + +* [\#3138](https://github.com/cosmos/ibc-go/pull/3138) Use `testing.TB` instead of `testing.T` to support benchmarks and fuzz tests. +* [\#3980](https://github.com/cosmos/ibc-go/pull/3980) Change `sdk.Events` usage to `[]abci.Event` in the testing package. +* [\#3986](https://github.com/cosmos/ibc-go/pull/3986) Add function `RelayPacketWithResults`. +* [\#4182](https://github.com/cosmos/ibc-go/pull/4182) Return current validator set when requesting current height in `GetValsAtHeight`. +* [\#4319](https://github.com/cosmos/ibc-go/pull/4319) Fix in `TimeoutPacket` function to use counterparty `portID`/`channelID` in `GetNextSequenceRecv` query. +* [\#4180](https://github.com/cosmos/ibc-go/pull/4180) Remove unused function `simapp.SetupWithGenesisAccounts`. + +### Miscellaneous Tasks + +* (apps/27-interchain-accounts) [\#4677](https://github.com/cosmos/ibc-go/pull/4677) Remove ica store key. +* [\#4724](https://github.com/cosmos/ibc-go/pull/4724) Add `HasValidateBasic` compiler assertions to messages. +* [\#4725](https://github.com/cosmos/ibc-go/pull/4725) Add fzf selection for config files. +* [\#4741](https://github.com/cosmos/ibc-go/pull/4741) Panic with error. +* [\#3186](https://github.com/cosmos/ibc-go/pull/3186) Migrate all SDK errors to the new errors go module. +* [\#3216](https://github.com/cosmos/ibc-go/pull/3216) Modify `simapp` to fulfill the SDK `runtime.AppI` interface. +* [\#3290](https://github.com/cosmos/ibc-go/pull/3290) Remove `gogoproto` yaml tags from proto files. +* [\#3439](https://github.com/cosmos/ibc-go/pull/3439) Use nil pointer pattern to check for interface compliance. +* [\#3433](https://github.com/cosmos/ibc-go/pull/3433) Add tests for `acknowledgement.Acknowledgement()`. +* (core, apps/29-fee) [\#3462](https://github.com/cosmos/ibc-go/pull/3462) Add missing `nil` check and corresponding tests for query handlers. +* (light-clients/07-tendermint, light-clients/06-solomachine) [\#3571](https://github.com/cosmos/ibc-go/pull/3571) Delete unused `GetProofSpecs` functions. +* (core) [\#3616](https://github.com/cosmos/ibc-go/pull/3616) Add debug log for redundant relay. +* (core) [\#3892](https://github.com/cosmos/ibc-go/pull/3892) Add deprecated option to `create_localhost` field. +* (core) [\#3893](https://github.com/cosmos/ibc-go/pull/3893) Add deprecated option to `MsgSubmitMisbehaviour`. +* (apps/transfer, apps/29-fee) [\#4570](https://github.com/cosmos/ibc-go/pull/4570) Remove `GetSignBytes` from 29-fee and transfer msgs. +* [\#3630](https://github.com/cosmos/ibc-go/pull/3630) Add annotation to Msg service. + +## [v7.8.0](https://github.com/cosmos/ibc-go/releases/tag/v7.8.0) - 2024-08-30 + +### State Machine Breaking + +* (core/03-connection) [\#7128](https://github.com/cosmos/ibc-go/pull/7128) Remove verification of self client and consensus state from connection handshake. + +## [v7.7.0](https://github.com/cosmos/ibc-go/releases/tag/v7.7.0) - 2024-07-29 + +### Dependencies + +* [\#6943](https://github.com/cosmos/ibc-go/pull/6943) Update Cosmos SDK to v0.47.13. + +### Features + +* (apps/transfer) [\#6877](https://github.com/cosmos/ibc-go/pull/6877) Added the possibility to transfer the entire user balance of a particular denomination by using [`UnboundedSpendLimit`](https://github.com/cosmos/ibc-go/blob/715f00eef8727da41db25fdd4763b709bdbba07e/modules/apps/transfer/types/transfer_authorization.go#L253-L255) as the token amount. + +### Bug Fixes + +## [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0) - 2024-06-20 + +### State Machine Breaking + +* (apps/transfer, apps/27-interchain-accounts, app/29-fee) [\#4992](https://github.com/cosmos/ibc-go/pull/4992) Set validation for length of string fields. + +## [v7.5.2](https://github.com/cosmos/ibc-go/releases/tag/v7.5.2) - 2024-06-20 + +### Dependencies + +* [\#6613](https://github.com/cosmos/ibc-go/pull/6613) Update Cosmos SDK to v0.47.12. + +### Improvements + +* (apps/27-interchain-accounts) [\#6436](https://github.com/cosmos/ibc-go/pull/6436) Refactor ICA host keeper instantiation method to avoid panic related to proto files. + +## [v7.5.1](https://github.com/cosmos/ibc-go/releases/tag/v7.5.1) - 2024-05-22 + +### Improvements + +* (core/ante) [\#6302](https://github.com/cosmos/ibc-go/pull/6302) Performance: Skip app callbacks during RecvPacket execution in checkTx within the redundant relay ante handler. +* (core/ante) [\#6280](https://github.com/cosmos/ibc-go/pull/6280) Performance: Skip redundant proof checking in RecvPacket execution in reCheckTx within the redundant relay ante handler. +* (core/ante) [\#6306](https://github.com/cosmos/ibc-go/pull/6306) Performance: Skip misbehaviour checks in UpdateClient flow and skip signature checks in reCheckTx mode. + +## [v7.5.0](https://github.com/cosmos/ibc-go/releases/tag/v7.5.0) - 2024-05-14 + +### Dependencies + +* [\#6254](https://github.com/cosmos/ibc-go/pull/6254) Update Cosmos SDK to v0.47.11 and CometBFT to v0.37.5. + +### State Machine Breaking + +* (light-clients/07-tendermint) [\#6276](https://github.com/cosmos/ibc-go/pull/6276) Fix: No-op to avoid panicking on `UpdateState` for invalid misbehaviour submissions. + +### Improvements + +* (apps/27-interchain-accounts) [\#6147](https://github.com/cosmos/ibc-go/pull/6147) Emit an event signalling that the host submodule is disabled. +* (testing) [\#6180](https://github.com/cosmos/ibc-go/pull/6180) Add version to tm abci headers in ibctesting. +* (apps/27-interchain-accounts, apps/transfer, apps/29-fee) [\#6253](https://github.com/cosmos/ibc-go/pull/6253) Allow channel handshake to succeed if fee middleware is wired up on one side, but not the other. +* (apps/transfer) [\#6268](https://github.com/cosmos/ibc-go/pull/6268) Use memo strings instead of JSON keys in `AllowedPacketData` of transfer authorization. + +### Features + +* (apps/27-interchain-accounts) [\#5633](https://github.com/cosmos/ibc-go/pull/5633) Allow new ICA channels to use unordered ordering. +* (apps/27-interchain-accounts) [\#5785](https://github.com/cosmos/ibc-go/pull/5785) Introduce a new tx message that ICA host submodule can use to query the chain (only those marked with `module_query_safe`) and write the responses to the acknowledgement. + +### Bug Fixes + +* (apps/29-fee) [\#6255](https://github.com/cosmos/ibc-go/pull/6255) Delete already refunded fees from state if some fee(s) cannot be refunded on channel closure. + +## [v7.4.0](https://github.com/cosmos/ibc-go/releases/tag/v7.4.0) - 2024-04-05 + +## [v7.3.2](https://github.com/cosmos/ibc-go/releases/tag/v7.3.2) - 2024-01-31 + +### Dependencies + +* [\#5717](https://github.com/cosmos/ibc-go/pull/5717) Update Cosmos SDK to v0.47.8 and CometBFT to v0.37.4. + +### Improvements + +* (core) [\#5541](https://github.com/cosmos/ibc-go/pull/5541) Enable emission of events on erroneous IBC application callbacks by appending a prefix to all event type and attribute keys. + +### Bug Fixes + +* (apps/27-interchain-accounts) [\#4944](https://github.com/cosmos/ibc-go/pull/4944) Add missing proto interface registration. + +## [v7.3.1](https://github.com/cosmos/ibc-go/releases/tag/v7.3.1) - 2023-10-20 + +### Dependencies + +* [\#4539](https://github.com/cosmos/ibc-go/pull/4539) Update Cosmos SDK to v0.47.5. + +### Improvements + +* (apps/27-interchain-accounts) [\#4537](https://github.com/cosmos/ibc-go/pull/4537) Add argument to `generate-packet-data` cli to choose the encoding format for the messages in the ICA packet data. + +### Bug Fixes + +* (apps/transfer) [\#4709](https://github.com/cosmos/ibc-go/pull/4709) Order query service RPCs to fix availability of denom traces endpoint when no args are provided. + +## [v7.3.0](https://github.com/cosmos/ibc-go/releases/tag/v7.3.0) - 2023-08-31 + +### Dependencies + +* [\#4122](https://github.com/cosmos/ibc-go/pull/4122) Update Cosmos SDK to v0.47.4. + +### Improvements + +* [\#4187](https://github.com/cosmos/ibc-go/pull/4187) Adds function `WithICS4Wrapper` to keepers to allow to set the middleware after the keeper's creation. +* (light-clients/06-solomachine) [\#4429](https://github.com/cosmos/ibc-go/pull/4429) Remove IBC key from path of bytes signed by solomachine and not escape the path. + +### Features + +* (apps/27-interchain-accounts) [\#3796](https://github.com/cosmos/ibc-go/pull/3796) Adds support for json tx encoding for interchain accounts. +* [\#4188](https://github.com/cosmos/ibc-go/pull/4188) Adds optional `PacketDataUnmarshaler` interface that allows a middleware to request the packet data to be unmarshaled by the base application. +* [\#4199](https://github.com/cosmos/ibc-go/pull/4199) Adds optional `PacketDataProvider` interface for retrieving custom packet data stored on behalf of another application. +* [\#4200](https://github.com/cosmos/ibc-go/pull/4200) Adds optional `PacketData` interface which application's packet data may implement. + +### Bug Fixes + +* (04-channel) [\#4476](https://github.com/cosmos/ibc-go/pull/4476) Use UTC time in log messages for packet timeout error. +* (testing) [\#4483](https://github.com/cosmos/ibc-go/pull/4483) Use the correct revision height when querying trusted validator set. + +## [v7.2.3](https://github.com/cosmos/ibc-go/releases/tag/v7.2.3) - 2024-01-31 + +### Dependencies + +* [\#5716](https://github.com/cosmos/ibc-go/pull/5716) Update Cosmos SDK to v0.47.8 and CometBFT to v0.37.4. + +### Improvements + +* (core) [\#5541](https://github.com/cosmos/ibc-go/pull/5541) Enable emission of events on erroneous IBC application callbacks by appending a prefix to all event type and attribute keys. + +## [v7.2.2](https://github.com/cosmos/ibc-go/releases/tag/v7.2.2) - 2023-10-20 + +### Dependencies + +* [\#4539](https://github.com/cosmos/ibc-go/pull/4539) Update Cosmos SDK to v0.47.5. + +### Bug Fixes + +* (apps/transfer) [\#4709](https://github.com/cosmos/ibc-go/pull/4709) Order query service RPCs to fix availability of denom traces endpoint when no args are provided. + +## [v7.2.1](https://github.com/cosmos/ibc-go/releases/tag/v7.2.1) - 2023-08-31 + +### Bug Fixes + +* (04-channel) [\#4476](https://github.com/cosmos/ibc-go/pull/4476) Use UTC time in log messages for packet timeout error. +* (testing) [\#4483](https://github.com/cosmos/ibc-go/pull/4483) Use the correct revision height when querying trusted validator set. + +## [v7.2.0](https://github.com/cosmos/ibc-go/releases/tag/v7.2.0) - 2023-06-22 + +### Dependencies + +* [\#3810](https://github.com/cosmos/ibc-go/pull/3810) Update Cosmos SDK to v0.47.3. +* [\#3862](https://github.com/cosmos/ibc-go/pull/3862) Update CometBFT to v0.37.2. + +### State Machine Breaking + +* [\#3907](https://github.com/cosmos/ibc-go/pull/3907) Re-implemented missing functions of `LegacyMsg` interface to fix transaction signing with ledger. + +## [v7.1.0](https://github.com/cosmos/ibc-go/releases/tag/v7.1.0) - 2023-06-09 + +### Dependencies + +* [\#3542](https://github.com/cosmos/ibc-go/pull/3542) Update Cosmos SDK to v0.47.2 and CometBFT to v0.37.1. +* [\#3457](https://github.com/cosmos/ibc-go/pull/3457) Update to ics23 v0.10.0. + +### Improvements + +* (apps/transfer) [\#3454](https://github.com/cosmos/ibc-go/pull/3454) Support transfer authorization unlimited spending when the max `uint256` value is provided as limit. + +### Features + +* (light-clients/09-localhost) [\#3229](https://github.com/cosmos/ibc-go/pull/3229) Implementation of v2 of localhost loopback client. +* (apps/transfer) [\#3019](https://github.com/cosmos/ibc-go/pull/3019) Add state entry to keep track of total amount of tokens in escrow. + +### Bug Fixes + +* (core/04-channel) [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. +* (core/04-channel) [\#3593](https://github.com/cosmos/ibc-go/pull/3593) `SendPacket` now correctly returns `ErrClientNotFound` in favour of `ErrConsensusStateNotFound`. + +## [v7.0.1](https://github.com/cosmos/ibc-go/releases/tag/v7.0.1) - 2023-05-25 + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v7.0.0](https://github.com/cosmos/ibc-go/releases/tag/v7.0.0) - 2023-03-17 + +### Dependencies + +* [\#2672](https://github.com/cosmos/ibc-go/issues/2672) Update to cosmos-sdk v0.47. +* [\#3175](https://github.com/cosmos/ibc-go/issues/3175) Migrate to cometbft v0.37. + +### API Breaking + +* (core) [\#2897](https://github.com/cosmos/ibc-go/pull/2897) Remove legacy migrations required for upgrading from Stargate release line to ibc-go >= v1.x.x. +* (core/02-client) [\#2856](https://github.com/cosmos/ibc-go/pull/2856) Rename `IterateClients` to `IterateClientStates`. The function now takes a prefix argument which may be used for prefix iteration over the client store. +* (light-clients/tendermint)[\#1768](https://github.com/cosmos/ibc-go/pull/1768) Removed `AllowUpdateAfterExpiry`, `AllowUpdateAfterMisbehaviour` booleans as they are deprecated (see ADR026) +* (06-solomachine) [\#1679](https://github.com/cosmos/ibc-go/pull/1679) Remove `types` sub-package from `06-solomachine` lightclient directory. +* (07-tendermint) [\#1677](https://github.com/cosmos/ibc-go/pull/1677) Remove `types` sub-package from `07-tendermint` lightclient directory. +* (06-solomachine) [\#1687](https://github.com/cosmos/ibc-go/pull/1687) Bump `06-solomachine` protobuf version from `v2` to `v3`. +* (06-solomachine) [\#1687](https://github.com/cosmos/ibc-go/pull/1687) Removed `DataType` enum and associated message types from `06-solomachine`. `DataType` has been removed from `SignBytes` and `SignatureAndData` in favour of `path`. +* (02-client) [\#598](https://github.com/cosmos/ibc-go/pull/598) The client state and consensus state return value has been removed from `VerifyUpgradeAndUpdateState`. Light client implementations must update the client state and consensus state after verifying a valid client upgrade. +* (06-solomachine) [\#1100](https://github.com/cosmos/ibc-go/pull/1100) Remove `GetClientID` function from 06-solomachine `Misbehaviour` type. +* (06-solomachine) [\#1100](https://github.com/cosmos/ibc-go/pull/1100) Deprecate `ClientId` field in 06-solomachine `Misbehaviour` type. +* (07-tendermint) [\#1097](https://github.com/cosmos/ibc-go/pull/1097) Remove `GetClientID` function from 07-tendermint `Misbehaviour` type. +* (07-tendermint) [\#1097](https://github.com/cosmos/ibc-go/pull/1097) Deprecate `ClientId` field in 07-tendermint `Misbehaviour` type. +* (modules/core/exported) [\#1107](https://github.com/cosmos/ibc-go/pull/1107) Merging the `Header` and `Misbehaviour` interfaces into a single `ClientMessage` type. +* (06-solomachine)[\#1906](https://github.com/cosmos/ibc-go/pull/1906/files) Removed `AllowUpdateAfterProposal` boolean as it has been deprecated (see 01_concepts of the solo machine spec for more details). +* (07-tendermint) [\#1896](https://github.com/cosmos/ibc-go/pull/1896) Remove error return from `IterateConsensusStateAscending` in `07-tendermint`. +* (apps/27-interchain-accounts) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Interchain accounts host and controller Keepers now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (06-solomachine) [\#2761](https://github.com/cosmos/ibc-go/pull/2761) Removed deprecated `ClientId` field from `Misbehaviour` and `allow_update_after_proposal` field from `ClientState`. +* (apps) [\#3154](https://github.com/cosmos/ibc-go/pull/3154) Remove unused `ProposalContents` function. +* (apps) [\#3149](https://github.com/cosmos/ibc-go/pull/3149) Remove legacy interface function `RandomizedParams`, which is no longer used. +* (light-clients/06-solomachine) [\#2941](https://github.com/cosmos/ibc-go/pull/2941) Remove solomachine header sequence. +* (core) [\#2982](https://github.com/cosmos/ibc-go/pull/2982) Moved the ibc module name into the exported package. + +### State Machine Breaking + +* (06-solomachine) [\#2744](https://github.com/cosmos/ibc-go/pull/2744) `Misbehaviour.ValidateBasic()` now only enforces that signature data does not match when the signature paths are different. +* (06-solomachine) [\#2748](https://github.com/cosmos/ibc-go/pull/2748) Adding sentinel value for header path in 06-solomachine. +* (apps/29-fee) [\#2942](https://github.com/cosmos/ibc-go/pull/2942) Check `x/bank` send enabled before escrowing fees. +* (core/04-channel) [\#3009](https://github.com/cosmos/ibc-go/pull/3009) Change check to disallow optimistic sends. + +### Improvements + +* (core) [\#3082](https://github.com/cosmos/ibc-go/pull/3082) Add `HasConnection` and `HasChannel` methods. +* (tests) [\#2926](https://github.com/cosmos/ibc-go/pull/2926) Lint tests +* (apps/transfer) [\#2643](https://github.com/cosmos/ibc-go/pull/2643) Add amount, denom, and memo to transfer event emission. +* (core) [\#2746](https://github.com/cosmos/ibc-go/pull/2746) Allow proof height to be zero for all core IBC `sdk.Msg` types that contain proofs. +* (light-clients/06-solomachine) [\#2746](https://github.com/cosmos/ibc-go/pull/2746) Discard proofHeight for solo machines and use the solo machine sequence instead. +* (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. +* (modules/core/02-client) [\#1188](https://github.com/cosmos/ibc-go/pull/1188/files) Routing `MsgSubmitMisbehaviour` to `UpdateClient` keeper function. Deprecating `SubmitMisbehaviour` endpoint. +* (modules/core/02-client) [\#1208](https://github.com/cosmos/ibc-go/pull/1208) Replace `CheckHeaderAndUpdateState` usage in 02-client with calls to `VerifyClientMessage`, `CheckForMisbehaviour`, `UpdateStateOnMisbehaviour` and `UpdateState`. +* (modules/light-clients/09-localhost) [\#1187](https://github.com/cosmos/ibc-go/pull/1187/) Removing localhost light client implementation as it is not functional. An upgrade handler is provided in `modules/migrations/v5` to prune `09-localhost` clients and consensus states from the store. +* (modules/core/02-client) [\#1186](https://github.com/cosmos/ibc-go/pull/1186) Removing `GetRoot` function from ConsensusState interface in `02-client`. `GetRoot` is unused by core IBC. +* (modules/core/02-client) [\#1196](https://github.com/cosmos/ibc-go/pull/1196) Adding VerifyClientMessage to ClientState interface. +* (modules/core/02-client) [\#1198](https://github.com/cosmos/ibc-go/pull/1198) Adding UpdateStateOnMisbehaviour to ClientState interface. +* (modules/core/02-client) [\#1170](https://github.com/cosmos/ibc-go/pull/1170) Updating `ClientUpdateProposal` to set client state in lightclient implementations `CheckSubstituteAndUpdateState` methods. +* (modules/core/02-client) [\#1197](https://github.com/cosmos/ibc-go/pull/1197) Adding `CheckForMisbehaviour` to `ClientState` interface. +* (modules/core/02-client) [\#1210](https://github.com/cosmos/ibc-go/pull/1210) Removing `CheckHeaderAndUpdateState` from `ClientState` interface & associated light client implementations. +* (modules/core/02-client) [\#1212](https://github.com/cosmos/ibc-go/pull/1212) Removing `CheckMisbehaviourAndUpdateState` from `ClientState` interface & associated light client implementations. +* (modules/core/exported) [\#1206](https://github.com/cosmos/ibc-go/pull/1206) Adding new method `UpdateState` to `ClientState` interface. +* (modules/core/02-client) [\#1741](https://github.com/cosmos/ibc-go/pull/1741) Emitting a new `upgrade_chain` event upon setting upgrade consensus state. +* (client) [\#724](https://github.com/cosmos/ibc-go/pull/724) `IsRevisionFormat` and `IsClientIDFormat` have been updated to disallow newlines before the dash used to separate the chainID and revision number, and the client type and client sequence. +* (02-client/cli) [\#897](https://github.com/cosmos/ibc-go/pull/897) Remove `GetClientID()` from `Misbehaviour` interface. Submit client misbehaviour cli command requires an explicit client id now. +* (06-solomachine) [\#1972](https://github.com/cosmos/ibc-go/pull/1972) Solo machine implementation of `ZeroCustomFields` fn now panics as the fn is only used for upgrades which solo machine does not support. +* (light-clients/06-solomachine) Moving `verifyMisbehaviour` function from update.go to misbehaviour_handle.go. +* [\#2434](https://github.com/cosmos/ibc-go/pull/2478) Removed all `TypeMsg` constants +* (modules/core/exported) [\#2539](https://github.com/cosmos/ibc-go/pull/2539) Removing `GetVersions` from `ConnectionI` interface. +* (core/02-connection) [\#2419](https://github.com/cosmos/ibc-go/pull/2419) Add optional proof data to proto definitions of `MsgConnectionOpenTry` and `MsgConnectionOpenAck` for host state machines that are unable to introspect their own consensus state. +* (light-clients/07-tendermint) [\#3046](https://github.com/cosmos/ibc-go/pull/3046) Moved non-verification misbehaviour checks to `CheckForMisbehaviour`. +* (apps/29-fee) [\#2975](https://github.com/cosmos/ibc-go/pull/2975) Adding distribute fee events to ics29. +* (light-clients/07-tendermint) [\#2965](https://github.com/cosmos/ibc-go/pull/2965) Prune expired `07-tendermint` consensus states on duplicate header updates. +* (light-clients) [\#2736](https://github.com/cosmos/ibc-go/pull/2736) Updating `VerifyMembership` and `VerifyNonMembership` methods to use `Path` interface. +* (light-clients) [\#3113](https://github.com/cosmos/ibc-go/pull/3113) Align light client module names. + +### Features + +* (apps/transfer) [\#3079](https://github.com/cosmos/ibc-go/pull/3079) Added authz support for ics20. +* (core/02-client) [\#2824](https://github.com/cosmos/ibc-go/pull/2824) Add genesis migrations for v6 to v7. The migration migrates the solo machine client state definition, removes all solo machine consensus states and removes the localhost client. +* (core/24-host) [\#2856](https://github.com/cosmos/ibc-go/pull/2856) Add `PrefixedClientStorePath` and `PrefixedClientStoreKey` functions to 24-host +* (core/02-client) [\#2819](https://github.com/cosmos/ibc-go/pull/2819) Add automatic in-place store migrations to remove the localhost client and migrate existing solo machine definitions. +* (light-clients/06-solomachine) [\#2826](https://github.com/cosmos/ibc-go/pull/2826) Add `AppModuleBasic` for the 06-solomachine client and remove solo machine type registration from core IBC. Chains must register the `AppModuleBasic` of light clients. +* (light-clients/07-tendermint) [\#2825](https://github.com/cosmos/ibc-go/pull/2825) Add `AppModuleBasic` for the 07-tendermint client and remove tendermint type registration from core IBC. Chains must register the `AppModuleBasic` of light clients. +* (light-clients/07-tendermint) [\#2800](https://github.com/cosmos/ibc-go/pull/2800) Add optional in-place store migration function to prune all expired tendermint consensus states. +* (core/24-host) [\#2820](https://github.com/cosmos/ibc-go/pull/2820) Add `MustParseClientStatePath` which parses the clientID from a client state key path. +* (testing/simapp) [\#2842](https://github.com/cosmos/ibc-go/pull/2842) Adding the new upgrade handler for v6 -> v7 to simapp which prunes expired Tendermint consensus states. +* (testing) [\#2829](https://github.com/cosmos/ibc-go/pull/2829) Add `AssertEvents` which asserts events against expected event map. + +### Bug Fixes + +* (testing) [\#3295](https://github.com/cosmos/ibc-go/pull/3295) The function `SetupWithGenesisValSet` will set the baseapp chainID before running `InitChain` +* (light-clients/solomachine) [\#1839](https://github.com/cosmos/ibc-go/pull/1839) Fixed usage of the new diversifier in validation of changing diversifiers for the solo machine. The current diversifier must sign over the new diversifier. +* (light-clients/07-tendermint) [\#1674](https://github.com/cosmos/ibc-go/pull/1674) Submitted ClientState is zeroed out before checking the proof in order to prevent the proposal from containing information governance is not actually voting on. +* (modules/core/02-client)[\#1676](https://github.com/cosmos/ibc-go/pull/1676) ClientState must be zeroed out for `UpgradeProposals` to pass validation. This prevents a proposal containing information governance is not actually voting on. +* (core/02-client) [\#2510](https://github.com/cosmos/ibc-go/pull/2510) Fix client ID validation regex to conform closer to spec. +* (apps/transfer) [\#3045](https://github.com/cosmos/ibc-go/pull/3045) Allow value with slashes in URL template. +* (apps/27-interchain-accounts) [\#2601](https://github.com/cosmos/ibc-go/pull/2601) Remove bech32 check from owner address on ICA controller msgs RegisterInterchainAccount and SendTx. +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Skip emission of unpopulated memo field in ics20. +* (apps/27-interchain-accounts) [\#2682](https://github.com/cosmos/ibc-go/pull/2682) Avoid race conditions in ics27 handshakes. +* (light-clients/06-solomachine) [\#2741](https://github.com/cosmos/ibc-go/pull/2741) Added check for empty path in 06-solomachine. +* (light-clients/07-tendermint) [\#3022](https://github.com/cosmos/ibc-go/pull/3022) Correctly close iterator in `07-tendermint` store. +* (core/02-client) [\#3010](https://github.com/cosmos/ibc-go/pull/3010) Update `Paginate` to use `FilterPaginate` in `ClientStates` and `ConnectionChannels` grpc queries. + +## [v6.3.0](https://github.com/cosmos/ibc-go/releases/tag/v6.3.0) - 2024-04-05 + +## [v6.2.1](https://github.com/cosmos/ibc-go/releases/tag/v6.2.1) - 2023-10-20 + +### Bug Fixes + +* (apps/transfer) [\#3045](https://github.com/cosmos/ibc-go/pull/3045) allow value with slashes in URL template for `denom_traces` and `denom_hashes` queries. +* (apps/transfer) [\#4709](https://github.com/cosmos/ibc-go/pull/4709) Order query service RPCs to fix availability of denom traces endpoint when no args are provided. + +## [v6.2.0](https://github.com/cosmos/ibc-go/releases/tag/v6.2.0) - 2023-05-31 + +### Dependencies + +* [\#3393](https://github.com/cosmos/ibc-go/pull/3393) Bump Cosmos SDK to v0.46.12 and replace Tendermint with CometBFT v0.34.37. + +### Improvements + +* (core) [\#3082](https://github.com/cosmos/ibc-go/pull/3082) Add `HasConnection` and `HasChannel` methods. +* (apps/transfer) [\#3454](https://github.com/cosmos/ibc-go/pull/3454) Support transfer authorization unlimited spending when the max `uint256` value is provided as limit. + +### Features + +* [\#3079](https://github.com/cosmos/ibc-go/pull/3079) Add authz support for ics20. + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v6.1.2](https://github.com/cosmos/ibc-go/releases/tag/v6.1.2) - 2023-10-20 + +### Bug Fixes + +* (apps/transfer) [\#3045](https://github.com/cosmos/ibc-go/pull/3045) allow value with slashes in URL template for `denom_traces` and `denom_hashes` queries. +* (apps/transfer) [\#4709](https://github.com/cosmos/ibc-go/pull/4709) Order query service RPCs to fix availability of denom traces endpoint when no args are provided. + +## [v6.1.1](https://github.com/cosmos/ibc-go/releases/tag/v6.1.1) - 2023-05-25 + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v6.1.0](https://github.com/cosmos/ibc-go/releases/tag/v6.1.0) - 2022-12-20 + +### Dependencies + +* [\#2945](https://github.com/cosmos/ibc-go/pull/2945) Bump Cosmos SDK to v0.46.7 and Tendermint to v0.34.24. + +### State Machine Breaking + +* (apps/29-fee) [\#2942](https://github.com/cosmos/ibc-go/pull/2942) Check `x/bank` send enabled before escrowing fees. + +## [v6.0.0](https://github.com/cosmos/ibc-go/releases/tag/v6.0.0) - 2022-12-09 + +### Dependencies + +* [\#2868](https://github.com/cosmos/ibc-go/pull/2868) Bump ICS 23 to v0.9.0. +* [\#2458](https://github.com/cosmos/ibc-go/pull/2458) Bump Cosmos SDK to v0.46.2 +* [\#2784](https://github.com/cosmos/ibc-go/pull/2784) Bump Cosmos SDK to v0.46.6 and Tendermint to v0.34.23. + +### API Breaking + +* (apps/27-interchain-accounts) [\#2607](https://github.com/cosmos/ibc-go/pull/2607) `SerializeCosmosTx` now takes in a `[]proto.Message` instead of `[]sdk.Msg`. +* (apps/transfer) [\#2446](https://github.com/cosmos/ibc-go/pull/2446) Remove `SendTransfer` function in favor of a private `sendTransfer` function. All IBC transfers must be initiated with `MsgTransfer`. +* (apps/29-fee) [\#2395](https://github.com/cosmos/ibc-go/pull/2395) Remove param space from ics29 NewKeeper function. The field was unused. +* (apps/27-interchain-accounts) [\#2133](https://github.com/cosmos/ibc-go/pull/2133) Generates genesis protos in a separate directory to avoid circular import errors. The protobuf package name has changed for the genesis types. +* (apps/27-interchain-accounts) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Interchain accounts host and controller Keepers now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (transfer) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Transfer Keeper now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (05-port) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Port Keeper now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (04-channel) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Channel Keeper now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (core/04-channel)[\#1703](https://github.com/cosmos/ibc-go/pull/1703) Update `SendPacket` API to take in necessary arguments and construct rest of packet rather than taking in entire packet. The generated packet sequence is returned by the `SendPacket` function. +* (modules/apps/27-interchain-accounts) [\#2433](https://github.com/cosmos/ibc-go/pull/2450) Renamed icatypes.PortPrefix to icatypes.ControllerPortPrefix & icatypes.PortID to icatypes.HostPortID +* (testing) [\#2567](https://github.com/cosmos/ibc-go/pull/2567) Modify `SendPacket` API of `Endpoint` to match the API of `SendPacket` in 04-channel. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (27-interchain-accounts) [\#2590](https://github.com/cosmos/ibc-go/pull/2590) Removing port prefix requirement from the ICA host channel handshake +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. +* (light-clients/07-tendermint) [\#2555](https://github.com/cosmos/ibc-go/pull/2555) Forbid negative values for `TrustingPeriod`, `UnbondingPeriod` and `MaxClockDrift` (as specified in ICS-07). +* (core/04-channel) [\#2973](https://github.com/cosmos/ibc-go/pull/2973) Write channel state before invoking app callbacks in ack and confirm channel handshake steps. + +### Improvements + +* (apps/27-interchain-accounts) [\#2134](https://github.com/cosmos/ibc-go/pull/2134) Adding upgrade handler to ICS27 `controller` submodule for migration of channel capabilities. This upgrade handler migrates ownership of channel capabilities from the underlying application to the ICS27 `controller` submodule. +* (apps/27-interchain-accounts) [\#2102](https://github.com/cosmos/ibc-go/pull/2102) ICS27 controller middleware now supports a nil underlying application. This allows chains to make use of interchain accounts with existing auth mechanisms such as x/group and x/gov. +* (apps/27-interchain-accounts) [\#2157](https://github.com/cosmos/ibc-go/pull/2157) Adding `IsMiddlewareEnabled` functionality to enforce calls to ICS27 msg server to *not* route to the underlying application. +* (apps/27-interchain-accounts) [\#2146](https://github.com/cosmos/ibc-go/pull/2146) ICS27 controller now claims the channel capability passed via ibc core, and passes `nil` to the underlying app callback. The channel capability arg in `SendTx` is now ignored and looked up internally. +* (apps/27-interchain-accounts) [\#2177](https://github.com/cosmos/ibc-go/pull/2177) Adding `IsMiddlewareEnabled` flag to interchain accounts `ActiveChannel` genesis type. +* (apps/27-interchain-accounts) [\#2140](https://github.com/cosmos/ibc-go/pull/2140) Adding migration handler to ICS27 `controller` submodule to assert ownership of channel capabilities and set middleware enabled flag for existing channels. The ICS27 module consensus version has been bumped from 1 to 2. +* (core/04-channel) [\#2304](https://github.com/cosmos/ibc-go/pull/2304) Adding `GetAllChannelsWithPortPrefix` function which filters channels based on a provided port prefix. +* (apps/27-interchain-accounts) [\#2248](https://github.com/cosmos/ibc-go/pull/2248) Adding call to underlying app in `OnChanCloseConfirm` callback of the controller submodule and adding relevant unit tests. +* (apps/27-interchain-accounts) [\#2251](https://github.com/cosmos/ibc-go/pull/2251) Adding `msgServer` struct to controller submodule that embeds the `Keeper` struct. +* (apps/27-interchain-accounts) [\#2290](https://github.com/cosmos/ibc-go/pull/2290) Changed `DefaultParams` function in `host` submodule to allow all messages by default. Defined a constant named `AllowAllHostMsgs` for `host` module to keep wildcard "*" string which allows all messages. +* (apps/27-interchain-accounts) [\#2297](https://github.com/cosmos/ibc-go/pull/2297) Adding cli command to generate ICS27 packet data. +* (modules/core/keeper) [\#1728](https://github.com/cosmos/ibc-go/pull/2399) Updated channel callback errors to include portID & channelID for better identification of errors. +* (testing) [\#2657](https://github.com/cosmos/ibc-go/pull/2657) Carry `ProposerAddress` through committed blocks. Allow `DefaultGenTxGas` to be modified. +* (core/03-connection) [\#2745](https://github.com/cosmos/ibc-go/pull/2745) Adding `ConnectionParams` grpc query and CLI to 03-connection. +* (apps/29-fee) [\#2786](https://github.com/cosmos/ibc-go/pull/2786) Save gas by checking key existence with `KVStore`'s `Has` method. + +### Features + +* (apps/27-interchain-accounts) [\#2147](https://github.com/cosmos/ibc-go/pull/2147) Adding a `SubmitTx` gRPC endpoint for the ICS27 Controller module which allows owners of interchain accounts to submit transactions. This replaces the previously existing need for authentication modules to implement this standard functionality. +* (testing/simapp) [\#2190](https://github.com/cosmos/ibc-go/pull/2190) Adding the new `x/group` cosmos-sdk module to simapp. +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (modules/core/keeper) [\#2403](https://github.com/cosmos/ibc-go/pull/2403) Added a function in keeper to cater for blank pointers. +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. +* (modules/core/keeper) [\#2745](https://github.com/cosmos/ibc-go/pull/2745) Fix request wiring for `UpgradedConsensusState` in core query server. + +## [v5.4.0](https://github.com/cosmos/ibc-go/releases/tag/v5.4.0) - 2024-04-05 + +## [v5.3.2](https://github.com/cosmos/ibc-go/releases/tag/v5.3.2) - 2023-10-20 + +### Bug Fixes + +* (apps/transfer) [\#3045](https://github.com/cosmos/ibc-go/pull/3045) allow value with slashes in URL template for `denom_traces` and `denom_hashes` queries. +* (apps/transfer) [\#4709](https://github.com/cosmos/ibc-go/pull/4709) Order query service RPCs to fix availability of denom traces endpoint when no args are provided. + +## [v5.3.1](https://github.com/cosmos/ibc-go/releases/tag/v5.3.1) - 2023-05-25 + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v5.3.0](https://github.com/cosmos/ibc-go/releases/tag/v5.3.0) - 2023-05-04 + +### Dependencies + +* [\#3354](https://github.com/cosmos/ibc-go/pull/3354) Bump Cosmos SDK to v0.46.12 and replace Tendermint with CometBFT v0.34.27. + +## [v5.2.1](https://github.com/cosmos/ibc-go/releases/tag/v5.2.1) - 2023-05-25 + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v5.2.0](https://github.com/cosmos/ibc-go/releases/tag/v5.2.0) - 2022-12-20 + +### Dependencies + +* [\#2868](https://github.com/cosmos/ibc-go/pull/2868) Bump ICS 23 to v0.9.0. +* [\#2944](https://github.com/cosmos/ibc-go/pull/2944) Bump Cosmos SDK to v0.46.7 and Tendermint to v0.34.24. + +### State Machine Breaking + +* (apps/29-fee) [\#2942](https://github.com/cosmos/ibc-go/pull/2942) Check `x/bank` send enabled before escrowing fees. + +### Improvements + +* (apps/29-fee) [\#2786](https://github.com/cosmos/ibc-go/pull/2786) Save gas by checking key existence with `KVStore`'s `Has` method. + +## [v5.1.0](https://github.com/cosmos/ibc-go/releases/tag/v5.1.0) - 2022-11-09 + +### Dependencies + +* [\#2647](https://github.com/cosmos/ibc-go/pull/2647) Bump Cosmos SDK to v0.46.4 and Tendermint to v0.34.22. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (27-interchain-accounts) [\#2590](https://github.com/cosmos/ibc-go/pull/2590) Removing port prefix requirement from the ICA host channel handshake +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. + +### Improvements + +* (testing) [\#2657](https://github.com/cosmos/ibc-go/pull/2657) Carry `ProposerAddress` through committed blocks. Allow `DefaultGenTxGas` to be modified. + +### Features + +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. + +## [v5.0.1](https://github.com/cosmos/ibc-go/releases/tag/v5.0.1) - 2022-10-27 + +### Dependencies + +* [\#2623](https://github.com/cosmos/ibc-go/pull/2623) Bump SDK version to v0.46.3 and Tendermint version to v0.34.22. + +## [v5.0.0](https://github.com/cosmos/ibc-go/releases/tag/v5.0.0) - 2022-09-28 + +### Dependencies + +* [\#1653](https://github.com/cosmos/ibc-go/pull/1653) Bump SDK version to v0.46 +* [\#2124](https://github.com/cosmos/ibc-go/pull/2124) Bump SDK version to v0.46.1 + +### API Breaking + +* (testing)[\#2028](https://github.com/cosmos/ibc-go/pull/2028) New interface `ibctestingtypes.StakingKeeper` added and set for the testing app `StakingKeeper` setup. +* (core/04-channel) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) `NewPacketId` has been renamed to `NewPacketID` to comply with go linting rules. +* (core/ante) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) `AnteDecorator` has been renamed to `RedundancyDecorator` to comply with go linting rules and to give more clarity to the purpose of the Decorator. +* (core/ante) [\#1820](https://github.com/cosmos/ibc-go/pull/1418) `RedundancyDecorator` has been renamed to `RedundantRelayDecorator` to make the name for explicit. +* (testing) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) `MockIBCApp` has been renamed to `IBCApp` and `MockEmptyAcknowledgement` has been renamed to `EmptyAcknowledgement` to comply with go linting rules +* (apps/27-interchain-accounts) [\#2058](https://github.com/cosmos/ibc-go/pull/2058) Added `MessageRouter` interface and replaced `*baseapp.MsgServiceRouter` with it. The controller and host keepers of apps/27-interchain-accounts have been updated to use it. +* (apps/27-interchain-accounts)[\#2302](https://github.com/cosmos/ibc-go/pull/2302) Handle unwrapping of channel version in interchain accounts channel reopening handshake flow. The `host` submodule `Keeper` now requires an `ICS4Wrapper` similarly to the `controller` submodule. + +### Improvements + +* (27-interchain-accounts) [\#1352](https://github.com/cosmos/ibc-go/pull/1352) Add support for Cosmos-SDK simulation to ics27 module. +* (linting) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) Fix linting errors, resulting compatibility with go1.18 linting style, golangci-lint 1.46.2 and the revivie linter. This caused breaking changes in core/04-channel, core/ante, and the testing library. + +### Features + +* (apps/27-interchain-accounts) [\#2193](https://github.com/cosmos/ibc-go/pull/2193) Adding `InterchainAccount` gRPC query endpoint to ICS27 `controller` submodule to allow users to retrieve registered interchain account addresses. + +### Bug Fixes + +* (27-interchain-accounts) [\#2308](https://github.com/cosmos/ibc-go/pull/2308) Nil checks have been added to ensure services are not registered for nil host or controller keepers. +* (makefile) [\#1785](https://github.com/cosmos/ibc-go/pull/1785) Fetch the correct versions of protocol buffers dependencies from tendermint, cosmos-sdk, and ics23. +* (modules/core/04-channel)[\#1919](https://github.com/cosmos/ibc-go/pull/1919) Fixed formatting of sequence for packet "acknowledgement written" logs. + +## [v4.6.0](https://github.com/cosmos/ibc-go/releases/tag/v4.6.0) - 2024-04-05 + +## [v4.5.1](https://github.com/cosmos/ibc-go/releases/tag/v4.5.1) - 2023-10-20 + +### Bug Fixes + +* (apps/transfer) [\#3045](https://github.com/cosmos/ibc-go/pull/3045) allow value with slashes in URL template for `denom_traces` and `denom_hashes` queries. +* (apps/transfer) [\#4709](https://github.com/cosmos/ibc-go/pull/4709) Order query service RPCs to fix availability of denom traces endpoint when no args are provided. + +## [v4.5.0](https://github.com/cosmos/ibc-go/releases/tag/v4.5.0) - 2023-10-03 + +### Dependencies + +* [\#4738](https://github.com/cosmos/ibc-go/pull/4738) Bump Cosmos SDK to v0.45.16. +* [\#4782](https://github.com/cosmos/ibc-go/pull/4782) Bump ics23 to v0.9.1. + +## [v4.4.3](https://github.com/cosmos/ibc-go/releases/tag/v4.4.3) - 2023-10-20 + +### Bug Fixes + +* (apps/transfer) [\#3045](https://github.com/cosmos/ibc-go/pull/3045) allow value with slashes in URL template for `denom_traces` and `denom_hashes` queries. +* (apps/transfer) [\#4709](https://github.com/cosmos/ibc-go/pull/4709) Order query service RPCs to fix availability of denom traces endpoint when no args are provided. + +## [v4.4.2](https://github.com/cosmos/ibc-go/releases/tag/v4.4.2) - 2023-05-25 + +### Bug Fixes + +* [\#3662](https://github.com/cosmos/ibc-go/pull/3662) Retract v4.1.2 and v4.2.1. + +## [v4.4.1](https://github.com/cosmos/ibc-go/releases/tag/v4.4.1) - 2023-05-25 + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v4.4.0](https://github.com/cosmos/ibc-go/releases/tag/v4.4.0) - 2023-04-25 + +### Dependencies + +* [\#3416](https://github.com/cosmos/ibc-go/pull/3416) Bump Cosmos SDK to v0.45.15 and replace Tendermint with CometBFT v0.34.27. + +## [v4.3.1](https://github.com/cosmos/ibc-go/releases/tag/v4.3.1) - 2023-05-25 + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v4.3.0](https://github.com/cosmos/ibc-go/releases/tag/v4.3.0) - 2023-01-24 + +### Dependencies + +* [\#3049](https://github.com/cosmos/ibc-go/pull/3049) Bump Cosmos SDK to v0.45.12. +* [\#2868](https://github.com/cosmos/ibc-go/pull/2868) Bump ics23 to v0.9.0. + +### State Machine Breaking + +* (core/04-channel) [\#2973](https://github.com/cosmos/ibc-go/pull/2973) Write channel state before invoking app callbacks in ack and confirm channel handshake steps. + +### Improvements + +* (apps/29-fee) [\#2786](https://github.com/cosmos/ibc-go/pull/2786) Save gas on `IsFeeEnabled`. + +### Bug Fixes + +* (apps/29-fee) [\#2942](https://github.com/cosmos/ibc-go/pull/2942) Check `x/bank` send enabled before escrowing fees. + +### Documentation + +* [\#2737](https://github.com/cosmos/ibc-go/pull/2737) Fix migration/docs for ICA controller middleware. + +### Miscellaneous Tasks + +* [\#2772](https://github.com/cosmos/ibc-go/pull/2772) Integrated git cliff into the code base to automate generation of changelogs. + +## [v4.2.2](https://github.com/cosmos/ibc-go/releases/tag/v4.2.2) - 2023-05-25 + +### Bug Fixes + +* [\#3661](https://github.com/cosmos/ibc-go/pull/3661) Revert state-machine breaking improvement from PR [#2786](https://github.com/cosmos/ibc-go/pull/2786). + +## [v4.2.1](https://github.com/cosmos/ibc-go/releases/tag/v4.2.1) - 2023-05-25 + +### Dependencies + +* [\#2868](https://github.com/cosmos/ibc-go/pull/2868) Bump ICS 23 to v0.9.0. + +### Improvements + +* (apps/29-fee) [\#2786](https://github.com/cosmos/ibc-go/pull/2786) Save gas by checking key existence with `KVStore`'s `Has` method. + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v4.2.0](https://github.com/cosmos/ibc-go/releases/tag/v4.2.0) - 2022-11-07 + +### Dependencies + +* [\#2588](https://github.com/cosmos/ibc-go/pull/2588) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (27-interchain-accounts) [\#2590](https://github.com/cosmos/ibc-go/pull/2590) Removing port prefix requirement from the ICA host channel handshake +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. + +### Features + +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. + +## [v4.1.3](https://github.com/cosmos/ibc-go/releases/tag/v4.1.3) - 2023-05-25 + +### Bug Fixes + +* [\#3660](https://github.com/cosmos/ibc-go/pull/3660) Revert state-machine breaking improvement from PR [#2786](https://github.com/cosmos/ibc-go/pull/2786). + +## [v4.1.2](https://github.com/cosmos/ibc-go/releases/tag/v4.1.2) - 2023-05-25 + +### Dependencies + +* [\#2868](https://github.com/cosmos/ibc-go/pull/2868) Bump ICS 23 to v0.9.0. + +### Improvements + +* (apps/29-fee) [\#2786](https://github.com/cosmos/ibc-go/pull/2786) Save gas by checking key existence with `KVStore`'s `Has` method. + +### Bug Fixes + +* [\#3346](https://github.com/cosmos/ibc-go/pull/3346) Properly handle ordered channels in `UnreceivedPackets` query. + +## [v4.1.1](https://github.com/cosmos/ibc-go/releases/tag/v4.1.1) - 2022-10-27 + +### Dependencies + +* [\#2624](https://github.com/cosmos/ibc-go/pull/2624) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +## [v4.1.0](https://github.com/cosmos/ibc-go/releases/tag/v4.1.0) - 2022-09-20 + +### Dependencies + +* [\#2288](https://github.com/cosmos/ibc-go/pull/2288) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +### Features + +* (apps/27-interchain-accounts) [\#2193](https://github.com/cosmos/ibc-go/pull/2193) Adding `InterchainAccount` gRPC query endpoint to ICS27 `controller` submodule to allow users to retrieve registered interchain account addresses. + +### Bug Fixes + +* (27-interchain-accounts) [\#2308](https://github.com/cosmos/ibc-go/pull/2308) Nil checks have been added to ensure services are not registered for nil host or controller keepers. + +## [v4.0.1](https://github.com/cosmos/ibc-go/releases/tag/v4.0.1) - 2022-09-15 + +### Dependencies + +* [\#2287](https://github.com/cosmos/ibc-go/pull/2287) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +## [v4.0.0](https://github.com/cosmos/ibc-go/releases/tag/v4.0.0) - 2022-08-12 + +### Dependencies + +* [\#1627](https://github.com/cosmos/ibc-go/pull/1627) Bump Go version to 1.18 +* [\#1905](https://github.com/cosmos/ibc-go/pull/1905) Bump SDK version to v0.45.7 + +### API Breaking + +* (core/04-channel) [\#1792](https://github.com/cosmos/ibc-go/pull/1792) Remove `PreviousChannelID` from `NewMsgChannelOpenTry` arguments. `MsgChannelOpenTry.ValidateBasic()` returns error if the deprecated `PreviousChannelID` is not empty. +* (core/03-connection) [\#1797](https://github.com/cosmos/ibc-go/pull/1797) Remove `PreviousConnectionID` from `NewMsgConnectionOpenTry` arguments. `MsgConnectionOpenTry.ValidateBasic()` returns error if the deprecated `PreviousConnectionID` is not empty. +* (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 + +* (apps/transfer) [\#1907](https://github.com/cosmos/ibc-go/pull/1907) Blocked module account addresses are no longer allowed to send IBC transfers. +* (apps/27-interchain-accounts) [\#1882](https://github.com/cosmos/ibc-go/pull/1882) Explicitly check length of interchain account packet data in favour of nil check. + +### 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. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +### Features + +* [\#276](https://github.com/cosmos/ibc-go/pull/276) Adding the Fee Middleware module v1 +* (apps/29-fee) [\#1229](https://github.com/cosmos/ibc-go/pull/1229) Adding CLI commands for getting all unrelayed incentivized packets and packet by packet-id. +* (apps/29-fee) [\#1224](https://github.com/cosmos/ibc-go/pull/1224) Adding Query/CounterpartyAddress and CLI to ICS29 fee middleware +* (apps/29-fee) [\#1225](https://github.com/cosmos/ibc-go/pull/1225) Adding Query/FeeEnabledChannel and Query/FeeEnabledChannels with CLIs to ICS29 fee middleware. +* (modules/apps/29-fee) [\#1230](https://github.com/cosmos/ibc-go/pull/1230) Adding CLI command for getting incentivized packets for a specific channel-id. + +### Bug Fixes + +* (apps/29-fee) [\#1774](https://github.com/cosmos/ibc-go/pull/1774) Change non nil relayer assertion to non empty to avoid import/export issues for genesis upgrades. +* (apps/29-fee) [\#1278](https://github.com/cosmos/ibc-go/pull/1278) The URI path for the query to get all incentivized packets for a specific channel did not follow the same format as the rest of queries. +* (modules/core/04-channel)[\#1919](https://github.com/cosmos/ibc-go/pull/1919) Fixed formatting of sequence for packet "acknowledgement written" logs. + +## [v3.4.0](https://github.com/cosmos/ibc-go/releases/tag/v3.4.0) - 2022-11-07 + +### Dependencies + +* [\#2589](https://github.com/cosmos/ibc-go/pull/2589) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (27-interchain-accounts) [\#2590](https://github.com/cosmos/ibc-go/pull/2590) Removing port prefix requirement from the ICA host channel handshake +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. + +### Features + +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. + +## [v3.3.1](https://github.com/cosmos/ibc-go/releases/tag/v3.3.1) - 2022-10-27 + +### Dependencies + +* [\#2621](https://github.com/cosmos/ibc-go/pull/2621) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +## [v3.3.0](https://github.com/cosmos/ibc-go/releases/tag/v3.3.0) - 2022-09-20 + +### Dependencies + +* [\#2286](https://github.com/cosmos/ibc-go/pull/2286) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +### Features + +* (apps/27-interchain-accounts) [\#2193](https://github.com/cosmos/ibc-go/pull/2193) Adding `InterchainAccount` gRPC query endpoint to ICS27 `controller` submodule to allow users to retrieve registered interchain account addresses. + +### Bug Fixes + +* (27-interchain-accounts) [\#2308](https://github.com/cosmos/ibc-go/pull/2308) Nil checks have been added to ensure services are not registered for nil host or controller keepers. + +## [v3.2.1](https://github.com/cosmos/ibc-go/releases/tag/v3.2.1) - 2022-09-15 + +### Dependencies + +* [\#2285](https://github.com/cosmos/ibc-go/pull/2285) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +## [v3.2.0](https://github.com/cosmos/ibc-go/releases/tag/v3.2.0) - 2022-08-12 + +### Dependencies + +* [\#1627](https://github.com/cosmos/ibc-go/pull/1627) Bump Go version to 1.18 +* [\#1905](https://github.com/cosmos/ibc-go/pull/1905) Bump SDK version to v0.45.7 + +### State Machine Breaking + +* (apps/transfer) [\#1907](https://github.com/cosmos/ibc-go/pull/1907) Blocked module account addresses are no longer allowed to send IBC transfers. +* (apps/27-interchain-accounts) [\#1882](https://github.com/cosmos/ibc-go/pull/1882) Explicitly check length of interchain account packet data in favour of nil check. + +### Improvements + +* (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. +* (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. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +### Bug Fixes + +* (modules/core/04-channel)[\#1919](https://github.com/cosmos/ibc-go/pull/1919) Fixed formatting of sequence for packet "acknowledgement written" logs. + +## [v3.1.1](https://github.com/cosmos/ibc-go/releases/tag/v3.1.1) - 2022-08-02 + +### Dependencies + +* [\#1525](https://github.com/cosmos/ibc-go/pull/1525) Bump SDK version to v0.45.5 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v3.1.0](https://github.com/cosmos/ibc-go/releases/tag/v3.1.0) - 2022-06-14 + +### Dependencies + +* [\#1300](https://github.com/cosmos/ibc-go/pull/1300) Bump SDK version to v0.45.4 + +### Improvements + +* (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. +* (modules/core/04-channel) [\#1160](https://github.com/cosmos/ibc-go/pull/1160) Improve `uint64 -> string` performance in `Logger`. +* (modules/core/04-channel) [\#1279](https://github.com/cosmos/ibc-go/pull/1279) Add selected channel version to MsgChanOpenInitResponse and MsgChanOpenTryResponse. Emit channel version during OpenInit/OpenTry +* (modules/core/keeper) [\#1284](https://github.com/cosmos/ibc-go/pull/1284) Add sanity check for the keepers passed into `ibckeeper.NewKeeper`. `ibckeeper.NewKeeper` now panics if any of the keepers passed in is empty. +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. +* (modules/core/04-channel) [\#1464](https://github.com/cosmos/ibc-go/pull/1464) Emit a channel close event when an ordered channel is closed. +* (modules/light-clients/07-tendermint) [\#1118](https://github.com/cosmos/ibc-go/pull/1118) Deprecating `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehaviour`. See ADR-026 for context. + +### Features + +* (modules/core/02-client) [\#1336](https://github.com/cosmos/ibc-go/pull/1336) Adding Query/ConsensusStateHeights gRPC for fetching the height of every consensus state associated with a client. +* (modules/apps/transfer) [\#1416](https://github.com/cosmos/ibc-go/pull/1416) Adding gRPC endpoint for getting an escrow account for a given port-id and channel-id. +* (modules/apps/27-interchain-accounts) [\#1512](https://github.com/cosmos/ibc-go/pull/1512) Allowing ICA modules to handle all message types with "*". + +### Bug Fixes + +* (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output +* (apps/transfer) [\#1451](https://github.com/cosmos/ibc-go/pull/1451) Fixing the support for base denoms that contain slashes. + +## [v3.0.2](https://github.com/cosmos/ibc-go/releases/tag/v3.0.2) - 2022-08-02 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v3.0.1](https://github.com/cosmos/ibc-go/releases/tag/v3.0.1) - 2022-06-14 + +### Dependencies + +* [\#1300](https://github.com/cosmos/ibc-go/pull/1300) Bump SDK version to v0.45.4 + +### Improvements + +* (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. +* (modules/core/04-channel) [\#1160](https://github.com/cosmos/ibc-go/pull/1160) Improve `uint64 -> string` performance in `Logger`. +* (modules/core/keeper) [\#1284](https://github.com/cosmos/ibc-go/pull/1284) Add sanity check for the keepers passed into `ibckeeper.NewKeeper`. `ibckeeper.NewKeeper` now panics if any of the keepers passed in is empty. +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. +* (modules/core/04-channel) [\#1464](https://github.com/cosmos/ibc-go/pull/1464) Emit a channel close event when an ordered channel is closed. + +### Bug Fixes + +* (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output + +## [v3.0.0](https://github.com/cosmos/ibc-go/releases/tag/v3.0.0) - 2022-03-15 + +### Dependencies + +* [\#404](https://github.com/cosmos/ibc-go/pull/404) Bump Go version to 1.17 +* [\#851](https://github.com/cosmos/ibc-go/pull/851) Bump SDK version to v0.45.1 +* [\#948](https://github.com/cosmos/ibc-go/pull/948) Bump ics23/go to v0.7 +* (core) [\#709](https://github.com/cosmos/ibc-go/pull/709) Replace github.com/pkg/errors with stdlib errors + +### API Breaking + +* (testing) [\#939](https://github.com/cosmos/ibc-go/pull/939) Support custom power reduction for testing. +* (modules/core/05-port) [\#1086](https://github.com/cosmos/ibc-go/pull/1086) Added `counterpartyChannelID` argument to IBCModule.OnChanOpenAck +* (channel) [\#848](https://github.com/cosmos/ibc-go/pull/848) Added `ChannelId` to MsgChannelOpenInitResponse +* (testing) [\#813](https://github.com/cosmos/ibc-go/pull/813) The `ack` argument to the testing function `RelayPacket` has been removed as it is no longer needed. +* (testing) [\#774](https://github.com/cosmos/ibc-go/pull/774) Added `ChainID` arg to `SetupWithGenesisValSet` on the testing app. `Coordinator` generated ChainIDs now starts at index 1 +* (transfer) [\#675](https://github.com/cosmos/ibc-go/pull/675) Transfer `NewKeeper` now takes in an ICS4Wrapper. The ICS4Wrapper may be the IBC Channel Keeper when ICS20 is not used in a middleware stack. The ICS4Wrapper is required for applications wishing to connect middleware to ICS20. +* (core) [\#650](https://github.com/cosmos/ibc-go/pull/650) Modify `OnChanOpenTry` IBC application module callback to return the negotiated app version. The version passed into the `MsgChanOpenTry` has been deprecated and will be ignored by core IBC. +* (core) [\#629](https://github.com/cosmos/ibc-go/pull/629) Removes the `GetProofSpecs` from the ClientState interface. This function was previously unused by core IBC. +* (transfer) [\#517](https://github.com/cosmos/ibc-go/pull/517) Separates the ICS 26 callback functions from `AppModule` into a new type `IBCModule` for ICS 20 transfer. +* (modules/core/02-client) [\#536](https://github.com/cosmos/ibc-go/pull/536) `GetSelfConsensusState` return type changed from bool to error. +* (channel) [\#644](https://github.com/cosmos/ibc-go/pull/644) Removes `CounterpartyHops` function from the ChannelKeeper. +* (testing) [\#776](https://github.com/cosmos/ibc-go/pull/776) Adding helper fn to generate capability name for testing callbacks +* (testing) [\#892](https://github.com/cosmos/ibc-go/pull/892) IBC Mock modules store the scoped keeper and portID within the IBCMockApp. They also maintain reference to the AppModule to update the AppModule's list of IBC applications it references. Allows for the mock module to be reused as a base application in middleware stacks. +* (channel) [\#882](https://github.com/cosmos/ibc-go/pull/882) The `WriteAcknowledgement` API now takes `exported.Acknowledgement` instead of a byte array +* (modules/core/ante) [\#950](https://github.com/cosmos/ibc-go/pull/950) Replaces the channel keeper with the IBC keeper in the IBC `AnteDecorator` in order to execute the entire message and be able to reject redundant messages that are in the same block as the non-redundant messages. + +### State Machine Breaking + +* (transfer) [\#818](https://github.com/cosmos/ibc-go/pull/818) Error acknowledgements returned from Transfer `OnRecvPacket` now include a deterministic ABCI code and error message. + +### Improvements + +* (client) [\#888](https://github.com/cosmos/ibc-go/pull/888) Add `GetTimestampAtHeight` to `ClientState` +* (interchain-accounts) [\#1037](https://github.com/cosmos/ibc-go/pull/1037) Add a function `InitModule` to the interchain accounts `AppModule`. This function should be called within the upgrade handler when adding the interchain accounts module to a chain. It should be called in place of InitGenesis (set the consensus version in the version map). +* (testing) [\#942](https://github.com/cosmos/ibc-go/pull/942) `NewTestChain` will create 4 validators in validator set by default. A new constructor function `NewTestChainWithValSet` is provided for test writers who want custom control over the validator set of test chains. +* (testing) [\#904](https://github.com/cosmos/ibc-go/pull/904) Add `ParsePacketFromEvents` function to the testing package. Useful when sending/relaying packets via the testing package. +* (testing) [\#893](https://github.com/cosmos/ibc-go/pull/893) Support custom private keys for testing. +* (testing) [\#810](https://github.com/cosmos/ibc-go/pull/810) Additional testing function added to `Endpoint` type called `RecvPacketWithResult`. Performs the same functionality as the existing `RecvPacket` function but also returns the message result. `path.RelayPacket` no longer uses the provided acknowledgement argument and instead obtains the acknowledgement via MsgRecvPacket events. +* (connection) [\#721](https://github.com/cosmos/ibc-go/pull/721) Simplify connection handshake error messages when unpacking client state. +* (channel) [\#692](https://github.com/cosmos/ibc-go/pull/692) Minimize channel logging by only emitting the packet sequence, source port/channel, destination port/channel upon packet receives, acknowledgements and timeouts. +* [\#383](https://github.com/cosmos/ibc-go/pull/383) Adds helper functions for merging and splitting middleware versions from the underlying app version. +* (modules/core/05-port) [\#288](https://github.com/cosmos/ibc-go/pull/288) Making the 05-port keeper function IsBound public. The IsBound function checks if the provided portID is already binded to a module. +* (client) [\#724](https://github.com/cosmos/ibc-go/pull/724) `IsRevisionFormat` and `IsClientIDFormat` have been updated to disallow newlines before the dash used to separate the chainID and revision number, and the client type and client sequence. +* (channel) [\#644](https://github.com/cosmos/ibc-go/pull/644) Adds `GetChannelConnection` to the ChannelKeeper. This function returns the connectionID and connection state associated with a channel. +* (channel) [\647](https://github.com/cosmos/ibc-go/pull/647) Reorganizes channel handshake handling to set channel state after IBC application callbacks. +* (interchain-accounts) [\#1466](https://github.com/cosmos/ibc-go/pull/1466) Emit event when there is an acknowledgement during `OnRecvPacket`. + +### Features + +* [\#432](https://github.com/cosmos/ibc-go/pull/432) Introduce `MockIBCApp` struct to the mock module. Allows the mock module to be reused to perform custom logic on each IBC App interface function. This might be useful when testing out IBC applications written as middleware. +* [\#380](https://github.com/cosmos/ibc-go/pull/380) Adding the Interchain Accounts module v1 +* [\#679](https://github.com/cosmos/ibc-go/pull/679) New CLI command `query ibc-transfer denom-hash ` to get the denom hash for a denom trace; this might be useful for debug + +### Bug Fixes + +* (testing) [\#884](https://github.com/cosmos/ibc-go/pull/884) Add and use in simapp a custom ante handler that rejects redundant transactions +* (transfer) [\#978](https://github.com/cosmos/ibc-go/pull/978) Support base denoms with slashes in denom validation +* (client) [\#941](https://github.com/cosmos/ibc-go/pull/941) Classify client states without consensus states as expired +* (channel) [\#995](https://github.com/cosmos/ibc-go/pull/995) Call `packet.GetSequence()` rather than passing func in `AcknowledgePacket` log output + +## [v2.5.0](https://github.com/cosmos/ibc-go/releases/tag/v2.5.0) - 2022-11-07 + +### Dependencies + +* [\#2578](https://github.com/cosmos/ibc-go/pull/2578) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. + +### Features + +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. + +## [v2.4.2](https://github.com/cosmos/ibc-go/releases/tag/v2.4.2) - 2022-10-27 + +### Dependencies + +* [\#2622](https://github.com/cosmos/ibc-go/pull/2622) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +## [v2.4.1](https://github.com/cosmos/ibc-go/releases/tag/v2.4.1) - 2022-09-15 + +### Dependencies + +* [\#2284](https://github.com/cosmos/ibc-go/pull/2284) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +## [v2.4.0](https://github.com/cosmos/ibc-go/releases/tag/v2.4.0) - 2022-08-12 + +### Dependencies + +* [\#1627](https://github.com/cosmos/ibc-go/pull/1627) Bump Go version to 1.18 +* [\#1905](https://github.com/cosmos/ibc-go/pull/1905) Bump SDK version to v0.45.7 + +### State Machine Breaking + +* (apps/transfer) [\#1907](https://github.com/cosmos/ibc-go/pull/1907) Blocked module account addresses are no longer allowed to send IBC transfers. + +### Improvements + +* (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. +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (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. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +### Bug Fixes + +* (modules/core/04-channel)[\#1919](https://github.com/cosmos/ibc-go/pull/1919) Fixed formatting of sequence for packet "acknowledgement written" logs. + +## [v2.3.1](https://github.com/cosmos/ibc-go/releases/tag/v2.3.1) - 2022-08-02 + +### Dependencies + +* [\#1525](https://github.com/cosmos/ibc-go/pull/1525) Bump SDK version to v0.45.5 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v2.3.0](https://github.com/cosmos/ibc-go/releases/tag/v2.3.0) - 2022-06-14 + +### Dependencies + +* [\#404](https://github.com/cosmos/ibc-go/pull/404) Bump Go version to 1.17 +* [\#1300](https://github.com/cosmos/ibc-go/pull/1300) Bump SDK version to v0.45.4 + +### Improvements + +* (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. +* (modules/core/04-channel) [\#1160](https://github.com/cosmos/ibc-go/pull/1160) Improve `uint64 -> string` performance in `Logger`. +* (modules/core/keeper) [\#1284](https://github.com/cosmos/ibc-go/pull/1284) Add sanity check for the keepers passed into `ibckeeper.NewKeeper`. `ibckeeper.NewKeeper` now panics if any of the keepers passed in is empty. +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. +* (modules/core/04-channel) [\#1464](https://github.com/cosmos/ibc-go/pull/1464) Emit a channel close event when an ordered channel is closed. +* (modules/light-clients/07-tendermint) [\#1118](https://github.com/cosmos/ibc-go/pull/1118) Deprecating `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehaviour`. See ADR-026 for context. + +### Features + +* (modules/core/02-client) [\#1336](https://github.com/cosmos/ibc-go/pull/1336) Adding Query/ConsensusStateHeights gRPC for fetching the height of every consensus state associated with a client. +* (modules/apps/transfer) [\#1416](https://github.com/cosmos/ibc-go/pull/1416) Adding gRPC endpoint for getting an escrow account for a given port-id and channel-id. + +### Bug Fixes + +* (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output +* (apps/transfer) [\#1451](https://github.com/cosmos/ibc-go/pull/1451) Fixing the support for base denoms that contain slashes. + +## [v2.2.2](https://github.com/cosmos/ibc-go/releases/tag/v2.2.2) - 2022-08-02 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v2.2.1](https://github.com/cosmos/ibc-go/releases/tag/v2.2.1) - 2022-06-14 + +### Improvements + +* (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. +* (modules/core/04-channel) [\#1160](https://github.com/cosmos/ibc-go/pull/1160) Improve `uint64 -> string` performance in `Logger`. +* (modules/core/keeper) [\#1284](https://github.com/cosmos/ibc-go/pull/1284) Add sanity check for the keepers passed into `ibckeeper.NewKeeper`. `ibckeeper.NewKeeper` now panics if any of the keepers passed in is empty. +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. +* (modules/core/04-channel) [\#1464](https://github.com/cosmos/ibc-go/pull/1464) Emit a channel close event when an ordered channel is closed. + +### Bug Fixes + +* (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output + +## [v2.2.0](https://github.com/cosmos/ibc-go/releases/tag/v2.2.0) - 2022-03-15 + +### Dependencies + +* [\#851](https://github.com/cosmos/ibc-go/pull/851) Bump SDK version to v0.45.1 + +## [v2.1.2](https://github.com/cosmos/ibc-go/releases/tag/v2.1.2) - 2022-08-02 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v2.1.1](https://github.com/cosmos/ibc-go/releases/tag/v2.1.1) - 2022-06-14 + +### Dependencies + +* [\#1268](https://github.com/cosmos/ibc-go/pull/1268) Bump SDK version to v0.44.8 and Tendermint to version 0.34.19 + +### Improvements + +* (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. +* (modules/core/keeper) [\#1284](https://github.com/cosmos/ibc-go/pull/1284) Add sanity check for the keepers passed into `ibckeeper.NewKeeper`. `ibckeeper.NewKeeper` now panics if any of the keepers passed in is empty. +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. +* (modules/core/04-channel) [\#1464](https://github.com/cosmos/ibc-go/pull/1464) Emit a channel close event when an ordered channel is closed. + +### Bug Fixes + +* (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output + +## [v2.1.0](https://github.com/cosmos/ibc-go/releases/tag/v2.1.0) - 2022-03-15 + +### Dependencies + +* [\#1084](https://github.com/cosmos/ibc-go/pull/1084) Bump SDK version to v0.44.6 +* [\#948](https://github.com/cosmos/ibc-go/pull/948) Bump ics23/go to v0.7 + +### State Machine Breaking + +* (transfer) [\#818](https://github.com/cosmos/ibc-go/pull/818) Error acknowledgements returned from Transfer `OnRecvPacket` now include a deterministic ABCI code and error message. + +### Features + +* [\#679](https://github.com/cosmos/ibc-go/pull/679) New CLI command `query ibc-transfer denom-hash ` to get the denom hash for a denom trace; this might be useful for debug + +### Bug Fixes + +* (client) [\#941](https://github.com/cosmos/ibc-go/pull/941) Classify client states without consensus states as expired +* (transfer) [\#978](https://github.com/cosmos/ibc-go/pull/978) Support base denoms with slashes in denom validation +* (channel) [\#995](https://github.com/cosmos/ibc-go/pull/995) Call `packet.GetSequence()` rather than passing func in `AcknowledgePacket` log output + +## [v2.0.3](https://github.com/cosmos/ibc-go/releases/tag/v2.0.3) - 2022-02-03 + +### Improvements + +* (channel) [\#692](https://github.com/cosmos/ibc-go/pull/692) Minimize channel logging by only emitting the packet sequence, source port/channel, destination port/channel upon packet receives, acknowledgements and timeouts. + +## [v2.0.2](https://github.com/cosmos/ibc-go/releases/tag/v2.0.2) - 2021-12-15 + +### Dependencies + +* [\#589](https://github.com/cosmos/ibc-go/pull/589) Bump SDK version to v0.44.5 + +### Bug Fixes + +* (modules/core) [\#603](https://github.com/cosmos/ibc-go/pull/603) Fix module name emitted as part of `OnChanOpenInit` event. Replacing `connection` module name with `channel`. + +## [v2.0.1](https://github.com/cosmos/ibc-go/releases/tag/v2.0.1) - 2021-12-05 + +### Dependencies + +* [\#567](https://github.com/cosmos/ibc-go/pull/567) Bump SDK version to v0.44.4 + +### Improvements + +* (02-client) [\#568](https://github.com/cosmos/ibc-go/pull/568) In IBC `transfer` cli command use local clock time as reference for relative timestamp timeout if greater than the block timestamp queried from the latest consensus state corresponding to the counterparty channel. +* [\#583](https://github.com/cosmos/ibc-go/pull/583) Move third_party/proto/confio/proofs.proto to third_party/proto/proofs.proto to enable proto service reflection. Migrate `buf` from v1beta1 to v1. + +### Bug Fixes + +* (02-client) [\#500](https://github.com/cosmos/ibc-go/pull/500) Fix IBC `update-client proposal` cli command to expect correct number of args. + +## [v2.0.0](https://github.com/cosmos/ibc-go/releases/tag/v2.0.0) - 2021-11-09 + +### Dependencies + +* [\#489](https://github.com/cosmos/ibc-go/pull/489) Bump Tendermint to v0.34.14 +* [\#503](https://github.com/cosmos/ibc-go/pull/503) Bump SDK version to v0.44.3 + +### API Breaking + +* (core) [\#227](https://github.com/cosmos/ibc-go/pull/227) Remove sdk.Result from application callbacks +* (transfer) [\#350](https://github.com/cosmos/ibc-go/pull/350) Change FungibleTokenPacketData to use a string for the Amount field. This enables token transfers with amounts previously restricted by uint64. Up to the maximum uint256 value is supported. + +### Features + +* [\#384](https://github.com/cosmos/ibc-go/pull/384) Added `NegotiateAppVersion` method to `IBCModule` interface supported by a gRPC query service in `05-port`. This provides routing of requests to the desired application module callback, which in turn performs application version negotiation. + +## [v1.5.0](https://github.com/cosmos/ibc-go/releases/tag/v1.5.0) - 2022-06-14 + +### Dependencies + +* [\#404](https://github.com/cosmos/ibc-go/pull/404) Bump Go version to 1.17 +* [\#1300](https://github.com/cosmos/ibc-go/pull/1300) Bump SDK version to v0.45.4 + +### Improvements + +* (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. +* (modules/core/04-channel) [\#1160](https://github.com/cosmos/ibc-go/pull/1160) Improve `uint64 -> string` performance in `Logger`. +* (modules/core/keeper) [\#1284](https://github.com/cosmos/ibc-go/pull/1284) Add sanity check for the keepers passed into `ibckeeper.NewKeeper`. `ibckeeper.NewKeeper` now panics if any of the keepers passed in is empty. +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. +* (modules/core/04-channel) [\#1464](https://github.com/cosmos/ibc-go/pull/1464) Emit a channel close event when an ordered channel is closed. +* (modules/light-clients/07-tendermint) [\#1118](https://github.com/cosmos/ibc-go/pull/1118) Deprecating `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehaviour`. See ADR-026 for context. + +### Features + +* (modules/core/02-client) [\#1336](https://github.com/cosmos/ibc-go/pull/1336) Adding Query/ConsensusStateHeights gRPC for fetching the height of every consensus state associated with a client. +* (modules/apps/transfer) [\#1416](https://github.com/cosmos/ibc-go/pull/1416) Adding gRPC endpoint for getting an escrow account for a given port-id and channel-id. + +### Bug Fixes + +* (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output +* (apps/transfer) [\#1451](https://github.com/cosmos/ibc-go/pull/1451) Fixing the support for base denoms that contain slashes. + +## [v1.4.1](https://github.com/cosmos/ibc-go/releases/tag/v1.4.1) - 2022-06-14 + +### Improvements + +* (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. +* (modules/core/04-channel) [\#1160](https://github.com/cosmos/ibc-go/pull/1160) Improve `uint64 -> string` performance in `Logger`. +* (modules/core/keeper) [\#1284](https://github.com/cosmos/ibc-go/pull/1284) Add sanity check for the keepers passed into `ibckeeper.NewKeeper`. `ibckeeper.NewKeeper` now panics if any of the keepers passed in is empty. +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. +* (modules/core/04-channel) [\#1464](https://github.com/cosmos/ibc-go/pull/1464) Emit a channel close event when an ordered channel is closed. + +### Bug Fixes + +* (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output + +## [v1.4.0](https://github.com/cosmos/ibc-go/releases/tag/v1.4.0) - 2022-03-15 + +### Dependencies + +* [\#851](https://github.com/cosmos/ibc-go/pull/851) Bump SDK version to v0.45.1 + +## [v1.3.1](https://github.com/cosmos/ibc-go/releases/tag/v1.3.1) - 2022-06-14 + +### Dependencies + +* [\#1267](https://github.com/cosmos/ibc-go/pull/1267) Bump SDK version to v0.44.8 and Tendermint to version 0.34.19 + +### Improvements + +* (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. +* (modules/core/04-channel) [\#1160](https://github.com/cosmos/ibc-go/pull/1160) Improve `uint64 -> string` performance in `Logger`. +* (modules/core/keeper) [\#1284](https://github.com/cosmos/ibc-go/pull/1284) Add sanity check for the keepers passed into `ibckeeper.NewKeeper`. `ibckeeper.NewKeeper` now panics if any of the keepers passed in is empty. +* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. +* (modules/core/04-channel) [\#1464](https://github.com/cosmos/ibc-go/pull/1464) Emit a channel close event when an ordered channel is closed. + +### Bug Fixes + +* (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output + +## [v1.3.0](https://github.com/cosmos/ibc-go/releases/tag/v1.3.0) - 2022-03-15 + +### Dependencies + +* [\#1073](https://github.com/cosmos/ibc-go/pull/1073) Bump SDK version to v0.44.6 +* [\#948](https://github.com/cosmos/ibc-go/pull/948) Bump ics23/go to v0.7 + +### State Machine Breaking + +* (transfer) [\#818](https://github.com/cosmos/ibc-go/pull/818) Error acknowledgements returned from Transfer `OnRecvPacket` now include a deterministic ABCI code and error message. + +### Features + +* [\#679](https://github.com/cosmos/ibc-go/pull/679) New CLI command `query ibc-transfer denom-hash ` to get the denom hash for a denom trace; this might be useful for debug + +### Bug Fixes + +* (client) [\#941](https://github.com/cosmos/ibc-go/pull/941) Classify client states without consensus states as expired +* (transfer) [\#978](https://github.com/cosmos/ibc-go/pull/978) Support base denoms with slashes in denom validation +* (channel) [\#995](https://github.com/cosmos/ibc-go/pull/995) Call `packet.GetSequence()` rather than passing func in `AcknowledgePacket` log output + +## [v1.2.6](https://github.com/cosmos/ibc-go/releases/tag/v1.2.6) - 2022-02-03 + +### Improvements + +* (channel) [\#692](https://github.com/cosmos/ibc-go/pull/692) Minimize channel logging by only emitting the packet sequence, source port/channel, destination port/channel upon packet receives, acknowledgements and timeouts. + +## [v1.2.5](https://github.com/cosmos/ibc-go/releases/tag/v1.2.5) - 2021-12-15 + +### Dependencies + +* [\#589](https://github.com/cosmos/ibc-go/pull/589) Bump SDK version to v0.44.5 + +### Bug Fixes + +* (modules/core) [\#603](https://github.com/cosmos/ibc-go/pull/603) Fix module name emitted as part of `OnChanOpenInit` event. Replacing `connection` module name with `channel`. + +## [v1.2.4](https://github.com/cosmos/ibc-go/releases/tag/v1.2.4) - 2021-12-05 + +### Dependencies + +* [\#567](https://github.com/cosmos/ibc-go/pull/567) Bump SDK version to v0.44.4 + +### Improvements + +* [\#583](https://github.com/cosmos/ibc-go/pull/583) Move third_party/proto/confio/proofs.proto to third_party/proto/proofs.proto to enable proto service reflection. Migrate `buf` from v1beta1 to v1. + +## [v1.2.3](https://github.com/cosmos/ibc-go/releases/tag/v1.2.3) - 2021-11-09 + +### Dependencies + +* [\#489](https://github.com/cosmos/ibc-go/pull/489) Bump Tendermint to v0.34.14 +* [\#503](https://github.com/cosmos/ibc-go/pull/503) Bump SDK version to v0.44.3 + +## [v1.2.2](https://github.com/cosmos/ibc-go/releases/tag/v1.2.2) - 2021-10-15 + +### Dependencies + +* [\#485](https://github.com/cosmos/ibc-go/pull/485) Bump SDK version to v0.44.2 + +## [v1.2.1](https://github.com/cosmos/ibc-go/releases/tag/v1.2.1) - 2021-10-04 + +### Dependencies + +* [\#455](https://github.com/cosmos/ibc-go/pull/455) Bump SDK version to v0.44.1 + +## [v1.2.0](https://github.com/cosmos/ibc-go/releases/tag/v1.2.0) - 2021-09-10 + +### State Machine Breaking + +* (24-host) [\#344](https://github.com/cosmos/ibc-go/pull/344) Increase port identifier limit to 128 characters. + +### Improvements + +* [\#373](https://github.com/cosmos/ibc-go/pull/375) Added optional field `PacketCommitmentSequences` to `QueryPacketAcknowledgementsRequest` to provide filtering of packet acknowledgements. + +### Features + +* [\#372](https://github.com/cosmos/ibc-go/pull/372) New CLI command `query ibc client status ` to get the current activity status of a client. + +### Dependencies + +* [\#386](https://github.com/cosmos/ibc-go/pull/386) Bump [tendermint](https://github.com/tendermint/tendermint) from v0.34.12 to v0.34.13. + +## [v1.1.6](https://github.com/cosmos/ibc-go/releases/tag/v1.1.6) - 2022-01-25 + +### Improvements + +* (channel) [\#692](https://github.com/cosmos/ibc-go/pull/692) Minimize channel logging by only emitting the packet sequence, source port/channel, destination port/channel upon packet receives, acknowledgements and timeouts. + +## [v1.1.5](https://github.com/cosmos/ibc-go/releases/tag/v1.1.5) - 2021-12-15 + +### Dependencies + +* [\#589](https://github.com/cosmos/ibc-go/pull/589) Bump SDK version to v0.44.5 + +### Bug Fixes + +* (modules/core) [\#603](https://github.com/cosmos/ibc-go/pull/603) Fix module name emitted as part of `OnChanOpenInit` event. Replacing `connection` module name with `channel`. + +## [v1.1.4](https://github.com/cosmos/ibc-go/releases/tag/v1.1.4) - 2021-12-05 + +### Dependencies + +* [\#567](https://github.com/cosmos/ibc-go/pull/567) Bump SDK version to v0.44.4 + +### Improvements + +* [\#583](https://github.com/cosmos/ibc-go/pull/583) Move third_party/proto/confio/proofs.proto to third_party/proto/proofs.proto to enable proto service reflection. Migrate `buf` from v1beta1 to v1. + +## [v1.1.3](https://github.com/cosmos/ibc-go/releases/tag/v1.1.3) - 2021-11-09 + +### Dependencies + +* [\#489](https://github.com/cosmos/ibc-go/pull/489) Bump Tendermint to v0.34.14 +* [\#503](https://github.com/cosmos/ibc-go/pull/503) Bump SDK version to v0.44.3 + +## [v1.1.2](https://github.com/cosmos/ibc-go/releases/tag/v1.1.2) - 2021-10-15 + +* [\#485](https://github.com/cosmos/ibc-go/pull/485) Bump SDK version to v0.44.2 + +## [v1.1.1](https://github.com/cosmos/ibc-go/releases/tag/v1.1.1) - 2021-10-04 + +### Dependencies + +* [\#455](https://github.com/cosmos/ibc-go/pull/455) Bump SDK version to v0.44.1 + +## [v1.1.0](https://github.com/cosmos/ibc-go/releases/tag/v1.1.0) - 2021-09-03 + +### Dependencies + +* [\#367](https://github.com/cosmos/ibc-go/pull/367) Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) from 0.43 to 0.44. + +## [v1.0.1](https://github.com/cosmos/ibc-go/releases/tag/v1.0.1) - 2021-08-25 + +### Improvements + +* [\#343](https://github.com/cosmos/ibc-go/pull/343) Create helper functions for publishing of packet sent and acknowledgement sent events. + +## [v1.0.0](https://github.com/cosmos/ibc-go/releases/tag/v1.0.0) - 2021-08-10 + +### Bug Fixes + +* (07-tendermint) [\#241](https://github.com/cosmos/ibc-go/pull/241) Ensure tendermint client state latest height revision number matches chain id revision number. +* (07-tendermint) [\#234](https://github.com/cosmos/ibc-go/pull/234) Use sentinel value for the consensus state root set during a client upgrade. This prevents genesis validation from failing. +* (modules) [\#223](https://github.com/cosmos/ibc-go/pull/223) Use correct Prometheus format for metric labels. +* (06-solomachine) [\#214](https://github.com/cosmos/ibc-go/pull/214) Disable defensive timestamp check in SendPacket for solo machine clients. +* (07-tendermint) [\#210](https://github.com/cosmos/ibc-go/pull/210) Export all consensus metadata on genesis restarts for tendermint clients. +* (core) [\#200](https://github.com/cosmos/ibc-go/pull/200) Fixes incorrect export of IBC identifier sequences. Previously, the next identifier sequence for clients/connections/channels was not set during genesis export. This resulted in the next identifiers being generated on the new chain to reuse old identifiers (the sequences began again from 0). +* (02-client) [\#192](https://github.com/cosmos/ibc-go/pull/192) Fix IBC `query ibc client header` cli command. Support historical queries for query header/node-state commands. +* (modules/light-clients/06-solomachine) [\#153](https://github.com/cosmos/ibc-go/pull/153) Fix solo machine proof height sequence mismatch bug. +* (modules/light-clients/06-solomachine) [\#122](https://github.com/cosmos/ibc-go/pull/122) Fix solo machine merkle prefix casting bug. +* (modules/light-clients/06-solomachine) [\#120](https://github.com/cosmos/ibc-go/pull/120) Fix solo machine handshake verification bug. +* (modules/light-clients/06-solomachine) [\#153](https://github.com/cosmos/ibc-go/pull/153) fix solo machine connection handshake failure at `ConnectionOpenAck`. + +### API Breaking + +* (04-channel) [\#220](https://github.com/cosmos/ibc-go/pull/220) Channel legacy handler functions were removed. Please use the MsgServer functions or directly call the channel keeper's handshake function. +* (modules) [\#206](https://github.com/cosmos/ibc-go/pull/206) Expose `relayer sdk.AccAddress` on `OnRecvPacket`, `OnAcknowledgementPacket`, `OnTimeoutPacket` module callbacks to enable incentivization. +* (02-client) [\#181](https://github.com/cosmos/ibc-go/pull/181) Remove 'InitialHeight' from UpdateClient Proposal. Only copy over latest consensus state from substitute client. +* (06-solomachine) [\#169](https://github.com/cosmos/ibc-go/pull/169) Change FrozenSequence to boolean in solomachine ClientState. The solo machine proto package has been bumped from `v1` to `v2`. +* (module/core/02-client) [\#165](https://github.com/cosmos/ibc-go/pull/165) Remove GetFrozenHeight from the ClientState interface. +* (modules) [\#166](https://github.com/cosmos/ibc-go/pull/166) Remove GetHeight from the misbehaviour interface. The `consensus_height` attribute has been removed from Misbehaviour events. +* (modules) [\#162](https://github.com/cosmos/ibc-go/pull/162) Remove deprecated Handler types in core IBC and the ICS 20 transfer module. +* (modules/core) [\#161](https://github.com/cosmos/ibc-go/pull/161) Remove Type(), Route(), GetSignBytes() from 02-client, 03-connection, and 04-channel messages. +* (modules) [\#140](https://github.com/cosmos/ibc-go/pull/140) IsFrozen() client state interface changed to Status(). gRPC `ClientStatus` route added. +* (modules/core) [\#109](https://github.com/cosmos/ibc-go/pull/109) Remove connection and channel handshake CLI commands. +* (modules) [\#107](https://github.com/cosmos/ibc-go/pull/107) Modify OnRecvPacket callback to return an acknowledgement which indicates if it is successful or not. Callback state changes are discarded for unsuccessful acknowledgements only. +* (modules) [\#108](https://github.com/cosmos/ibc-go/pull/108) All message constructors take the signer as a string to prevent upstream bugs. The `String()` function for an SDK Acc Address relies on external context. +* (transfer) [\#275](https://github.com/cosmos/ibc-go/pull/275) Remove 'ChanCloseInit' function from transfer keeper. ICS20 does not close channels. + +### State Machine Breaking + +* (modules/light-clients/07-tendermint) [\#99](https://github.com/cosmos/ibc-go/pull/99) Enforce maximum chain-id length for tendermint client. +* (modules/light-clients/07-tendermint) [\#141](https://github.com/cosmos/ibc-go/pull/141) Allow a new form of misbehaviour that proves counterparty chain breaks time monotonicity, automatically enforce monotonicity in UpdateClient and freeze client if monotonicity is broken. +* (modules/light-clients/07-tendermint) [\#141](https://github.com/cosmos/ibc-go/pull/141) Freeze the client if there's a conflicting header submitted for an existing consensus state. +* (modules/core/02-client) [\#8405](https://github.com/cosmos/cosmos-sdk/pull/8405) Refactor IBC client update governance proposals to use a substitute client to update a frozen or expired client. +* (modules/core/02-client) [\#8673](https://github.com/cosmos/cosmos-sdk/pull/8673) IBC upgrade logic moved to 02-client and an IBC UpgradeProposal is added. +* (modules/core/03-connection) [\#171](https://github.com/cosmos/ibc-go/pull/171) Introduces a new parameter `MaxExpectedTimePerBlock` to allow connections to calculate and enforce a block delay that is proportional to time delay set by connection. +* (core) [\#268](https://github.com/cosmos/ibc-go/pull/268) Perform a no-op on redundant relay messages. Previous behaviour returned an error. Now no state change will occur and no error will be returned. + +### Improvements + +* (04-channel) [\#220](https://github.com/cosmos/ibc-go/pull/220) Channel handshake events are now emitted with the channel keeper. +* (core/02-client) [\#205](https://github.com/cosmos/ibc-go/pull/205) Add in-place and genesis migrations from SDK v0.42.0 to ibc-go v1.0.0. Solo machine protobuf definitions are migrated from v1 to v2. All solo machine consensus states are pruned. All expired tendermint consensus states are pruned. +* (modules/core) [\#184](https://github.com/cosmos/ibc-go/pull/184) Improve error messages. Uses unique error codes to indicate already relayed packets. +* (07-tendermint) [\#182](https://github.com/cosmos/ibc-go/pull/182) Remove duplicate checks in upgrade logic. +* (modules/core/04-channel) [\#7949](https://github.com/cosmos/cosmos-sdk/issues/7949) Standardized channel `Acknowledgement` moved to its own file. Codec registration redundancy removed. +* (modules/core/04-channel) [\#144](https://github.com/cosmos/ibc-go/pull/144) Introduced a `packet_data_hex` attribute to emit the hex-encoded packet data in events. This allows for raw binary (proto-encoded message) to be sent over events and decoded correctly on relayer. Original `packet_data` is DEPRECATED. All relayers and IBC event consumers are encouraged to switch to `packet_data_hex` as soon as possible. +* (core/04-channel) [\#197](https://github.com/cosmos/ibc-go/pull/197) Introduced a `packet_ack_hex` attribute to emit the hex-encoded acknowledgement in events. This allows for raw binary (proto-encoded message) to be sent over events and decoded correctly on relayer. Original `packet_ack` is DEPRECATED. All relayers and IBC event consumers are encouraged to switch to `packet_ack_hex` as soon as possible. +* (modules/light-clients/07-tendermint) [\#125](https://github.com/cosmos/ibc-go/pull/125) Implement efficient iteration of consensus states and pruning of earliest expired consensus state on UpdateClient. +* (modules/light-clients/07-tendermint) [\#141](https://github.com/cosmos/ibc-go/pull/141) Return early in case there's a duplicate update call to save Gas. +* (modules/core/ante) [\#235](https://github.com/cosmos/ibc-go/pull/235) Introduces a new IBC Antedecorator that will reject transactions that only contain redundant packet messages (and accompany UpdateClient msgs). This will prevent relayers from wasting fees by submitting messages for packets that have already been processed by previous relayer(s). The Antedecorator is only applied on CheckTx and RecheckTx and is therefore optional for each node. + +### Features + +* [\#198](https://github.com/cosmos/ibc-go/pull/198) New CLI command `query ibc-transfer escrow-address ` to get the escrow address for a channel; can be used to then query balance of escrowed tokens + +### Client Breaking Changes + +* (02-client/cli) [\#196](https://github.com/cosmos/ibc-go/pull/196) Rename `node-state` cli command to `self-consensus-state`. + +## IBC in the Cosmos SDK Repository + +The IBC module was originally released in [v0.40.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0) of the SDK. +Please see the [Release Notes](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/RELEASE_NOTES.md). + +The IBC module is also contained in the releases for [v0.41.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.41.0) and [v0.42.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.0). +Please see the Release Notes for [v0.41.x](https://github.com/cosmos/cosmos-sdk/blob/v0.41.0/RELEASE_NOTES.md) and [v0.42.x](https://github.com/cosmos/cosmos-sdk/blob/v0.42.0/RELEASE_NOTES.md). + +The IBC module was removed in the commit hash [da064e13d56add466548135739c5860a9f7ed842](https://github.com/cosmos/cosmos-sdk/commit/da064e13d56add466548135739c5860a9f7ed842) on the SDK. The release for SDK v0.43.0 will be the first release without the IBC module. + +Backports should be made to the [release/v0.42.x](https://github.com/cosmos/cosmos-sdk/tree/release/v0.42.x) branch on the SDK. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..9efa379 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f489727 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,78 @@ +# Contributing to ibc-go + +Thank you for considering making contributions to ibc-go! 🎉👍 + +## Code of conduct + +This project and everyone participating in it is governed by ibc-go's [code of conduct](./CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code + +## How can I contribute? + +Contributing to this repository can mean many things such as participating in discussions or proposing code changes. To ensure a smooth workflow for all contributors, the general procedure for contributing has been established: + +### Reporting bugs + +If you find that something is not working as expected, please open an issue using the [bug report template](https://github.com/cosmos/ibc-go/blob/main/.github/ISSUE_TEMPLATE/bug-report.md) and provide as much information possible: how can the bug be reproduced? What's the expected behavior? What version is affected? + +This is also true if you plan to fix the bug yourself and submit a PR. As a general rule, we want contributing pull requests to reference an existing issue. See [Submitting pull requests](#submitting-pull-requests) + +### Proposing improvements or new features + +New features or improvements should be written in an issue using the [new feature template](https://github.com/cosmos/ibc-go/blob/main/.github/ISSUE_TEMPLATE/feature-request.md). Please include in the issue as many details as possible: what use case(s) would this new feature or improvement enable? Why are those use cases important or helpful? what user group would benefit? The team will evaluate and engage with you in a discussion of the proposal, which could have different outcomes: + +- the core ibc-go team deciding to implement this feature and adding it to their planning, +- agreeing to support external contributors to implement it with the goal of merging it eventually in ibc-go, +- discarding the suggestion if deemed not aligned with the objectives of ibc-go; +- or proposing (in the case of applications or light clients) to be developed and maintained in a separate repository. + +Unless the change is a minor bug fix with minor code changes, and you want to submit a pull request, please make sure to write a Github issue for it before opening the pull request. + +### Architecture Decision Records (ADR) + +When proposing an architecture decision for the ibc-go, please create an [ADR](./docs/architecture/README.md) so further discussions can be made. We are following this process so all involved parties are in agreement before any party begins coding the proposed implementation. Please use the [ADR template](./docs/architecture/adr.template.md) to scaffold any new ADR. If you would like to see some examples of how these are written refer to ibc-go's [ADRs](./docs/architecture/). ADRs are solidified designs that will be implemented in ibc-go (and do not have a spec). They should document the architecture that will be built. Most design feedback should be gathered before the initial draft of the ADR. ADR's can/should be written for any design decisions we make which may be changed at some point in the future. + +### Participating in discussions + +New features or improvements are sometimes also debated in [discussions](https://github.com/cosmos/ibc-go/discussions). Sharing feedback or ideas there is very helpful for us. high level discussions that may get a lot of comments on a variety of different aspects, design aspects still being considered. + +### Submitting pull requests + +Before opening a pull request, make sure there is an accompanying issue that has been assigned to you. +In the case of smaller changes, opening a pull request without being assigned to the issue **can** be accepted, but to avoid having to redesign or discard your work due to the change no longer being needed, asking to be assigned to the issue is the safest course of action. We welcome contributors, but we have put in place these guidelines to safeguard the time of both external and core contributors. + +Unless you feel confident your change will be accepted (see [Unwanted pull requests](#unwanted-pull-requests)) you should first create an issue to discuss your change with us. This lets us all discuss the design and proposed implementation of your change, which helps ensure your time is well spent and that your contribution will be accepted. + +Looking for a good place to start contributing? The issue tracker is always the first place to go. Issues are triaged to categorize them: + +- Check out some [`good first issue`s](https://github.com/cosmos/ibc-go/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). These are issues whose scope of work should be pretty clearly specified and they are best suited for developers new to ibc-go (i.e. no deep knowledge of Cosmos SDK or ibc-go is required). For example, some of these issues may involve improving the logging, emitting new events or removing unused code. +- Or pick up a [`help wanted`](https://github.com/cosmos/ibc-go/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issue. These issues should be a bit more involved than the good first issues and the developer working on them would benefit from some familiarity already with the codebase. These types of issues may involve adding new (or extending the functionality of existing) gRPC endpoints, bumping the version of Cosmos SDK or Tendermint or fixing bugs. + +If you would like to contribute, follow this process: + +1. If the issue is a proposal, ensure that the proposal has been accepted. +2. Ensure that nobody else has already begun working on this issue. If they have, make sure to contact them to collaborate. +3. If nobody has been assigned for the issue and you would like to work on it, comment on the issue to inform the community of your intentions to begin work. Then we will be able to assign the issue to you, making it visible for others that this issue is being tackled. If you end up not creating a pull request for this issue, please comment on the issue as well, so that it can be assigned to somebody else. +4. Follow standard GitHub best practices: fork the repo, branch from the HEAD of `main`, make some commits, and submit a PR to `main`. For core developers working within the ibc-go repo, branches must be named with the convention `{moniker}/{issue#}-branch-name` to ensure a clear ownership of branches. +5. Feel free to submit the pull request in `Draft` mode, even if the work is not complete, as this indicates to the community you are working on something and allows them to provide comments early in the development process. +6. When the code is complete it can be marked `Ready for Review`. +7. Be sure to include a relevant changelog entry in the [Commit Message / Changelog Entry section of pull request description](https://github.com/cosmos/ibc-go/blob/main/.github/PULL_REQUEST_TEMPLATE.md#commit-message--changelog-entry) so that we can add changelog entry when merging the pull request. Please follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and use one of the commit types mentioned in the [Commit messages section of the pull request guidelines](./docs/dev/pull-requests.md#commit-messages). + +Please make sure to check out our [Pull request guidelines](./docs/dev/pull-requests.md) for more information. + +#### Unwanted pull requests + +To ensure the core maintainers time are spent well, we have certain pull requests we want to avoid: + +- Any non-minor pull requests without an **assigned** issue +- Any non-minor bug fixes without an issue (ideally, also assigned, but we are less strict on this) +- Spelling mistakes/changes (instead, try to fix our CI so that it would be able to catch it automatically - that would be useful) + +## Relevant development docs + +- [Project structure](./docs/dev/project-structure.md) +- [Development setup](./docs/dev/development-setup.md) +- [Go style guide](./docs/dev/go-style-guide.md) +- [Documentation guide](./docs/README.md) +- [Writing tests](./testing/README.md) +- [Pull request guidelines](./docs/dev/pull-requests.md) +- [Release process](./docs/dev/release-management.md) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..385e373 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM golang:1.23.8-alpine AS builder +ARG IBC_GO_VERSION + +RUN set -eux; apk add --no-cache gcc git libusb-dev linux-headers make musl-dev; + +ENV GOPATH="" + +# ensure the ibc go version is being specified for this image. +RUN test -n "${IBC_GO_VERSION}" + +# Copy relevant files before go mod download. Replace directives to local paths break if local +# files are not copied before go mod download. +ADD internal internal +ADD simapp simapp +ADD testing testing +ADD modules modules +ADD LICENSE LICENSE + +COPY contrib/devtools/Makefile contrib/devtools/Makefile +COPY Makefile . + +COPY go.mod . +COPY go.sum . + +RUN go mod download + +RUN make build + +FROM alpine:3.21 +ARG IBC_GO_VERSION + +LABEL "org.cosmos.ibc-go"="${IBC_GO_VERSION}" + +COPY --from=builder /go/build/simd /bin/simd + +ENTRYPOINT ["simd"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a5cec31 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fc55d9a --- /dev/null +++ b/Makefile @@ -0,0 +1,407 @@ +#!/usr/bin/make -f + +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 +BINDIR ?= $(GOPATH)/bin +BUILDDIR ?= $(CURDIR)/build +SIMAPP = ./simapp +MOCKS_DIR = $(CURDIR)/tests/mocks +HTTPS_GIT := https://github.com/cosmos/ibc-go.git +DOCKER := $(shell which docker) +PROJECT_NAME = $(shell git remote get-url origin | xargs basename -s .git) + +export GO111MODULE = on + +# process build tags + +build_tags = netgo +ifeq ($(LEDGER_ENABLED),true) + ifeq ($(OS),Windows_NT) + GCCEXE = $(shell where gcc.exe 2> NUL) + ifeq ($(GCCEXE),) + $(error gcc.exe not installed for ledger support, please install or set LEDGER_ENABLED=false) + else + build_tags += ledger + endif + else + UNAME_S = $(shell uname -s) + ifeq ($(UNAME_S),OpenBSD) + $(warning OpenBSD detected, disabling ledger support (https://github.com/cosmos/cosmos-sdk/issues/1988)) + else + GCC = $(shell command -v gcc 2> /dev/null) + ifeq ($(GCC),) + $(error gcc not installed for ledger support, please install or set LEDGER_ENABLED=false) + else + build_tags += ledger + endif + endif + endif +endif + +ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS))) + build_tags += gcc +endif +build_tags += $(BUILD_TAGS) +build_tags := $(strip $(build_tags)) + +whitespace := +whitespace += $(whitespace) +comma := , +build_tags_comma_sep := $(subst $(whitespace),$(comma),$(build_tags)) + +# process linker flags + +ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=sim \ + -X github.com/cosmos/cosmos-sdk/version.AppName=simd \ + -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \ + -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \ + -X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" + +# DB backend selection +ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS))) + ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb +endif +ifeq (badgerdb,$(findstring badgerdb,$(COSMOS_BUILD_OPTIONS))) + ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=badgerdb +endif +# handle rocksdb +ifeq (rocksdb,$(findstring rocksdb,$(COSMOS_BUILD_OPTIONS))) + CGO_ENABLED=1 + BUILD_TAGS += rocksdb + ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=rocksdb +endif +# handle boltdb +ifeq (boltdb,$(findstring boltdb,$(COSMOS_BUILD_OPTIONS))) + BUILD_TAGS += boltdb + ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=boltdb +endif + +ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS))) + ldflags += -w -s +endif +ldflags += $(LDFLAGS) +ldflags := $(strip $(ldflags)) +BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)' +# check for nostrip option +ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS))) + BUILD_FLAGS += -trimpath +endif + +#? all: Run tools build lint test +all: build lint test + +# The below include contains the tools and runsim targets. +include contrib/devtools/Makefile + +############################################################################### +### Build ### +############################################################################### + +BUILD_TARGETS := build install + +#? tidy-all: Run go mod tidy for all modules +tidy-all: + ./scripts/go-mod-tidy-all.sh + +#? build: Build simapp and build_test_matrix +build: BUILD_ARGS=-o $(BUILDDIR)/ + +#? build-linux: Build simapp and build_test_matrix for GOOS=linux GOARCH=amd64 +build-linux: + GOOS=linux GOARCH=amd64 LEDGER_ENABLED=false $(MAKE) build + +$(BUILD_TARGETS): go.sum $(BUILDDIR)/ + cd simapp && go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./... + +$(BUILDDIR)/: + mkdir -p $(BUILDDIR)/ + +.PHONY: build build-linux + +#? distclean: Run `make clean` +distclean: clean + +#? clean: Clean some auto generated directories +clean: + rm -rf \ + $(BUILDDIR)/ \ + artifacts/ \ + tmp-swagger-gen/ + +.PHONY: distclean clean + +#? build-docker-wasm: Build wasm simapp with specified tag. +build-docker-wasm: + ./scripts/build-wasm-simapp-docker.sh $(tag) + +build-docker-local: + docker build -t ghcr.io/cosmos/ibc-go-simd:local --build-arg IBC_GO_VERSION=local . + +.PHONY: build-docker-wasm + +############################################################################### +### Tools & Dependencies ### +############################################################################### + +go.sum: go.mod + echo "Ensure dependencies have not been modified ..." >&2 + go mod verify + go mod tidy + +#? python-install-deps: Install python dependencies +python-install-deps: + @echo "Installing python dependencies..." + @pip3 install --upgrade pip + @pip3 install -r requirements.txt + +############################################################################### +### Documentation ### +############################################################################### + +#? godocs: Generate go documentation +godocs: + @echo "--> Wait a few seconds and visit http://localhost:6060/pkg/github.com/cosmos/cosmos-sdk/types" + godoc -http=:6060 + +#? build-docs: Build documentation +build-docs: + @cd docs && npm ci && npm run build + +#? serve-docs: Run docs server +serve-docs: + @cd docs && npm run serve + +# If the DOCS_VERSION variable is not set, display an error message and exit +ifndef DOCS_VERSION +#? tag-docs-version: Tag the docs version +tag-docs-version: + @echo "Error: DOCS_VERSION is not set. Use 'make tag-docs-version DOCS_VERSION=' to set it. For example: 'make tag-docs-version DOCS_VERSION=v8.0.x'" + @exit 1 +else +tag-docs-version: + @cd docs && npm run docusaurus docs:version $(DOCS_VERSION) +endif + +check-docs-links: + @command -v lychee >/dev/null 2>&1 || { echo "ERROR: lychee is not installed (https://lychee.cli.rs/installation/)" >&2; exit 1; } + @echo "Checking links in documentation..." + @lychee --root-dir $(CURDIR)/docs/docs \ + --cache \ + --cache-exclude-status 429 \ + --max-cache-age 1w \ + --retry-wait-time 30 \ + --max-retries 25 \ + --max-concurrency 25 \ + --remap '($(CURDIR)/docs)(/docs/)(architecture/|events/)([^#]+?)(#[^#]+)?$$ $$1/$$3/$$4.md' \ + './docs/docs' + +lint-docs: + @command -v markdownlint-cli2 >/dev/null 2>&1 || { echo "ERROR: markdownlint-cli2 is not installed (https://github.com/DavidAnson/markdownlint-cli2#install)" >&2; exit 1; } + @echo "Linting documentation..." + @markdownlint-cli2 ./docs/docs/**/*.md + +.PHONY: build-docs serve-docs tag-docs-version + +############################################################################### +### Tests & Simulation ### +############################################################################### + +# make init-simapp initializes a single local node network +# it is useful for testing and development +# Usage: make install && make init-simapp && simd start +# Warning: make init-simapp will remove all data in simapp home directory +#? init-simapp: Run scripts/init-simapp.sh +init-simapp: + ./scripts/init-simapp.sh + +#? test: Run make test-unit +test: test-unit + +#? test-all: Run all test +test-all: test-unit test-ledger-mock test-race test-cover + +TEST_PACKAGES=./... +TEST_TARGETS := test-unit test-unit-amino test-unit-proto test-ledger-mock test-race test-ledger test-race + +# Test runs-specific rules. To add a new test target, just add +# a new rule, customise ARGS or TEST_PACKAGES ad libitum, and +# append the new rule to the TEST_TARGETS list. +test-unit: ARGS=-tags='cgo ledger test_ledger_mock test_e2e' +test-unit-amino: ARGS=-tags='ledger test_ledger_mock test_amino' +test-ledger: ARGS=-tags='cgo ledger' +test-ledger-mock: ARGS=-tags='ledger test_ledger_mock' +test-race: ARGS=-race -tags='cgo ledger test_ledger_mock' +test-race: TEST_PACKAGES=$(PACKAGES_NOSIMULATION) +$(TEST_TARGETS): run-tests + +# check-* compiles and collects tests without running them +# note: go test -c doesn't support multiple packages yet (https://github.com/golang/go/issues/15513) +CHECK_TEST_TARGETS := check-test-unit check-test-unit-amino +check-test-unit: ARGS=-tags='cgo ledger test_ledger_mock' +check-test-unit-amino: ARGS=-tags='ledger test_ledger_mock test_amino' +$(CHECK_TEST_TARGETS): EXTRA_ARGS=-run=none +$(CHECK_TEST_TARGETS): run-tests + +ARGS += -tags "$(test_tags)" +#? run-tests: Runs the go test command for all modules +run-tests: + @ARGS="$(ARGS)" TEST_PACKAGES=$(TEST_PACKAGES) EXTRA_ARGS="$(EXTRA_ARGS)" python3 ./scripts/go-test-all.py + +.PHONY: run-tests test test-all $(TEST_TARGETS) + +#? test-sim-nondeterminism: Run non-determinism test for simapp +test-sim-nondeterminism: + @echo "Running non-determinism test..." + @go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \ + -NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h + +test-sim-custom-genesis-fast: + @echo "Running custom genesis simulation..." + @echo "By default, ${HOME}/.gaiad/config/genesis.json will be used." + @go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Genesis=${HOME}/.gaiad/config/genesis.json \ + -Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h + +test-sim-import-export: runsim + @echo "Running application import/export simulation. This may take several minutes..." + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestAppImportExport + +test-sim-after-import: runsim + @echo "Running application simulation-after-import. This may take several minutes..." + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestAppSimulationAfterImport + +test-sim-custom-genesis-multi-seed: runsim + @echo "Running multi-seed custom genesis simulation..." + @echo "By default, ${HOME}/.gaiad/config/genesis.json will be used." + @$(BINDIR)/runsim -Genesis=${HOME}/.gaiad/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 400 5 TestFullAppSimulation + +test-sim-multi-seed-long: runsim + @echo "Running long multi-seed application simulation. This may take awhile!" + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 500 50 TestFullAppSimulation + +test-sim-multi-seed-short: runsim + @echo "Running short multi-seed application simulation. This may take awhile!" + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 10 TestFullAppSimulation + +test-sim-benchmark-invariants: + @echo "Running simulation invariant benchmarks..." + @go test -mod=readonly $(SIMAPP) -benchmem -bench=BenchmarkInvariants -run=^$ \ + -Enabled=true -NumBlocks=1000 -BlockSize=200 \ + -Period=1 -Commit=true -Seed=57 -v -timeout 24h + +.PHONY: \ +test-sim-nondeterminism \ +test-sim-custom-genesis-fast \ +test-sim-import-export \ +test-sim-after-import \ +test-sim-custom-genesis-multi-seed \ +test-sim-multi-seed-short \ +test-sim-multi-seed-long \ +test-sim-benchmark-invariants + +SIM_NUM_BLOCKS ?= 500 +SIM_BLOCK_SIZE ?= 200 +SIM_COMMIT ?= true + +#? test-sim-benchmark: Run application benchmark +test-sim-benchmark: + @echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!" + @go test -mod=readonly -benchmem -run=^$$ $(SIMAPP) -bench ^BenchmarkFullAppSimulation$$ \ + -Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -timeout 24h + +#? test-sim-profile: Run application benchmark and output cpuprofile, memprofile +test-sim-profile: + @echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!" + @go test -mod=readonly -benchmem -run=^$$ $(SIMAPP) -bench ^BenchmarkFullAppSimulation$$ \ + -Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -timeout 24h -cpuprofile cpu.out -memprofile mem.out + +.PHONY: test-sim-profile test-sim-benchmark + +#? test-cover: Run contrib/test_cover.sh +test-cover: + @export VERSION=$(VERSION); bash -x contrib/test_cover.sh +.PHONY: test-cover + +#? benchmark: Run benchmark tests +benchmark: + @go test -mod=readonly -bench=. $(PACKAGES_NOSIMULATION) +.PHONY: benchmark + +############################################################################### +### Linting ### +############################################################################### + +#? setup-pre-commit: Set pre commit git hook +setup-pre-commit: + @cp .git/hooks/pre-commit .git/hooks/pre-commit.bak 2>/dev/null || true + @echo "Installing pre-commit hook..." + @ln -sf ../../scripts/hooks/pre-commit.sh .git/hooks/pre-commit + @echo "Pre-commit hook was installed at .git/hooks/pre-commit" + +#? lint: Run golangci-lint on all modules +lint: + @echo "--> Running linter" + @./scripts/go-lint-all.sh --timeout=15m + +#? lint-fix: Run golangci-lint and fix issues on all modules +lint-fix: + @echo "--> Running linter" + @./scripts/go-lint-all.sh --fix + +#? format: Run gofumpt and misspell +format: + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./docs/client/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' -not -name '*.pb.gw.go' | xargs gofumpt -w + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./docs/client/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' -not -name '*.pb.gw.go' | xargs misspell -w +.PHONY: format + +.PHONY: lint lint-fix format + +############################################################################### +### Protobuf ### +############################################################################### + +protoVer=0.14.0 +protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer) +protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) + +#? proto-all: Format, lint and generate Protobuf files +proto-all: proto-format proto-lint proto-gen + +#? proto-gen: Generate Protobuf files +proto-gen: + @echo "Generating Protobuf files" + @$(protoImage) sh ./scripts/protocgen.sh + +#? proto-swagger-gen: Generate Protobuf Swagger +proto-swagger-gen: + @echo "Generating Protobuf Swagger" + @$(protoImage) sh ./scripts/protoc-swagger-gen.sh + +#? proto-format: Format Protobuf files +proto-format: + @$(protoImage) find ./ -name "*.proto" -exec clang-format -i {} \; + +#? proto-lint: Lint Protobuf files +proto-lint: + @$(protoImage) buf lint --error-format=json + +#? proto-check-breaking: Check if Protobuf file contains breaking changes +proto-check-breaking: + @$(protoImage) buf breaking --against $(HTTPS_GIT)#branch=main + +#? proto-update-deps: Update Protobuf dependencies +proto-update-deps: + @echo "Updating Protobuf dependencies" + $(DOCKER) run --rm -v $(CURDIR)/proto:/workspace --workdir /workspace $(protoImageName) buf mod update + +.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps + +#? help: Get more info on make commands +help: Makefile + @echo " Choose a command run in "$(PROJECT_NAME)":" + @sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /' +.PHONY: help diff --git a/README.md b/README.md new file mode 100644 index 0000000..eabc225 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +

+ Mukan IBC +

+ +

+ The sovereign inter-blockchain communication layer of the Mukan Network, forked from IBC-go. +

+ +## Overview + +**Mukan IBC** is the Inter-Blockchain Communication (IBC) protocol implementation for the Mukan Network. It is a permanent hard-fork of [IBC-go v10.4.0](https://github.com/cosmos/ibc-go), updated to reference the sovereign Mukan Network stack. + +### Key Differences from IBC-go + +- All upstream dependencies updated to reference `git.cw.tr/mukan-network/...` instead of original Cosmos GitHub paths. +- Future: Cross-chain UMC transfers and PoJ-verified IBC channel authentication. + +## Integration + +Mukan IBC is used by [Mukan Core](https://git.cw.tr/mukan-network/mukan-core) to enable cross-chain communication. + +```go +require git.cw.tr/mukan-network/mukan-ibc v10.4.0-mukan.1 +``` + +## License + +Licensed under the **GNU General Public License v3.0 (GPLv3)**. + +*Original IBC-go components remain under their respective Apache 2.0 licenses where applicable.* diff --git a/RELEASES.md b/RELEASES.md new file mode 100644 index 0000000..8cfcaf1 --- /dev/null +++ b/RELEASES.md @@ -0,0 +1,163 @@ +# Releases + +IBC-Go follows [semantic versioning](https://semver.org), but with the following deviations: + +- A state-machine breaking change will result in an increase of the minor version Y (x.Y.z | x > 0). +- An API breaking change will result in an increase of the major number (X.y.z | x > 0). Please note that these changes **will be backwards compatible** (as opposed to canonical semantic versioning; read [Backwards compatibility](#backwards-compatibility) for a detailed explanation). + +This is visually explained in the following decision tree: + +

+ Releases decision tree +

+ +When bumping the dependencies of [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) and [CometBFT](https://github.com/cometbft/cometbft) we will only treat patch releases as non state-machine breaking. + +## Backwards compatibility + +[ibc-go](https://github.com/cosmos/ibc-go) and the [IBC protocol specification](https://github.com/cosmos/ibc) maintain different versions. Furthermore, ibc-go serves several different user groups (chains, IBC app developers, relayers, IBC light client developers). Each of these groups has different expectations of what *backwards compatible* means. It simply isn't possible to categorize a change as backwards or non backwards compatible for all user groups. We are primarily interested in when our API breaks and when changes are state machine breaking (thus requiring a coordinated upgrade). This is scoping the meaning of ibc-go to that of those interacting with the code (IBC app developers, relayers, IBC light client developers), not chains using IBC to communicate (that should be encapsulated by the IBC protocol specification versioning). + +To summarize: **All our ibc-go releases allow chains to communicate successfully with any chain running any version of our code**. That is to say, we are still using IBC protocol specification v1.0 (v10 will also include support for the IBC protocol specification v2.0) + +## Release cycle + +IBC-Go follows a traditional release cycle involving an alpha, beta, and rc (release candidate) releases before finalizing a new version. As ibc-go works in a non-traditional area, we apply our own interpretation to each release type. We reserve the right to make both go API breaking changes and state machine breaking changes throughout the entire release cycle. The stable release guarantees do not go into affect until a final release is performed. + +It is never advisable to use a non-final release in production. + +### Alpha + +Alpha releases are intended to make available new features as soon as they are functional. No correctness guarantees are made and alpha releases **may** contain serious security vulnerabilities, bugs, and lack of user tooling, so long as they don't affect the core functionality. + +Initial users of alpha releases are expected to be advanced, patient, and capable of handling unusual errors. Very basic integration testing will be performed by the ibc-go development team before alpha releases. + +An internal audit is typically performed before the alpha release allowing the development team to gauge the maturity and stability of changes included in the next release. + +### Beta + +Beta releases are intended to signal design stability. While the go API is still subject to change, the core design of the new features should not be. Developers integrating the new features should expect to handle breaking changes when upgrading to RC's. + +Beta releases should not be made with known bugs or security vulnerabilities. Beta releases should focus on ironing out remaining bugs and filling out the UX functionality required by a final release. Beta releases should have a clearly defined scope of the features that will be included in the release. Only highly requested feature additions should be acted upon in this phase. + +When the development team has determined a release is ready to enter the RC phase, a final security audit should be performed. The security audit should be limited to looking for bugs and security vulnerabilities. Code improvements may be noted, but they should not be acted upon unless highly desirable. + +### RC + +RC's are release candidates. Final releases should contain little to no changes in comparison to the latest RC. Changes included in between RC releases should be limited to: + +- Improved testing +- UX additions +- Bug fixes +- Highly requested changes by the community + +A release should not be finalized until the development team and the external community have done sufficient integration tests on the targeted release. + +## Stable Release Policy + +The beginning of a new major release series is marked by the release of a new major version. A major release series is comprised of all minor and patch releases made under the same major version number. The series continues to receive bug fixes (released as minor or patch releases) until it reaches end of life. The date when a major release series reaches end of life is determined by one of the two following methods: + +- If the next major release is made within the first 6 months, then the end of life date of the major release series is 18 months after its initial release. +- If the next major release is made 6 months after the initial release, then the end of life date of the major release series is 12 months after the release date of the next major release. + +For example, if the current major release series is v1 and was released on January 1st, 2022, then v1 will be supported at least until January 1st, 2023. If v2 is published on August 1st 2022, then v1's end of life will be March 1st, 2023. + +Only the following major release series have a stable release status. All missing minor release versions have been discontinued. + +We reserve the right to drop support for releases if they are deemed unused (for example, because the Cosmos SDK version they depend on is not used or has been deprecated). Likewise, we also reserve the right to drop support for pre v1.0 versions of modules if we deem them unnecessary to maintain (we are only looking to give support for stable major releases). + +### ibc-go + +|Release|End of Life Date| +|-------|----------------| +|`v7.10.x`|March 17, 2025| +|`v8.7.x`|May 10, 2025| + +### Callbacks middleware + +|Release|End of Life Date| +|-------|----------------| +|`v0.2.x+ibc-go-v7.3.x`|March 17, 2025| +|`v0.2.x+ibc-go-v8.0.x`|May 10, 2025| + +### `08-wasm` light client proxy module + +|Release|End of Life Date| +|-------|----------------| +|`v0.3.x+ibc-go-v7.4.x-wasmvm-v1.5.x`|March 17, 2025| +|`v0.4.x+ibc-go-v8.4.x-wasmvm-v2.0.x`|May 10, 2025| + +### What pull requests will be included in stable patch-releases? + +Pull requests that fix bugs and add features that fall in the following categories: + +- **Severe regressions**. +- Bugs that may cause **client applications** to be **largely unusable**. +- Bugs that may cause **state corruption or data loss**. +- Bugs that may directly or indirectly cause a **security vulnerability**. +- Non-breaking features that are strongly requested by the community. +- Non-breaking CLI improvements that are strongly requested by the community. + +### What pull requests will NOT be automatically included in stable patch-releases? + +As rule of thumb, the following changes will **NOT** be automatically accepted into stable point-releases: + +- **State machine changes**, unless the previous behaviour would result in a consensus halt. +- **Protobuf-breaking changes**. +- **Client-breaking changes**, i.e. changes that prevent gRPC, HTTP and RPC clients to continue interacting with the node without any change. +- **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. + +## Deprecation notice + +Code that is marked as deprecated in a release will be removed 2 major releases afterwards. For example: deprecation notice is added in v8.3.0, then code will be deleted in v10.0.0. + +## Version matrix + +### ibc-go + +Versions of Golang, Cosmos SDK and CometBFT used by ibc-go in the currently active releases: + +| Go | ibc-go | Cosmos SDK | Tendermint/CometBFT | +|----|--------|------------|---------------------| +| 1.19 | v7.10.0 | v0.47.13 | v0.37.5 | +| 1.21 | v8.7.0 | v0.50.9 | v0.38.11 | + +### Callbacks middleware + +Versions of Golang, ibc-go, Cosmos SDK and CometBFT used by callbacks middleware in the currently active releases: + +| Go | callbacks | ibc-go | Cosmos SDK | Tendermint/CometBFT | +|----|-----------|--------|------------|---------------------| +| 1.19 | v0.2.0+ibc-go-v7.3 | v7.3.0 | v0.47.5 | v0.37.2 | +| 1.21 | v0.2.0+ibc-go-v8.0 | v8.0.0 | v0.50.1 | v0.38.0 | + +### `08-wasm` light client proxy module + +Versions of Golang, ibc-go, Cosmos SDK and CometBFT used by `08-wasm` module in the currently active releases: + +| Go | 08-wasm | ibc-go | Cosmos SDK | Tendermint/CometBFT | +|----|-----------|--------|------------|---------------------| +| 1.19 | v0.3.1+ibc-go-v7.4-wasmvm-v1.5 | v7.4.0 | v0.47.8 | v0.37.4 | +| 1.21 | v0.4.1+ibc-go-v8.4-wasmvm-v2.0 | v8.4.0 | v0.50.7 | v0.38.9 | + +## Graphics + +The decision tree above was generated with the following code: + +```text +%%{init: + {'theme': 'default', + 'themeVariables': + {'fontFamily': 'verdana', 'fontSize': '13px'} + } +}%% +flowchart TD + A(Change):::c --> B{API breaking?} + B:::c --> |Yes| C(Increase major version):::c + B:::c --> |No| D{state-machine breaking?} + D:::c --> |Yes| G(Increase minor version):::c + D:::c --> |No| H(Increase patch version):::c + classDef c fill:#eee,stroke:#aaa +``` + +using [Mermaid](https://mermaid-js.github.io)'s [live editor](https://mermaid.live). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..3549eb4 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,16 @@ +# How to Report a Security Bug + +If you believe you have found a security vulnerability in the Interchain Stack, you can report it to our primary vulnerability disclosure channel, the [Cosmos HackerOne Bug Bounty program](https://hackerone.com/cosmos?type=team). + + +If you prefer to report an issue via email, you may send a bug report to [security@interchain.io](mailto:security@interchain.io) with the issue details, reproduction, impact, and other information. Please submit only one unique email thread per vulnerability. Any issues reported via email are ineligible for bounty rewards. + +Artifacts from an email report are saved at the time the email is triaged. Please note: our team is not able to monitor dynamic content (e.g. a Google Docs link that is edited after receipt) throughout the lifecycle of a report. If you would like to share additional information or modify previous information, please include it in an additional reply as an additional attachment. + +Please DO NOT file a public issue in this repository to report a security vulnerability. + +# Coordinated Vulnerability Disclosure Policy and Safe Harbor + +For the most up-to-date version of the policies that govern vulnerability disclosure, please consult the [HackerOne program page](https://hackerone.com/cosmos?type=team&view_policy=true). + +The policy hosted on HackerOne is the official Coordinated Vulnerability Disclosure policy and Safe Harbor for the Interchain Stack, and the teams and infrastructure it supports, and it supersedes previous security policies that have been used in the past by individual teams and projects with targets in scope of the program. diff --git a/buf.work.yaml b/buf.work.yaml new file mode 100644 index 0000000..8d2415b --- /dev/null +++ b/buf.work.yaml @@ -0,0 +1,8 @@ +# Generated by "buf config migrate-v1beta1". Edit as necessary, and +# remove this comment when you're finished. +# +# This workspace file points to the roots found in your +# previous "buf.yaml" configuration. +version: v1 +directories: + - proto diff --git a/cmd/build_test_matrix/main.go b/cmd/build_test_matrix/main.go new file mode 100644 index 0000000..89d0fe7 --- /dev/null +++ b/cmd/build_test_matrix/main.go @@ -0,0 +1,195 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "go/ast" + "go/parser" + "go/token" + "io/fs" + "os" + "path/filepath" + "slices" + "sort" + "strings" +) + +const ( + testNamePrefix = "Test" + testFileNameSuffix = "_test.go" + e2eTestDirectory = "e2e" + // testEntryPointEnv specifies a single test function to run if provided. + testEntryPointEnv = "TEST_ENTRYPOINT" + // testExclusionsEnv is a comma separated list of test function names that will not be included + // in the results of this script. + testExclusionsEnv = "TEST_EXCLUSIONS" + // testNameEnv if provided returns a single test entry so that only one test is actually run. + testNameEnv = "TEST_NAME" +) + +// GithubActionTestMatrix represents +type GithubActionTestMatrix struct { + Include []TestSuitePair `json:"include"` +} + +type TestSuitePair struct { + Test string `json:"test"` + EntryPoint string `json:"entrypoint"` +} + +func main() { + githubActionMatrix, err := getGithubActionMatrixForTests(e2eTestDirectory, getTestToRun(), getTestEntrypointToRun(), getExcludedTestFunctions()) + 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)) +} + +// getTestEntrypointToRun returns the specified test function to run if present, otherwise +// it returns an empty string which will result in running all test suites. +func getTestEntrypointToRun() string { + testSuite, ok := os.LookupEnv(testEntryPointEnv) + if !ok { + return "" + } + return testSuite +} + +// getTestToRun returns the specified test function to run if present. +// If specified, only this test will be run. +func getTestToRun() string { + testName, ok := os.LookupEnv(testNameEnv) + if !ok { + return "" + } + return testName +} + +// getExcludedTestFunctions returns a list of test functions that we don't want to run. +func getExcludedTestFunctions() []string { + exclusions, ok := os.LookupEnv(testExclusionsEnv) + if !ok { + return nil + } + return strings.Split(exclusions, ",") +} + +// 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, testName string, suite string, excludedItems []string) (GithubActionTestMatrix, error) { + testSuiteMapping := map[string][]string{} + fset := token.NewFileSet() + err := filepath.Walk(e2eRootDirectory, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return fmt.Errorf("error walking e2e directory: %s", err) + } + + // 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 nil + } + + if testName != "" && slices.Contains(testCases, testName) { + testCases = []string{testName} + } + + if slices.Contains(excludedItems, suiteNameForFile) { + return nil + } + + if suite == "" || suiteNameForFile == suite { + 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, + EntryPoint: testSuiteName, + }) + } + } + + if len(gh.Include) == 0 { + return GithubActionTestMatrix{}, errors.New("no test cases found") + } + + // Sort the test cases by name so that the order is consistent. + sort.SliceStable(gh.Include, func(i, j int) bool { + return gh.Include[i].Test < gh.Include[j].Test + }) + + if testName != "" && len(gh.Include) != 1 { + return GithubActionTestMatrix{}, fmt.Errorf("expected exactly 1 test in the output matrix but got %d", len(gh.Include)) + } + + 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 0000000..624b620 --- /dev/null +++ b/cmd/build_test_matrix/main_test.go @@ -0,0 +1,191 @@ +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 with no test cases fails", func(t *testing.T) { + testingDir := t.TempDir() + _, err := getGithubActionMatrixForTests(testingDir, "", "", nil) + assert.Error(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, "", "", nil) + assert.NoError(t, err) + + expected := GithubActionTestMatrix{ + Include: []TestSuitePair{ + { + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestA", + }, + { + EntryPoint: "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, "", "", nil) + assert.NoError(t, err) + + expected := GithubActionTestMatrix{ + Include: []TestSuitePair{ + { + EntryPoint: "TestTransferTestSuite", + Test: "TestC", + }, + { + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestA", + }, + { + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestB", + }, + { + EntryPoint: "TestTransferTestSuite", + Test: "TestD", + }, + }, + } + + assertGithubActionTestMatricesEqual(t, expected, gh) + }) + + t.Run("single test can be specified", 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, "TestA", "TestFeeMiddlewareTestSuite", nil) + assert.NoError(t, err) + + expected := GithubActionTestMatrix{ + Include: []TestSuitePair{ + { + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestA", + }, + }, + } + + assertGithubActionTestMatricesEqual(t, expected, gh) + }) + + t.Run("error if single test doesn't exist", func(t *testing.T) { + testingDir := t.TempDir() + createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) + + _, err := getGithubActionMatrixForTests(testingDir, "TestThatDoesntExist", "TestFeeMiddlewareTestSuite", nil) + assert.Error(t, err) + }) + + t.Run("non test files are skipped", func(t *testing.T) { + testingDir := t.TempDir() + createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, nonTestFile) + + gh, err := getGithubActionMatrixForTests(testingDir, "", "", nil) + assert.Error(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(0o777)) + assert.NoError(t, err) + + _, err = getGithubActionMatrixForTests(testingDir, "", "", nil) + assert.Error(t, err) + }) +} + +func assertGithubActionTestMatricesEqual(t *testing.T, expected, actual GithubActionTestMatrix) { + t.Helper() + // 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.EntryPoint == memberJ.EntryPoint { + return memberI.Test < memberJ.Test + } + return memberI.EntryPoint < memberJ.EntryPoint + }) + + sort.SliceStable(actual.Include, func(i, j int) bool { + memberI := actual.Include[i] + memberJ := actual.Include[j] + if memberI.EntryPoint == memberJ.EntryPoint { + return memberI.Test < memberJ.Test + } + return memberI.EntryPoint < memberJ.EntryPoint + }) + 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) { + t.Helper() + goFileContents := goTestFileContents(suiteName, fn1Name, fn2Name) + err := os.WriteFile(path.Join(dir, filename), []byte(goFileContents), os.FileMode(0o777)) + assert.NoError(t, err) +} diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..f301b7c --- /dev/null +++ b/codecov.yml @@ -0,0 +1,24 @@ +coverage: + precision: 2 + range: + - 70.0 + - 100.0 + round: down + status: + project: + default: + target: auto + threshold: 0% + base: auto +comment: + require_changes: "coverage_drop OR uncovered_patch" # Only comment when coverage drops or there is uncovered code in the commit +ignore: +- "**/*.pb.go" +- "**/*.pb.gw.go" +- "docs" +- "simapp" +- "testing" +- "modules/light-clients/08-wasm/testing" +- "scripts" +- "contrib" +- "cmd" diff --git a/contrib/devtools/Makefile b/contrib/devtools/Makefile new file mode 100644 index 0000000..740edca --- /dev/null +++ b/contrib/devtools/Makefile @@ -0,0 +1,76 @@ +### +# Find OS and Go environment +# GO contains the Go binary +# FS contains the OS file separator +### +ifeq ($(OS),Windows_NT) + GO := $(shell where go.exe 2> NUL) + FS := "\\" +else + GO := $(shell command -v go 2> /dev/null) + FS := "/" +endif + +ifeq ($(GO),) + $(error could not find go. Is it in PATH? $(GO)) +endif + +############################################################################### +### Functions ### +############################################################################### + +go_get = $(if $(findstring Windows_NT,$(OS)),\ +IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS) ( mkdir $(GITHUBDIR)$(FS)$(1) ) else (cd .) &\ +IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS)$(2)$(FS) ( cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2) ) else (cd .) &\ +,\ +mkdir -p $(GITHUBDIR)$(FS)$(1) &&\ +(test ! -d $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2)) || true &&\ +)\ +cd $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && git fetch origin && git checkout -q $(3) + +mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +mkfile_dir := $(shell cd $(shell dirname $(mkfile_path)); pwd) + + +############################################################################### +### Tools ### +############################################################################### + +PREFIX ?= /usr/local +BIN ?= $(PREFIX)/bin +UNAME_S ?= $(shell uname -s) +UNAME_M ?= $(shell uname -m) + +GOPATH ?= $(shell $(GO) env GOPATH) +GITHUBDIR := $(GOPATH)$(FS)src$(FS)github.com + +BUF_VERSION ?= 0.11.0 + +TOOLS_DESTDIR ?= $(GOPATH)/bin +STATIK = $(TOOLS_DESTDIR)/statik +RUNSIM = $(TOOLS_DESTDIR)/runsim + +tools: tools-stamp +tools-stamp: statik runsim + # Create dummy file to satisfy dependency and avoid + # rebuilding when this Makefile target is hit twice + # in a row. + touch $@ + +# Install the runsim binary +statik: $(STATIK) +$(STATIK): + @echo "Installing statik..." + @go install github.com/rakyll/statik@v0.1.6 + +# Install the runsim binary +runsim: $(RUNSIM) +$(RUNSIM): + @echo "Installing runsim..." + @go install github.com/cosmos/tools/cmd/runsim@v1.0.0 + +tools-clean: + rm -f $(STATIK) $(GOLANGCI_LINT) $(RUNSIM) + rm -f tools-stamp + +.PHONY: tools-clean statik runsim diff --git a/contrib/test_cover.sh b/contrib/test_cover.sh new file mode 100644 index 0000000..a33d842 --- /dev/null +++ b/contrib/test_cover.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -e + +PKGS=$(go list ./... | grep -v '/simapp') + +set -e +echo "mode: atomic" > coverage.txt +for pkg in ${PKGS[@]}; do + go test -v -timeout 30m -race -coverprofile=profile.out -covermode=atomic -tags='ledger test_ledger_mock' "$pkg" + if [ -f profile.out ]; then + tail -n +2 profile.out >> coverage.txt; + rm profile.out + fi +done diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..67e47a5 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/docs/.markdownlint-cli2.jsonc b/docs/.markdownlint-cli2.jsonc new file mode 100644 index 0000000..dbcf321 --- /dev/null +++ b/docs/.markdownlint-cli2.jsonc @@ -0,0 +1,7 @@ +// This file is used by markdownlint-cli2 to configure the linting process +// in conjunction with .markdownlint.jsonc. +{ + "ignores": [ + "node_modules/**" + ] +} diff --git a/docs/.markdownlint.jsonc b/docs/.markdownlint.jsonc new file mode 100644 index 0000000..d0065cb --- /dev/null +++ b/docs/.markdownlint.jsonc @@ -0,0 +1,27 @@ +{ + "default": true, + "MD003": { + "style": "atx" + }, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md003---heading-style + "MD004": { + "style": "dash" + }, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md004---unordered-list-style + "MD007": { + "indent": 4 + }, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md007---unordered-list-indentation + "MD009": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md009---trailing-spaces + "MD010": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md010---hard-tabs + "MD013": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md013---line-length + "MD024": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md024---multiple-headings-with-the-same-content + "MD025": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md025---multiple-top-level-headings-in-the-same-document + "MD029": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix + "MD033": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md033---inline-html + "MD036": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md036---emphasis-used-instead-of-a-heading + "MD041": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md041---first-line-in-a-file-should-be-a-top-level-heading + "MD049": { + "style": "asterisk" + }, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md049---emphasis-style-should-be-consistent + "MD050": { + "style": "asterisk" + } // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md050---strong-style-should-be-consistent +} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..c5a9404 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,289 @@ +# IBC-Go Documentation + +Welcome to the IBC-Go documentation! This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. + +## Table of Contents + +- [IBC-Go Documentation](#ibc-go-documentation) + - [Table of Contents](#table-of-contents) + - [Configuration](#configuration) + - [Local Development and Deployment](#local-development-and-deployment) + - [Installation](#installation) + - [Local Development](#local-development) + - [Build](#build) + - [Serve](#serve) + - [Updating the Documentation](#updating-the-documentation) + - [Best practices](#best-practices) + - [File and Directory Naming Conventions](#file-and-directory-naming-conventions) + - [Code Blocks](#code-blocks) + - [Links](#links) + - [Multi-Documentation Linking](#multi-documentation-linking) + - [Static Assets](#static-assets) + - [Raw Assets](#raw-assets) + - [Technical writing course](#technical-writing-course) + - [Versioning](#versioning) + - [Terminology](#terminology) + - [Overview](#overview) + - [Tagging a new version](#tagging-a-new-version) + - [Adding a new version](#adding-a-new-version) + - [Updating an existing version](#updating-an-existing-version) + - [Deleting a version](#deleting-a-version) + +## Configuration + +Docusaurus configuration file is located at `./docusaurus.config.js`. This file contains the configuration for the sidebar, navbar, footer, and other settings. Sidebars are created in `./sidebars.js`. + +## Local Development and Deployment + +### Installation + +```bash +npm install +``` + +### Local Development + +```bash +npm start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. However, in the local development environment, some plugins like `@docusaurus/plugin-client-redirects`, will not work at all. This is why the landing page is an error page in the local development environment, and why you have to click on the correct docs version to see the documentation. This is not the case in the production environment. To view the production environment, you must [build](#build) and [serve](#serve) the website locally. + +### Build + +```bash +npm run build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +### Serve + +```bash +npm run serve +``` + +This command starts a local production server and opens up a browser window. + +### Lint + +From the root of the repo: +```bash +make lint-docs +``` + +This command will run `markdownlint-cli2` (if you don't have it installed, see the [install docs](https://github.com/DavidAnson/markdownlint-cli2#install) and lint all markdown files in `./docs/docs` (i.e. it will not lint versioned docs). + +### Check links + +From the root of the repo: +```bash +make check-docs-link +``` + +This command will run `lychee` (if you don't have it, see the [install docs](https://lychee.cli.rs/installation/)) and check all links in `./docs/docs` (i.e. it will not check versioned docs). + +Since a lot of our links are to github, this command easily gets rate limited, so it has been set up with a long retry sequence for links. You may need to run it multiple times to check all links. +The results (except rate limit responses) are cached for 1 week, so once you have run it, it will not keep checking the same links twice (this is primarly to help with rate limiting). + +## Updating the Documentation + +The documentation website is autogenerated from the markdown files found in [docs](./docs) directory. Each directory in `./docs/` represents a category to be displayed in the sidebar. If you create a new directory, you must create a `_category_.json` file in that directory with the following contents: + +```json +{ + "label": "Sidebar Label", + "position": 1, // position of the category in the sidebar + "link": null +} +``` + +The `position` key above is used to order the categories in the sidebar. This position key pertains to the order of this category in the parent directory. + +If you create a new markdown file within a category (`.docs/` directory is itself a category), you must add the following frontmatter to the top of the markdown file: + +```yaml +--- +title: Title of the file # title of the file in the sidebar +sidebar_label: Sidebar Label # title of the file in the sidebar +sidebar_position: 1 # position of the file in the sidebar +slug: /migrations/v5-to-v6 # the url of the file +--- +``` + +The `link` key in `_category_.json` determines if the category has an introductory page that comes before any content pages. If `link` is `null`, then the category does not have an introductory page. If there is a markdown file you wish to link, you should do + +```json +{ + "label": "Sidebar Label", + "position": 1, // position of the category in the sidebar + "link": { "type": "doc", "id": "intro" } +} +``` + +The `id` key can be defined in the frontmatter of the markdown file. Or, you can use the id tag as an extension to the url of the current page. For example, the following frontmatter on a markdown file in the same directory as the `_category_.json` file shown above will link to the markdown file: + +```yaml +--- +title: Title +sidebar_label: Sidebar Label +sidebar_position: 0 # should be zero for intro pages +slug: /ibc/upgrades/intro +--- +``` + +## Best practices + +- Check the spelling and grammar, even if you have to copy and paste from an external source. +- Use simple sentences. Easy-to-read sentences mean the reader can quickly use the guidance you share. +- Try to express your thoughts in a concise and clean way. +- Either Leave a space or use a `-` between the acronyms ADR and ICS and the corresponding number (e.g. ADR 008 or ADR-008, and ICS 27 or ICS-27). +- Don't overuse `code` format when writing in plain English. +- Follow Google developer documentation [style guide](https://developers.google.com/style). +- Check the meaning of words in Microsoft's [A-Z word list and term collections](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/accessibility-terms) (use the search input!). +- We recommend using RFC keywords in user documentation (lowercase). The RFC keywords are: "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL. They are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119). +- Lint the markdown files for documentation with [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli). Run `make docs-lint` (you will need to have `markdownlint-cli` installed, so please follow the [installation instructions](https://github.com/igorshubovych/markdownlint-cli#installation)). + +### File and Directory Naming Conventions + +Inside `/docs/docs/`: + +- All files should be named in `kebab-case`. +- All files should have a two digit prefix, indicating the order in which they should be read and displayed in their respective categories. For example, `01-overview.md` should be read before `02-integration.md`. If this order changes, the prefix should be updated. Note that the ordering is enforced by the frontmatter and not the file name. +- **All files that end in `.template.md` will be ignored by the build process.** +- The prefix `00-` is reserved for root links of categories (if a category has a root link this should be defined in `_category_.json`). For example, see [`docs/01-ibc/05-upgrades/00-intro.md`](./docs/01-ibc/05-upgrades/00-intro.md) and [`docs/01-ibc/05-upgrades/_category_.json`](./docs/01-ibc/05-upgrades/_category_.json). +- All category directories should be named in `kebab-case`. +- All category directories must have a `_category_.json` file. +- All category directories should have a two digit prefix (except for the root `./docs` category), indicating the order in which they should be read and displayed in their respective categories. For example, contents of `./docs/01-ibc/03-apps/` should be read before `./docs/01-ibc/07-relayer.md`. If this order changes, the prefix should be updated. Note that the ordering is enforced by the frontmatter of the markdown files and `_category_.json` files, not the file name. +- The images for each documentation should be kept in the same directory as the markdown file that uses them. This will likely require creating a new directory for each new category. The goal of this is to make versioning easier, discourage repeated use of the image, and make it easier to find images. + +### Code Blocks + +Code blocks in docusaurus are super-powered, read more about them [here](https://docusaurus.io/docs/markdown-features/code-blocks). Three most important features for us are: + +1. We can add a `title` to the code block, which will be displayed above the code block. (This should be used to display the file path of the code block.) +2. We can add a `reference` tag to the code block, which will reference github to create the code block. **You should always use hyperlinks in reference codeblocks.** Here is what a typical code block should look like: + +````ignore +```go reference title="modules/apps/transfer/keeper/keeper.go" +https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/transfer/keeper/keeper.go#L19-L31 +``` +```` + +3. We can highlight lines in the code block by adding `// highlight-next-line` before the line we want to highlight. For example, we should use this to highlight diffs. Here is an example: + +````ignore +```go +import ( + ... + // highlight-next-line ++ ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint" + ... +) +``` +```` + +### Links + +In docusaurus, there are three ways to link to other pages: + +1. File Paths (relative or absolute) +2. URLs (relative or absolute) +3. Hyperlinks + +In this section, we will discuss when to use each. + +#### Multi-Documentation Linking + +Technically, there are four docs being maintained in this repo: + +1. Found in `docs/docs/` (this is the one displayed on the website in the "Documentation" tab) +2. Found in `docs/architecture/` (this is the one displayed on the website in the "Architecture Decision Records" tab) +3. Found in `docs/events/` (depreciated, this is not displayed on the website, but is hosted under `/events/` url) +4. Found in `docs/params/` (depreciated, this is not displayed on the website, but is hosted under `/params/` url) + +When referencing a markdown file, you should use relative file paths if they are in the same docs directory from above. For example, if you are in `docs/docs/01-ibc` and want to link to `docs/docs/02-apps/01-transfer/01-overview.md`, you should use the relative link `../02-apps/01-transfer/01-overview.md`. + +If the file you are referencing is in a different docs directory, you should use an absolute URL. For example, if you are in `docs/docs/01-ibc` and want to link to `docs/architecture/adr-001-coin-source-tracing.md`, you should use the absolute URL (not absolute file path), in this case `/architecture/adr-001-coin-source-tracing`. You can find the absolute URL by looking at the slug in the frontmatter of the markdown file you want to link to. If the frontmatter slug is not set (such as in `docs/architecture/adr-001-coin-source-tracing.md`), you should use the url that docusaurus generates for it. You can find this by looking at the url of the page in the browser. + +Note that when referencing any file outside of the parent `docs/` directory, you should always use a hyperlink. + +#### Static Assets + +Static assets are the non-code files that are directly copied to the build output. They include **images**, stylesheets, favicons, fonts, etc. + +By default, you are suggested to put these assets in the `static/` directory. Every file you put into that directory will be copied into the root of the generated build folder with the directory hierarchy preserved. E.g. if you add a file named `sun.jpg` to the static folder, it will be copied to `build/sun.jpg`. + +These assets should be referenced using absolute URLs. For example, if you have an image in `static/img/cosmos-logo-bw.png`, you should reference it using `/img/cosmos-logo-bw.png`. + +#### Raw Assets + +If you want to link a raw file, you should link to it using `@site` + its base path. For example, if you want to link to the raw markdown file `/architecture/adr.template.md`, you should use the absolute URL `@site/architecture/adr.template.md`. + +### Technical writing course + +Google provides a free [course](https://developers.google.com/tech-writing/overview) for technical writing. + +## Versioning + +Versioning only applies to documentation and not the ADRs found in the `./architecture/` directory. + +### Terminology + +- Current version: The version placed in the `.docs/` folder. This version is the one that is displayed on the website by default, referred to as next. +- Latest version: This version is defined in `./docusaurus.config.js` file under the `lastVersion` key. + +### Overview + +A typical versioned doc site looks like below: + +```ignore +docs/ +├── sidebars.json # sidebar for the current docs version +├── docs/ # docs directory for the current docs version +│ ├── 01-foo/ +│ │ └── 01-bar.md # https://mysite.com/docs/next/01-foo/01-bar +│ └── 00-intro.md # https://mysite.com/docs/next/00-intro +├── versions.json # file to indicate what versions are available +├── versioned_docs/ +│ ├── version-v1.1.0/ +│ │ ├── 01-foo/ +│ │ │ └── 01-bar.md # https://mysite.com/docs/01-foo/01-bar +│ │ └── 00-intro.md +│ └── version-v1.0.0/ +│ ├── 01-foo/ +│ │ └── 01-bar.md # https://mysite.com/docs/v1.0.0/01-foo/01-bar +│ └── 00-intro.md +├── versioned_sidebars/ +│ ├── version-v1.1.0-sidebars.json +│ └── version-v1.0.0-sidebars.json +├── docusaurus.config.js +└── package.json +``` + +The `./versions.json` file is a list of version names, ordered from newest to oldest. + +### Tagging a new version + +It is possible to tag the current version of the docs as a new version. This will create the appropriate files in `./versioned_docs/` and `./versioned_sidebars/` directories, and modify the `./versions.json` file. To do this, run the following command: + +```bash +npm run docusaurus docs:version v7.1.0 +``` + +### Adding a new version + +To add a new version: + +1. Create a new directory in `./versioned_docs/` called `version-vX.Y.Z` where `X.Y.Z` is the version number. This directory should contain the markdown files for the new version. +2. Create a new file in `./versioned_sidebars/` called `version-vX.Y.Z-sidebars.json`. This file should contain the sidebar for the new version. +3. Add the version to the `./versions.json` file. The list should be ordered from newest to oldest. +4. If needed, make any configuration changes in `./docusaurus.config.js`. For example, updating the `lastVersion` key in `./docusaurus.config.js` to the latest version. + +### Updating an existing version + +You can update multiple docs versions at the same time because each directory in `./versioned_docs/` represents specific routes when published. Make changes by editing the markdown files in the appropriate version directory. + +### Deleting a version + +When a version is no longer supported, you can delete it by removing it from `versions.json` and deleting the corresponding files in `./versioned_docs/` and `./versioned_sidebars/`. diff --git a/docs/architecture/README.md b/docs/architecture/README.md new file mode 100644 index 0000000..31d4fd0 --- /dev/null +++ b/docs/architecture/README.md @@ -0,0 +1,48 @@ +--- +sidebar_position: 1 +--- + +# Architecture Decision Records (ADR) + +This is a location to record all high-level architecture decisions in the ibc-go project. + +You can read more about the ADR concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t). + +An ADR should provide: + +- Context on the relevant goals and the current state +- Proposed changes to achieve the goals +- Summary of pros and cons +- References +- Changelog + +Note the distinction between an ADR and a spec. The ADR provides the context, intuition, reasoning, and +justification for a change in architecture, or for the architecture of something +new. The spec is much more compressed and streamlined summary of everything as +it is or should be. + +If recorded decisions turned out to be lacking, convene a discussion, record the new decisions here, and then modify the code to match. + +Note the context/background should be written in the present tense. + +To suggest an ADR, please make use of the [ADR template](https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr.template.md) provided. + +## Table of Contents + +| ADR \# | Description | Status | +| ------ | ----------- | ------ | +| [001](./adr-001-coin-source-tracing.md) | ICS-20 coin denomination format | Accepted, Implemented | +| [002](./adr-002-go-module-versioning.md) | Go module versioning | Accepted | +| [003](./adr-003-ics27-acknowledgement.md) | ICS27 acknowledgement format | Accepted | +| [004](./adr-004-ics29-lock-fee-module.md) | ICS29 module locking upon escrow out of balance | Accepted | +| [005](./adr-005-consensus-height-events.md) | `UpdateClient` events - `ClientState` consensus heights | Accepted | +| [006](./adr-006-02-client-refactor.md) | ICS02 client refactor | Accepted | +| [007](./adr-007-solomachine-signbytes.md) | ICS06 Solo machine sign bytes | Accepted | +| [008](./adr-008-app-caller-cbs.md) | Callback to IBC Actors | Accepted | +| [009](./adr-009-v6-ics27-msgserver.md) | ICS27 message server addition | Accepted | +| [010](./adr-010-light-clients-as-sdk-modules.md) | IBC light clients as SDK modules | Accepted | +| [011](./adr-011-transfer-total-escrow-state-entry.md) | ICS20 state entry for total amount of tokens in escrow | Accepted | +| [015](./adr-015-ibc-packet-receiver.md) | IBC Packet Routing | Accepted | +| [025](./adr-025-ibc-passive-channels.md) | IBC passive channels | Deprecated | +| [026](./adr-026-ibc-client-recovery-mechanisms.md) | IBC client recovery mechanisms | Accepted | +| [027](./adr-027-ibc-wasm.md) | Wasm based light clients | Accepted | diff --git a/docs/architecture/adr-001-coin-source-tracing.md b/docs/architecture/adr-001-coin-source-tracing.md new file mode 100644 index 0000000..7982404 --- /dev/null +++ b/docs/architecture/adr-001-coin-source-tracing.md @@ -0,0 +1,375 @@ +# ADR 001: Coin Source Tracing + +## Changelog + +- 2020-07-09: Initial Draft +- 2020-08-11: Implementation changes + +## Status + +Accepted, Implemented + +## Context + +The specification for IBC cross-chain fungible token transfers +([ICS20](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer)), needs to +be aware of the origin of any token denomination in order to relay a `Packet` which contains the sender +and recipient addresses in the +[`FungibleTokenPacketData`](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures). + +The Packet relay sending works based in 2 cases (per +[specification](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#packet-relay) and [Colin Axnér](https://github.com/colin-axner)'s description): + +1. Sender chain is acting as the source zone. The coins are transferred +to an escrow address (i.e locked) on the sender chain and then transferred +to the receiving chain through IBC TAO logic. It is expected that the +receiving chain will mint vouchers to the receiving address. + +2. Sender chain is acting as the sink zone. The coins (vouchers) are burned +on the sender chain and then transferred to the receiving chain through IBC +TAO logic. It is expected that the receiving chain, which had previously +sent the original denomination, will unescrow the fungible token and send +it to the receiving address. + +Another way of thinking of source and sink zones is through the token's +timeline. Each send to any chain other than the one it was previously +received from is a movement forwards in the token's timeline. This causes +trace to be added to the token's history and the destination port and +destination channel to be prefixed to the denomination. In these instances +the sender chain is acting as the source zone. When the token is sent back +to the chain it previously received from, the prefix is removed. This is +a backwards movement in the token's timeline and the sender chain +is acting as the sink zone. + +### Example + +Assume the following channel connections exist and that all channels use the port ID `transfer`: + +- chain `A` has channels with chain `B` and chain `C` with the IDs `channelToB` and `channelToC`, respectively +- chain `B` has channels with chain `A` and chain `C` with the IDs `channelToA` and `channelToC`, respectively +- chain `C` has channels with chain `A` and chain `B` with the IDs `channelToA` and `channelToB`, respectively + +These steps of transfer between chains occur in the following order: `A -> B -> C -> A -> C`. In particular: + +1. `A -> B`: sender chain is source zone. `A` sends packet with `denom` (escrowed on `A`), `B` receives `denom` and mints and sends voucher `transfer/channelToA/denom` to recipient. +2. `B -> C`: sender chain is source zone. `B` sends packet with `transfer/channelToA/denom` (escrowed on `B`), `C` receives `transfer/channelToA/denom` and mints and sends voucher `transfer/channelToB/transfer/channelToA/denom` to recipient. +3. `C -> A`: sender chain is source zone. `C` sends packet with `transfer/channelToB/transfer/channelToA/denom` (escrowed on `C`), `A` receives `transfer/channelToB/transfer/channelToA/denom` and mints and sends voucher `transfer/channelToC/transfer/channelToB/transfer/channelToA/denom` to recipient. +4. `A -> C`: sender chain is sink zone. `A` sends packet with `transfer/channelToC/transfer/channelToB/transfer/channelToA/denom` (burned on `A`), `C` receives `transfer/channelToC/transfer/channelToB/transfer/channelToA/denom`, and unescrows and sends `transfer/channelToB/transfer/channelToA/denom` to recipient. + +The token has a final denomination on chain `C` of `transfer/channelToB/transfer/channelToA/denom`, where `transfer/channelToB/transfer/channelToA` is the trace information. + +In this context, upon a receive of a cross-chain fungible token transfer, if the sender chain is the source of the token, the protocol prefixes the denomination with the port and channel identifiers in the following format: + +```typescript +prefix + denom = {destPortN}/{destChannelN}/.../{destPort0}/{destChannel0}/denom +``` + +Example: transferring `100 uatom` from port `HubPort` and channel `HubChannel` on the Hub to +Ethermint's port `EthermintPort` and channel `EthermintChannel` results in `100 +EthermintPort/EthermintChannel/uatom`, where `EthermintPort/EthermintChannel/uatom` is the new +denomination on the receiving chain. + +In the case those tokens are transferred back to the Hub (i.e the **source** chain), the prefix is +trimmed and the token denomination updated to the original one. + +### Problem + +The problem of adding additional information to the coin denomination is twofold: + +1. The ever increasing length if tokens are transferred to zones other than the source: + +If a token is transferred `n` times via IBC to a sink chain, the token denom will contain `n` pairs +of prefixes, as shown on the format example above. This poses a problem because, while port and +channel identifiers have a maximum length of 64 each, the SDK `Coin` type only accepts denoms up to +64 characters. Thus, a single cross-chain token, which again, is composed by the port and channels +identifiers plus the base denomination, can exceed the length validation for the SDK `Coins`. + +This can result in undesired behaviours such as tokens not being able to be transferred to multiple +sink chains if the denomination exceeds the length or unexpected `panics` due to denomination +validation failing on the receiving chain. + +2. The existence of special characters and uppercase letters on the denomination: + +In the SDK every time a `Coin` is initialized through the constructor function `NewCoin`, a validation +of a coin's denom is performed according to a +[Regex](https://github.com/cosmos/cosmos-sdk/blob/a940214a4923a3bf9a9161cd14bd3072299cd0c9/types/coin.go#L583), +where only lowercase alphanumeric characters are accepted. While this is desirable for native denominations +to keep a clean UX, it presents a challenge for IBC as ports and channels might be randomly +generated with special and uppercase characters as per the [ICS 024 - Host +Requirements](https://github.com/cosmos/ibc/tree/master/spec/core/ics-024-host-requirements#paths-identifiers-separators) +specification. + +## Decision + +The issues outlined above, are applicable only to SDK-based chains, and thus the proposed solution +are do not require specification changes that would result in modification to other implementations +of the ICS20 spec. + +Instead of adding the identifiers on the coin denomination directly, the proposed solution hashes +the denomination prefix in order to get a consistent length for all the cross-chain fungible tokens. + +This will be used for internal storage only, and when transferred via IBC to a different chain, the +denomination specified on the packed data will be the full prefix path of the identifiers needed to +trace the token back to the originating chain, as specified on ICS20. + +The new proposed format will be the following: + +```go +ibcDenom = "ibc/" + hash(trace path + "/" + base denom) +``` + +The hash function will be a SHA256 hash of the fields of the `DenomTrace`: + +```protobuf +// DenomTrace contains the base denomination for ICS20 fungible tokens and the source tracing +// information +message DenomTrace { + // chain of port/channel identifiers used for tracing the source of the fungible token + string path = 1; + // base denomination of the relayed fungible token + string base_denom = 2; +} +``` + +The `IBCDenom` function constructs the `Coin` denomination used when creating the ICS20 fungible token packet data: + +```go +// Hash returns the hex bytes of the SHA256 hash of the DenomTrace fields using the following formula: +// +// hash = sha256(tracePath + "/" + baseDenom) +func (dt DenomTrace) Hash() tmbytes.HexBytes { + return tmhash.Sum(dt.Path + "/" + dt.BaseDenom) +} + +// IBCDenom a coin denomination for an ICS20 fungible token in the format 'ibc/{hash(tracePath + baseDenom)}'. +// If the trace is empty, it will return the base denomination. +func (dt DenomTrace) IBCDenom() string { + if dt.Path != "" { + return fmt.Sprintf("ibc/%s", dt.Hash()) + } + return dt.BaseDenom +} +``` + +### `x/ibc-transfer` Changes + +In order to retrieve the trace information from an IBC denomination, a lookup table needs to be +added to the `ibc-transfer` module. These values need to also be persisted between upgrades, meaning +that a new `[]DenomTrace` `GenesisState` field state needs to be added to the module: + +```go +// GetDenomTrace retrieves the full identifiers trace and base denomination from the store. +func (k Keeper) GetDenomTrace(ctx Context, denomTraceHash []byte) (DenomTrace, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.KeyDenomTrace(traceHash)) + if bz == nil { + return &DenomTrace, false + } + + var denomTrace DenomTrace + k.cdc.MustUnmarshalBinaryBare(bz, &denomTrace) + return denomTrace, true +} + +// HasDenomTrace checks if a the key with the given trace hash exists on the store. +func (k Keeper) HasDenomTrace(ctx Context, denomTraceHash []byte) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.KeyTrace(denomTraceHash)) +} + +// SetDenomTrace sets a new {trace hash -> trace} pair to the store. +func (k Keeper) SetDenomTrace(ctx Context, denomTrace DenomTrace) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshalBinaryBare(&denomTrace) + store.Set(types.KeyTrace(denomTrace.Hash()), bz) +} +``` + +The `MsgTransfer` will validate that the `Coin` denomination from the `Token` field contains a valid +hash, if the trace info is provided, or that the base denominations matches: + +```go +func (msg MsgTransfer) ValidateBasic() error { + // ... + return ValidateIBCDenom(msg.Token.Denom) +} +``` + +```go +// ValidateIBCDenom validates that the given denomination is either: +// +// - A valid base denomination (eg: 'uatom') +// - A valid fungible token representation (i.e 'ibc/{hash}') per ADR 001 https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-001-coin-source-tracing.md +func ValidateIBCDenom(denom string) error { + denomSplit := strings.SplitN(denom, "/", 2) + + switch { + case strings.TrimSpace(denom) == "", + len(denomSplit) == 1 && denomSplit[0] == "ibc", + len(denomSplit) == 2 && (denomSplit[0] != "ibc" || strings.TrimSpace(denomSplit[1]) == ""): + return sdkerrors.Wrapf(ErrInvalidDenomForTransfer, "denomination should be prefixed with the format 'ibc/{hash(trace + \"/\" + %s)}'", denom) + + case denomSplit[0] == denom && strings.TrimSpace(denom) != "": + return sdk.ValidateDenom(denom) + } + + if _, err := ParseHexHash(denomSplit[1]); err != nil { + return Wrapf(err, "invalid denom trace hash %s", denomSplit[1]) + } + + return nil +} +``` + +The denomination trace info only needs to be updated when token is received: + +- Receiver is **source** chain: The receiver created the token and must have the trace lookup already stored (if necessary *ie* native token case wouldn't need a lookup). +- Receiver is **not source** chain: Store the received info. For example, during step 1, when chain `B` receives `transfer/channelToA/denom`. + +```go +// SendTransfer +// ... + + fullDenomPath := token.Denom + +// deconstruct the token denomination into the denomination trace info +// to determine if the sender is the source chain +if strings.HasPrefix(token.Denom, "ibc/") { + fullDenomPath, err = k.DenomPathFromHash(ctx, token.Denom) + if err != nil { + return err + } +} + +if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) { +//... +``` + +```go +// DenomPathFromHash returns the full denomination path prefix from an ibc denom with a hash +// component. +func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error) { + hexHash := denom[4:] + hash, err := ParseHexHash(hexHash) + if err != nil { + return "", Wrap(ErrInvalidDenomForTransfer, err.Error()) + } + + denomTrace, found := k.GetDenomTrace(ctx, hash) + if !found { + return "", Wrap(ErrTraceNotFound, hexHash) + } + + fullDenomPath := denomTrace.GetFullDenomPath() + return fullDenomPath, nil +} +``` + +```go +// OnRecvPacket +// ... + +// This is the prefix that would have been prefixed to the denomination +// on sender chain IF and only if the token originally came from the +// receiving chain. +// +// NOTE: We use SourcePort and SourceChannel here, because the counterparty +// chain would have prefixed with DestPort and DestChannel when originally +// receiving this coin as seen in the "sender chain is the source" condition. +if ReceiverChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), data.Denom) { + // sender chain is not the source, unescrow tokens + + // remove prefix added by sender chain + voucherPrefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) + unprefixedDenom := data.Denom[len(voucherPrefix):] + token := sdk.NewCoin(unprefixedDenom, sdk.NewIntFromUint64(data.Amount)) + + // unescrow tokens + escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) + return k.bankKeeper.SendCoins(ctx, escrowAddress, receiver, sdk.NewCoins(token)) +} + +// sender chain is the source, mint vouchers + +// since SendPacket did not prefix the denomination, we must prefix denomination here +sourcePrefix := types.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) +// NOTE: sourcePrefix contains the trailing "/" +prefixedDenom := sourcePrefix + data.Denom + +// construct the denomination trace from the full raw denomination +denomTrace := types.ParseDenomTrace(prefixedDenom) + +// set the value to the lookup table if not stored already +traceHash := denomTrace.Hash() +if !k.HasDenomTrace(ctx, traceHash) { + k.SetDenomTrace(ctx, traceHash, denomTrace) +} + +voucherDenom := denomTrace.IBCDenom() +voucher := sdk.NewCoin(voucherDenom, sdk.NewIntFromUint64(data.Amount)) + +// mint new tokens if the source of the transfer is the same chain +if err := k.bankKeeper.MintCoins( + ctx, types.ModuleName, sdk.NewCoins(voucher), +); err != nil { + return err +} + +// send to receiver +return k.bankKeeper.SendCoinsFromModuleToAccount( + ctx, types.ModuleName, receiver, sdk.NewCoins(voucher), +) +``` + +```go +func NewDenomTraceFromRawDenom(denom string) DenomTrace{ + denomSplit := strings.Split(denom, "/") + trace := "" + if len(denomSplit) > 1 { + trace = strings.Join(denomSplit[:len(denomSplit)-1], "/") + } + return DenomTrace{ + BaseDenom: denomSplit[len(denomSplit)-1], + Trace: trace, + } +} +``` + +One final remark is that the `FungibleTokenPacketData` will remain the same, i.e with the prefixed full denomination, since the receiving chain may not be an SDK-based chain. + +### Coin Changes + +The coin denomination validation will need to be updated to reflect these changes. In particular, the denomination validation +function will now: + +- Accept slash separators (`"/"`) and uppercase characters (due to the `HexBytes` format) +- Bump the maximum character length to 128, as the hex representation used by Tendermint's + `HexBytes` type contains 64 characters. + +Additional validation logic, such as verifying the length of the hash, the may be added to the bank module in the future if the [custom base denomination validation](https://github.com/cosmos/cosmos-sdk/pull/6755) is integrated into the SDK. + +### Positive + +- Clearer separation of the source tracing behaviour of the token (transfer prefix) from the original + `Coin` denomination +- Consistent validation of `Coin` fields (i.e no special characters, fixed max length) +- Cleaner `Coin` and standard denominations for IBC +- No additional fields to SDK `Coin` + +### Negative + +- Store each set of tracing denomination identifiers on the `ibc-transfer` module store +- Clients will have to fetch the base denomination every time they receive a new relayed fungible token over IBC. This can be mitigated using a map/cache for already seen hashes on the client side. Other forms of mitigation, would be opening a websocket connection subscribe to incoming events. + +### Neutral + +- Slight difference with the ICS20 spec +- Additional validation logic for IBC coins on the `ibc-transfer` module +- Additional genesis fields +- Slightly increases the gas usage on cross-chain transfers due to access to the store. This should + be inter-block cached if transfers are frequent. + +## References + +- [ICS 20 - Fungible token transfer](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer) +- [Custom Coin Denomination validation](https://github.com/cosmos/cosmos-sdk/pull/6755) diff --git a/docs/architecture/adr-002-go-module-versioning.md b/docs/architecture/adr-002-go-module-versioning.md new file mode 100644 index 0000000..fce0d09 --- /dev/null +++ b/docs/architecture/adr-002-go-module-versioning.md @@ -0,0 +1,112 @@ +# ADR 002: Go module versioning + +## Changelog + +- 05/01/2022: initial draft + +## Status + +Accepted + +## Context + +The IBC module was originally developed in the Cosmos SDK and released during the Stargate release series (v0.42). +It was subsequently migrated to its own repository, ibc-go. +The first official release on ibc-go was v1.0.0. +v1.0.0 was decided to be used instead of v0.1.0 primarily for the following reasons: + +- Maintaining compatibility with the IBC specification v1 requires stronger support/guarantees. +- Using the major, minor, and patch numbers allows for easier communication of what breaking changes are included in a release. +- The IBC module is being used by numerous high value projects which require stability. + +### Problems + +#### Go module version must be incremented + +When a Go module is released under v1.0.0, all following releases must follow Go semantic versioning. +Thus when the go API is broken, the Go module major version **must** be incremented. +For example, changing the go package version from `v2` to `v3` bumps the import from `github.com/cosmos/ibc-go/v2` to `github.com/cosmos/ibc-go/v3`. + +If the Go module version is not incremented then attempting to go get a module @v3.0.0 without the suffix results in: +`invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v3` + +Version validation was added in Go 1.13. This means that in order to release a v3.0.0 git tag without a /v3 suffix on the module definition, the tag must explicitly **not** contain a go.mod file. +Not including a go.mod in our release is not a viable option. + +#### Attempting to import multiple go module versions for ibc-go + +Attempting to import two versions of ibc-go, such as `github.com/cosmos/ibc-go/v2` and `github.com/cosmos/ibc-go/v3`, will result in multiple issues. + +The Cosmos SDK does global registration of error and governance proposal types. +The errors and proposals used in ibc-go would need to now register their naming based on the go module version. + +The more concerning problem is that protobuf definitions will also reach a namespace collision. +ibc-go and the Cosmos SDK in general rely heavily on using extended functions for go structs generated from protobuf definitions. +This requires the go structs to be defined in the same package as the extended functions. +Thus, bumping the import versioning causes the protobuf definitions to be generated in two places (in v2 and v3). +When registering these types at compile time, the go compiler will panic. +The generated types need to be registered against the proto codec, but there exist two definitions for the same name. + +The protobuf conflict policy can be overridden via the environment variable `GOLANG_PROTOBUF_REGISTRATION_CONFLICT`, but it is possible this could lead to various runtime errors or unexpected behaviour (see [here](https://github.com/protocolbuffers/protobuf-go/blob/master/reflect/protoregistry/registry.go#L46)). +More information [here](https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict) on namespace conflicts for protobuf versioning. + +### Potential solutions + +#### Changing the protobuf definition version + +The protobuf definitions all have a type URL containing the protobuf version for this type. +Changing the protobuf version would solve the namespace collision which arise from importing multiple versions of ibc-go, but it leads to new issues. + +In the Cosmos SDK, `Any`s are unpacked and decoded using the type URL. +Changing the type URL thus is creating a distinctly different type. +The same registration on the proto codec cannot be used to unpack the new type. +For example: + +All Cosmos SDK messages are packed into `Any`s. If we incremented the protobuf version for our IBC messages, clients which submitted the v1 of our Cosmos SDK messages would now be rejected since the old type is not registered on the codec. +The clients must know to submit the v2 of these messages. This pushes the burden of versioning onto relayers and wallets. + +A more serious problem is that the `ClientState` and `ConsensusState` are packed as `Any`s. Changing the protobuf versioning of these types would break compatibility with IBC specification v1. + +#### Moving protobuf definitions to their own go module + +The protobuf definitions could be moved to their own go module which uses 0.x versioning and will never go to 1.0. +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, let's say this solution is implemented in v3. Then + +`github.com/cosmos/ibc-go/v2` cannot be imported with any other ibc-go version + +`github.com/cosmos/ibc-go/v3` cannot be imported with any previous ibc-go versions + +`github.com/cosmos/ibc-go/v4` may be imported with ibc-go versions v3+ + +`github.com/cosmos/ibc-go/v5` may be imported with ibc-go versions v3+ + +## Decision + +Supporting importing multiple versions of ibc-go requires a non-trivial amount of complexity. +It is unclear when a user of the ibc-go code would need multiple versions of ibc-go. +Until there is an overwhelming reason to support importing multiple versions of ibc-go: + +**Major releases cannot be imported simultaneously**. +Releases should focus on keeping backwards compatibility for go code clients, within reason. +Old functionality should be marked as deprecated and there should exist upgrade paths between major versions. +Deprecated functionality may be removed when no clients rely on that functionality. +How this is determined is to be decided. + +**Error and proposal type registration will not be changed between go module version increments**. +This explicitly stops external clients from trying to import two major versions (potentially risking a bug due to the instability of proto name collisions override). + +## Consequences + +This only affects clients relying directly on the go code. + +### Positive + +### Negative + +Multiple ibc-go versions cannot be imported. + +### Neutral diff --git a/docs/architecture/adr-003-ics27-acknowledgement.md b/docs/architecture/adr-003-ics27-acknowledgement.md new file mode 100644 index 0000000..ff5e719 --- /dev/null +++ b/docs/architecture/adr-003-ics27-acknowledgement.md @@ -0,0 +1,120 @@ +# ADR 003: ICS27 Acknowledgement Format + +## Changelog + +- January 28th, 2022: Initial Draft + +## Status + +Accepted + +## Context + +Upon receiving an IBC packet, an IBC application can optionally return an acknowledgement. +This acknowledgement will be hashed and written into state. Thus any changes to the information included in an acknowledgement are state machine breaking. + +ICS27 executes transactions on behalf of a controller chain. Information such as the message result or message error may be returned from other SDK modules outside the control of the ICS27 module. +It might be very valuable to return message execution information inside the ICS27 acknowledgement so that controller chain interchain account auth modules can act upon this information. +Only deterministic information returned from the message execution is allowed to be returned in the packet acknowledgement otherwise the network will halt due to a fork in the expected app hash. + +## Decision + +At the time of this writing, Tendermint includes the following information in the [ABCI.ResponseDeliverTx](https://github.com/tendermint/tendermint/blob/release/v0.34.13/types/results.go#L47-#L53): + +```go +// deterministicResponseDeliverTx strips non-deterministic fields from +// ResponseDeliverTx and returns another ResponseDeliverTx. +func deterministicResponseDeliverTx(response *abci.ResponseDeliverTx) *abci.ResponseDeliverTx { + return &abci.ResponseDeliverTx{ + Code: response.Code, + Data: response.Data, + GasWanted: response.GasWanted, + GasUsed: response.GasUsed, + } +} +``` + +### Successful acknowledgements + +Successful acknowledgements should return information about the transaction execution. +Given the deterministic fields in the `abci.ResponseDeliverTx`, the transaction `Data` can be used to indicate information about the transaction execution. +The `abci.ResponseDeliverTx.Data` will be set in the ICS27 packet acknowledgement upon successful transaction execution. + +The format for the `abci.ResponseDeliverTx.Data` is constructed by the SDK. + +At the time of this writing, the next major release of the SDK will change the format for constructing the transaction response data. + +#### v0.45 format + +The current version, v0.45 constructs the transaction response as follows: + +```go +proto.Marshal(&sdk.TxMsgData{ + Data: []*sdk.MsgData{msgResponses...}, +} +``` + +Where `msgResponses` is a slice of `*sdk.MsgData`. +The `MsgData.MsgType` contains the `sdk.MsgTypeURL` of the `sdk.Msg` being executed. +The `MsgData.Data` contains the proto marshaled `MsgResponse` for the associated message executed. + +#### Next major version format + +The next major version will construct the transaction response as follows: + +```go +proto.Marshal(&sdk.TxMsgData{ + MsgResponses: []*codectypes.Any{msgResponses...}, +} +``` + +Where `msgResponses` is a slice of the `MsgResponse`s packed into `Any`s. + +#### Forwards compatible approach + +A forwards compatible approach was deemed infeasible. +The `handler` provided by the `MsgServiceRouter` will only include the `*sdk.Result` and an error (if one occurred). +In v0.45 of the SDK, the `*sdk.Result.Data` will contain the MsgResponse marshaled data. +However, the MsgResponse is not packed and marshaled as a `*codectypes.Any`, thus making it impossible from a generalized point of view to unmarshal the bytes. +If the bytes could be unmarshaled, then they could be packed into an `*codectypes.Any` in anticipation of the upcoming format. + +Intercepting the MsgResponse before it becomes marshaled requires replicating this [code](https://github.com/cosmos/cosmos-sdk/blob/dfd47f5b449f558a855da284a9a7eabbfbad435d/baseapp/msg_service_router.go#L109-#L128). +It may not even be possible to replicate the linked code. The method handler would need to be accessed somehow. + +For these reasons it is deemed infeasible to attempt a forwards compatible approach. + +ICA auth developers can interpret which format was used when constructing the transaction response by checking if the `sdk.TxMsgData.Data` field is non-empty. +If the `sdk.TxMsgData.Data` field is not empty then the format for v0.45 was used, otherwise ICA auth developers can assume the transaction response uses the newer format. + +#### Decision + +Replicate the transaction response format as provided by the current SDK version. +When the SDK version changes, adjust the transaction response format to use the updated transaction response format. +Include the transaction response bytes in the result channel acknowledgement. + +A test has been [written](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/ibc_module_test.go#L716-#L774) to fail if the `MsgResponse` is no longer included in consensus. + +### Error acknowledgements + +As indicated above, the `abci.ResponseDeliverTx.Code` is deterministic. +Upon transaction execution errors, an error acknowledgement should be returned including the abci code. + +A test has been [written](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/types/ack_test.go#L41-#L82) to fail if the ABCI code is no longer deterministic. + +## Consequences + +> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. + +### Positive + +- interchain account auth modules can act upon transaction results without requiring a query module +- transaction results align with those returned by execution of a normal SDK message. + +### Negative + +- the security assumptions of this decision rest on the inclusion of the ABCI error code and the Msg response in the ResponseDeliverTx hash created by Tendermint +- events are non-deterministic and cannot be included in the packet acknowledgement + +### Neutral + +No neutral consequences. diff --git a/docs/architecture/adr-004-ics29-lock-fee-module.md b/docs/architecture/adr-004-ics29-lock-fee-module.md new file mode 100644 index 0000000..472d5ad --- /dev/null +++ b/docs/architecture/adr-004-ics29-lock-fee-module.md @@ -0,0 +1,58 @@ +# ADR 004: Lock fee module upon escrow out of balance + +## Changelog + +- 03/03/2022: initial draft + +## Status + +Accepted + +## Context + +The fee module maintains an escrow account for all fees escrowed to incentivize packet relays. +It also tracks each packet fee escrowed separately from the escrow account. This is because the escrow account only maintains a total balance. It has no reference for which coins belonged to which packet fee. +In the presence of a severe bug, it is possible the escrow balance will become out of sync with the packet fees marked as escrowed. +The ICS29 module should be capable of elegantly handling such a scenario. + +## Decision + +We will allow for the ICS29 module to become "locked" if the escrow balance is determined to be out of sync with the packet fees marked as escrowed. +A "locked" fee module will not allow for packet escrows to occur nor will it distribute fees. All IBC callbacks will skip performing fee logic, similar to fee disabled channels. + +Manual intervention will be needed to unlock the fee module. + +### Sending side + +Special behaviour will have to be accounted for in `OnAcknowledgementPacket`. Since the counterparty will continue to send incentivized acknowledgements for fee enabled channels, the acknowledgement will still need to be unmarshalled into an incentivized acknowledgement before calling the underlying application `OnAcknowledgePacket` callback. + +When distributing fees, a cached context should be used. If the escrow account balance would become negative, the current state changes should be discarded and the fee module should be locked using the uncached context. This prevents fees from being partially distributed for a given packetID. + +### Receiving side + +`OnRecvPacket` should remain unaffected by the fee module becoming locked since escrow accounts only affect the sending side. + +## Consequences + +### Positive + +The fee module can be elegantly disabled in the presence of severe bugs. + +### Negative + +Extra logic is added to account for edge cases which are only possible in the presence of bugs. + +### Neutral + +## References + +Issues: + +- [#821](https://github.com/cosmos/ibc-go/issues/821) +- [#860](https://github.com/cosmos/ibc-go/issues/860) + +PR's: + +- [#1031](https://github.com/cosmos/ibc-go/pull/1031) +- [#1029](https://github.com/cosmos/ibc-go/pull/1029) +- [#1056](https://github.com/cosmos/ibc-go/pull/1056) diff --git a/docs/architecture/adr-005-consensus-height-events.md b/docs/architecture/adr-005-consensus-height-events.md new file mode 100644 index 0000000..30e8a34 --- /dev/null +++ b/docs/architecture/adr-005-consensus-height-events.md @@ -0,0 +1,92 @@ +# ADR 005: UpdateClient Events - ClientState Consensus Heights + +## Changelog + +- 25/04/2022: initial draft + +## Status + +Accepted + +## Context + +The `ibc-go` implementation leverages the [Cosmos-SDK's EventManager](https://github.com/cosmos/cosmos-sdk/blob/v0.45.4/docs/core/events.md#EventManager) to provide subscribers a method of reacting to application specific events. +Some IBC relayers depend on the [`consensus_height`](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/core/02-client/keeper/events.go#L33) attribute emitted as part of `UpdateClient` events in order to run `07-tendermint` misbehaviour detection by cross-checking the details of the *Header* emitted at a given consensus height against those of the *Header* from the originating chain. This includes such details as: + +- The `SignedHeader` containing the commitment root. +- The `ValidatorSet` that signed the *Header*. +- The `TrustedHeight` seen by the client at less than or equal to the height of *Header*. +- The last `TrustedValidatorSet` at the trusted height. + +Following the refactor of the `02-client` submodule and associated `ClientState` interfaces, it will now be possible for +light client implementations to perform such actions as batch updates, inserting `N` number of `ConsensusState`s into the application state tree with a single `UpdateClient` message. This flexibility is provided in `ibc-go` by the usage of the [Protobuf `Any`](https://developers.google.com/protocol-buffers/docs/proto3#any) field contained within the [`UpdateClient`](https://github.com/cosmos/ibc-go/blob/v3.0.0/proto/ibc/core/client/v1/tx.proto#L44) message. +For example, a batched client update message serialized as a Protobuf `Any` type for the `07-tendermint` lightclient implementation could be defined as follows: + +```protobuf +message BatchedHeaders { + repeated Header headers = 1; +} +``` + +To complement this flexibility, the `UpdateClient` handler will now support the submission of [client misbehaviour](https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics#misbehaviour) by consolidating the `Header` and `Misbehaviour` interfaces into a single `ClientMessage` interface type: + +```go +// ClientMessage is an interface used to update an IBC client. +// The update may be done by a single header, a batch of headers, misbehaviour, or any type which when verified produces +// a change to state of the IBC client +type ClientMessage interface { + proto.Message + + ClientType() string + ValidateBasic() error +} +``` + +To support this functionality the `GetHeight()` method has been omitted from the new `ClientMessage` interface. +Emission of standardised events from the `02-client` submodule now becomes problematic and is two-fold: + +1. The `02-client` submodule previously depended upon the `GetHeight()` method of `Header` types in order to [retrieve the updated consensus height](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/core/02-client/keeper/client.go#L90). +2. Emitting a single `consensus_height` event attribute is not sufficient in the case of a batched client update containing multiple *Headers*. + +## Decision + +The following decisions have been made in order to provide flexibility to consumers of `UpdateClient` events in a non-breaking fashion: + +1. Return a list of updated consensus heights `[]exported.Height` from the new `UpdateState` method of the `ClientState` interface. + +```go +// UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. +// Upon successful update, a list of consensus heights is returned. It assumes the ClientMessage has already been verified. +UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) []Height +``` + +2. Maintain the `consensus_height` event attribute emitted from the `02-client` update handler, but mark as deprecated for future removal. For example, with tendermint lightclients this will simply be `consensusHeights[0]` following a successful update using a single *Header*. + +3. Add an additional `consensus_heights` event attribute, containing a comma separated list of updated heights. This provides flexibility for emitting a single consensus height or multiple consensus heights in the example use-case of batched header updates. + +## Consequences + +### Positive + +- Subscribers of IBC core events can act upon `UpdateClient` events containing one or more consensus heights. +- Deprecation of the existing `consensus_height` attribute allows consumers to continue to process `UpdateClient` events as normal, with a path to upgrade to using the `consensus_heights` attribute moving forward. + +### Negative + +- Consumers of IBC core `UpdateClient` events are forced to make future code changes. + +### Neutral + +## References + +Discussions: + +- [#1208](https://github.com/cosmos/ibc-go/pull/1208#discussion_r839691927) + +Issues: + +- [#594](https://github.com/cosmos/ibc-go/issues/594) + +PRs: + +- [#1285](https://github.com/cosmos/ibc-go/pull/1285) diff --git a/docs/architecture/adr-006-02-client-refactor.md b/docs/architecture/adr-006-02-client-refactor.md new file mode 100644 index 0000000..16ec15a --- /dev/null +++ b/docs/architecture/adr-006-02-client-refactor.md @@ -0,0 +1,203 @@ +# ADR 006: ICS-02 client refactor + +## Changelog + +- 2022-08-01: Initial Draft + +## Status + +Accepted and applied in v7 of ibc-go + +## Context + +During the initial development of the 02-client submodule, each light client supported (06-solomachine, 07-tendermint, 09-localhost) was referenced through hardcoding. +Here is an example of the [code](https://github.com/cosmos/cosmos-sdk/commit/b93300288e3a04faef9c0774b75c13b24450ba1c#diff-c5f6b956947375f28d611f18d0e670cf28f8f305300a89c5a9b239b0eeec5064R83) that existed in the 02-client submodule: + +```go +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) (exported.ClientState, error) { + ... + + switch clientType { + case exported.Tendermint: + clientState, consensusState, err = tendermint.CheckValidityAndUpdateState( + clientState, header, ctx.BlockTime(), + ) + case exported.Localhost: + // override client state and update the block height + clientState = localhosttypes.NewClientState( + ctx.ChainID(), // use the chain ID from context since the client is from the running chain (i.e self). + ctx.BlockHeight(), + ) + default: + err = types.ErrInvalidClientType + } +``` + +To add additional light clients, code would need to be added directly to the 02-client submodule. +Evidently, this would likely become problematic as IBC scaled to many chains using consensus mechanisms beyond the initial supported light clients. +Issue [#6064](https://github.com/cosmos/cosmos-sdk/issues/6064) on the SDK addressed this problem by creating a more modular 02-client submodule. +The 02-client submodule would now interact with each light client via an interface. +While, this change was positive in development, increasing the flexibility and adoptability of IBC, it also opened the door to new problems. + +The difficulty of generalizing light clients became apparent once changes to those light clients were required. +Each light client represents a different consensus algorithm which may contain a host of complexity and nuances. +Here are some examples of issues which arose for light clients that are not applicable to all the light clients supported (06-solomachine, 07-tendermint, 09-localhost): + +### Tendermint non-zero height upgrades + +Before the launch of IBC, it was determined that the golang implementation of [tendermint](https://github.com/tendermint/tendermint) would not be capable of supporting non-zero height upgrades. +This implies that any upgrade would require changing of the chain ID and resetting the height to 0. +A chain is uniquely identified by its chain-id and validator set. +Two different chain ID's can be viewed as different chains and thus a normal update produced by a validator set cannot change the chain ID. +To work around the lack of support for non-zero height upgrades, an abstract height type was created along with an upgrade mechanism. +This type would indicate the revision number (the number of times the chain ID has been changed) and revision height (the current height of the blockchain). + +Refs: + +- Issue [#439](https://github.com/cosmos/ibc/issues/439) on IBC specification repository. +- Specification changes in [#447](https://github.com/cosmos/ibc/pull/447) +- Implementation changes for the abstract height type, [SDK#7211](https://github.com/cosmos/cosmos-sdk/pull/7211) + +### Tendermint requires misbehaviour detection during updates + +The initial release of the IBC module and the 07-tendermint light client implementation did not support misbehaviour detection during update nor did it prevent overwriting of previous updates. +Despite the fact that we designed the `ClientState` interface and developed the 07-tendermint client, we failed to detect even a duplicate update that constituted misbehaviour and thus should freeze the client. +This was fixed in PR [#141](https://github.com/cosmos/ibc-go/pull/141) which required light client implementations to be aware that they must handle duplicate updates and misbehaviour detection. +Misbehaviour detection during updates is not applicable to the solomachine nor localhost. +It is also not obvious that `CheckHeaderAndUpdateState` should be performing this functionality. + +### Localhost requires access to the entire client store + +The localhost has been broken since the initial version of the IBC module. +The localhost tried to be developed underneath the 02-client interfaces without special exception, but this proved to be impossible. +The issues were outlined in [#27](https://github.com/cosmos/ibc-go/issues/27) and further discussed in the attempted ADR in [#75](https://github.com/cosmos/ibc-go/pull/75). +Unlike all other clients, the localhost requires access to the entire IBC store and not just the prefixed client store. + +### Solomachine doesn't set consensus states + +The 06-solomachine does not set the consensus states within the prefixed client store. +It has a single consensus state that is stored within the client state. +This causes setting of the consensus state at the 02-client level to use unnecessary storage. +It also causes timeouts to fail with solo machines. +Previously, the timeout logic within IBC would obtain the consensus state at the height a timeout is being proved. +This is problematic for the solo machine as no consensus state is set. +See issue [#562](https://github.com/cosmos/ibc/issues/562) on the IBC specification repo. + +### New clients may want to do batch updates + +New light clients may not function in a similar fashion to 06-solomachine and 07-tendermint. +They may require setting many consensus states in a single update. +As @seunlanlege [states](https://github.com/cosmos/ibc-go/issues/284#issuecomment-1005583679): + +> I'm in support of these changes for 2 reasons: +> +> - This would allow light clients to handle batch header updates in CheckHeaderAndUpdateState, for the special case of 11-beefy proving the finality for a batch of headers is much more space and time efficient than the space/time complexity of proving each individual headers in that batch, combined. +> +> - This also allows for a single light client instance of 11-beefy be used to prove finality for every parachain connected to the relay chain (Polkadot/Kusama). We achieve this by setting the appropriate ConsensusState for individual parachain headers in CheckHeaderAndUpdateState + +## Decision + +### Require light clients to set client and consensus states + +The IBC specification states: + +> If the provided header was valid, the client MUST also mutate internal state to store now-finalised consensus roots and update any necessary signature authority tracking (e.g. changes to the validator set) for future calls to the validity predicate. + +The initial version of the IBC go SDK based module did not fulfill this requirement. +Instead, the 02-client submodule required each light client to return the client and consensus state which should be updated in the client prefixed store. +This decision lead to the issues "Solomachine doesn't set consensus states" and "New clients may want to do batch updates". + +Each light client should be required to set its own client and consensus states on any update necessary. +The go implementation should be changed to match the specification requirements. +This will allow more flexibility for light clients to manage their own internal storage and do batch updates. + +### Merge `Header`/`Misbehaviour` interface and rename to `ClientMessage` + +Remove `GetHeight()` from the header interface (as light clients now set the client/consensus states). +This results in the `Header`/`Misbehaviour` interfaces being the same. +To reduce complexity of the codebase, the `Header`/`Misbehaviour` interfaces should be merged into `ClientMessage`. +`ClientMessage` will provide the client with some authenticated information which may result in regular updates, misbehaviour detection, batch updates, or other custom functionality a light client requires. + +### Split `CheckHeaderAndUpdateState` into 4 functions + +See [#668](https://github.com/cosmos/ibc-go/issues/668). + +Split `CheckHeaderAndUpdateState` into 4 functions: + +- `VerifyClientMessage` +- `CheckForMisbehaviour` +- `UpdateStateOnMisbehaviour` +- `UpdateState` + +`VerifyClientMessage` checks the that the structure of a `ClientMessage` is correct and that all authentication data provided is valid. + +`CheckForMisbehaviour` checks to see if a `ClientMessage` is evidence of misbehaviour. + +`UpdateStateOnMisbehaviour` freezes the client and updates its state accordingly. + +`UpdateState` performs a regular update or a no-op on duplicate updates. + +The code roughly looks like: + +```go +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { + ... + + if err := clientState.VerifyClientMessage(clientMessage); err != nil { + return err + } + + foundMisbehaviour := clientState.CheckForMisbehaviour(clientMessage) + if foundMisbehaviour { + clientState.UpdateStateOnMisbehaviour(header) + // emit misbehaviour event + return + } + + clientState.UpdateState(clientMessage) // expects no-op on duplicate header + // emit update event + return +} +``` + +### Add `GetTimestampAtHeight` to the client state interface + +By adding `GetTimestampAtHeight` to the ClientState interface, we allow light clients which do non-traditional consensus state/timestamp storage to process timeouts correctly. +This fixes the issues outlined for the solo machine client. + +### Add generic verification functions + +As the complexity and the functionality grows, new verification functions will be required for additional paths. +This was explained in [#684](https://github.com/cosmos/ibc/issues/684) on the specification repo. +These generic verification functions would be immediately useful for the new paths added in connection/channel upgradability as well as for custom paths defined by IBC applications such as Interchain Queries. +The old verification functions (`VerifyClientState`, `VerifyConnection`, etc) should be removed in favor of the generic verification functions. + +## Consequences + +### Positive + +- Flexibility for light client implementations +- Well defined interfaces and their required functionality +- Generic verification functions +- Applies changes necessary for future client/connection/channel upgrabability features +- Timeout processing for solo machines +- Reduced code complexity + +### Negative + +- The refactor touches on sensitive areas of the ibc-go codebase +- Changing of established naming (`Header`/`Misbehaviour` to `ClientMessage`) + +### Neutral + +No notable consequences + +## References + +Issues: + +- [#284](https://github.com/cosmos/ibc-go/issues/284) + +PRs: + +- [#1871](https://github.com/cosmos/ibc-go/pull/1871) diff --git a/docs/architecture/adr-007-solomachine-signbytes.md b/docs/architecture/adr-007-solomachine-signbytes.md new file mode 100644 index 0000000..f2c7eef --- /dev/null +++ b/docs/architecture/adr-007-solomachine-signbytes.md @@ -0,0 +1,52 @@ +# ADR 007: Solo machine sign bytes + +## Changelog + +- 2022-08-02: Initial draft + +## Status + +Accepted, applied in v7 + +## Context + +The `06-solomachine` implementation up until ibc-go v7 constructed sign bytes using a `DataType` which described what type of data was being signed. +This design decision arose from a misunderstanding of the security implications. +It was noted that the proto definitions do not [provide uniqueness](https://github.com/cosmos/cosmos-sdk/pull/7237#discussion_r484264573) which is a necessity for ensuring two signatures over different data types can never be the same. +What was missed is that the uniqueness is not provided by the proto definition, but by the usage of the proto definition. +The path provided by core IBC will be unique and is already encoded into the signature data. +Thus two different paths with the same data values will encode differently which provides signature uniqueness. + +Furthermore, the current construction does not support the proposed changes in the spec repo to support [Generic Verification functions](https://github.com/cosmos/ibc/issues/684). +This is because in order to verify a new path, a new `DataType` must be added for that path. + +## Decision + +Remove `DataType` and change the `DataType` in the `SignBytes` and `SignatureAndData` to be `Path`. +The new `Path` field should be bytes. +Remove all `...Data` proto definitions except for `HeaderData` +These `...Data` definitions were created previously for each `DataType`. +The proto version of the solo machine proto definitions should be bumped to `v3`. + +This removes an extra layer of complexity from signature construction and allows for support of generic verification. + +## Consequences + +### Positive + +- Simplification of solo machine signature construction +- Support for generic verification + +### Negative + +- Breaks existing signature construction in a non-backwards compatible way +- Solo machines must update to handle the new format +- Migration required for solo machine client and consensus states + +### Neutral + +No notable consequences + +## References + +- [#1141](https://github.com/cosmos/ibc-go/issues/1141) diff --git a/docs/architecture/adr-008-app-caller-cbs.md b/docs/architecture/adr-008-app-caller-cbs.md new file mode 100644 index 0000000..8f423a4 --- /dev/null +++ b/docs/architecture/adr-008-app-caller-cbs.md @@ -0,0 +1,569 @@ +# ADR 008: Callback to IBC Actors + +## Changelog + +- 2022-08-10: Initial Draft +- 2023-03-22: Merged +- 2023-09-13: Updated with decisions made in implementation +- 2025-02-24: RecvPacket callback error now returns error acknowledgement + +## Status + +Accepted, middleware implemented + +## Context + +IBC was designed with callbacks between core IBC and IBC applications. IBC apps would send a packet to core IBC. When the result of the packet lifecycle eventually resolved into either an acknowledgement or a timeout, core IBC called a callback on the IBC application so that the IBC application could take action on the basis of the result (e.g. unescrow tokens for ICS-20). + +This setup worked well for off-chain users interacting with IBC applications. + +We are now seeing the desire for secondary applications (e.g. smart contracts, modules) to call into IBC apps as part of their state machine logic and then do some actions on the basis of the packet result. Or to receive a packet from IBC and do some logic upon receipt. + +Example Usecases: + +- Send an ICS-20 packet, and if it is successful, then send an ICA-packet to swap tokens on LP and return funds to sender +- Execute some logic upon receipt of token transfer to a smart contract address + +This requires a second layer of callbacks. The IBC application already gets the result of the packet from core IBC, but currently there is no standardized way to pass this information on to an actor module/smart contract. + +## Definitions + +- Actor: an actor is an on-chain module (this may be a hardcoded module in the chain binary or a smart contract) that wishes to execute custom logic whenever IBC receives a packet flow that it has either sent or received. It **must** be addressable by a string value. + +## Decision + +Create a middleware that can interface between IBC applications and smart contract VMs. The IBC applications and smart contract VMs will implement respective interfaces that will then be composed together by the callback middleware to allow a smart contract of any compatible VM to interact programmatically with an IBC application. + +## Data structures + +The `CallbackPacketData` struct will get constructed from custom callback data in the application packet. The `CallbackAddress` is the IBC Actor address on which the callback should be called on. The `SenderAddress` is also provided to optionally allow a VM to ensure that the sender is the same as the callback address. + +The struct also defines a `CommitGasLimit` which is the maximum gas a callback is allowed to use. If the callback exceeds this limit, the callback will panic and the tx will commit without the callback's state changes. + +The `ExecutionGasLimit` is the practical limit of the tx execution that is set in the context gas meter. It is the minimum of the `CommitGasLimit` and the gas left in the context gas meter which is determined by the relayer's choice of tx gas limit. If `ExecutionGasLimit < CommitGasLimit`, then an out-of-gas error will revert the entire transaction without committing anything, allowing for a different relayer to retry with a larger tx gas limit. + +Any middleware targeting this interface for callback handling should define a global limit that caps the gas that a callback is allowed to take (especially on AcknowledgePacket and TimeoutPacket) so that a custom callback does not prevent the packet lifecycle from completing. However, since this is a global cap it is likely to be very large. Thus, users may specify a smaller limit to cap the amount of fees a relayer must pay in order to complete the packet lifecycle on the user's behalf. + +```go +// Implemented by any packet data type that wants to support PacketActor callbacks +// PacketActor's will be unable to act on any packet data type that does not implement +// this interface. +type CallbackPacketData struct { + CallbackAddress: string + ExecutionGasLimit: uint64 + SenderAddress: string + CommitGasLimit: uint64 +} +``` + +IBC Apps or middleware can then call the IBCActor callbacks like so in their own callbacks: + +### Callback Middleware + +The CallbackMiddleware wraps an underlying IBC application along with a contractKeeper that delegates the callback to a virtual machine. This allows the Callback middleware to interface any compatible IBC application with any compatible VM (e.g. EVM, WASM) so long as the application implements the `CallbacksCompatibleModule` interface and the VM implements the `ContractKeeper` interface. + +```go +// IBCMiddleware implements the ICS26 callbacks for the ibc-callbacks middleware given +// the underlying application. +type IBCMiddleware struct { + app types.CallbacksCompatibleModule + ics4Wrapper porttypes.ICS4Wrapper + + contractKeeper types.ContractKeeper + + // maxCallbackGas defines the maximum amount of gas that a callback actor can ask the + // relayer to pay for. If a callback fails due to insufficient gas, the entire tx + // is reverted if the relayer hadn't provided the minimum(userDefinedGas, maxCallbackGas). + // If the actor hasn't defined a gas limit, then it is assumed to be the maxCallbackGas. + maxCallbackGas uint64 +} +``` + +### Callback-Compatible IBC Application + +The `CallbacksCompatibleModule` extends `porttypes.IBCModule` to include an `UnmarshalPacketData` function that allows the middleware to request that the underlying app unmarshal the packet data. This will then allow the middleware to retrieve the callback specific data from an arbitrary set of IBC application packets. + +```go +// CallbacksCompatibleModule is an interface that combines the IBCModule and PacketDataUnmarshaler +// interfaces to assert that the underlying application supports both. +type CallbacksCompatibleModule interface { + porttypes.IBCModule + porttypes.PacketDataUnmarshaler +} + +// PacketDataUnmarshaler defines an optional interface which allows a middleware to +// request the packet data to be unmarshaled by the base application. +type PacketDataUnmarshaler interface { + // UnmarshalPacketData unmarshals the packet data into a concrete type + // ctx, portID, channelID are provided as arguments, so that (if needed) + // the packet data can be unmarshaled based on the channel version. + // the version of the underlying app is also returned. + UnmarshalPacketData(ctx sdk.Context, portID, channelID string, bz []byte) (interface{}, string, error) +} +``` + +The application's packet data must additionally implement the following interfaces: + +```go +// PacketData defines an optional interface which an application's packet data structure may implement. +type PacketData interface { + // GetPacketSender returns the sender address of the packet data. + // If the packet sender is unknown or undefined, an empty string should be returned. + GetPacketSender(sourcePortID string) string +} + +// PacketDataProvider defines an optional interfaces for retrieving custom packet data stored on behalf of another application. +// An existing problem in the IBC middleware design is the inability for a middleware to define its own packet data type and insert packet sender provided information. +// A short term solution was introduced into several application's packet data to utilize a memo field to carry this information on behalf of another application. +// This interfaces standardizes that behaviour. Upon realization of the ability for middleware's to define their own packet data types, this interface will be deprecated and removed with time. +type PacketDataProvider interface { + // GetCustomPacketData returns the packet data held on behalf of another application. + // The name the information is stored under should be provided as the key. + // If no custom packet data exists for the key, nil should be returned. + GetCustomPacketData(key string) interface{} +} +``` + +The callback data can be embedded in an application packet by providing custom packet data for source and destination callback in the custom packet data under the appropriate key. + +```jsonc +// Custom Packet data embedded as a JSON object in the packet data + +// src callback custom data +{ + "src_callback": { + "address": "callbackAddressString", + // optional + "gas_limit": "userDefinedGasLimitString", + } +} + +// dest callback custom data +{ + "dest_callback": { + "address": "callbackAddressString", + // optional + "gas_limit": "userDefinedGasLimitString", + } +} + +// src and dest callback custom data embedded together +{ + "src_callback": { + "address": "callbackAddressString", + // optional + "gas_limit": "userDefinedGasLimitString", + }, + "dest_callback": { + "address": "callbackAddressString", + // optional + "gas_limit": "userDefinedGasLimitString", + } +} +``` + +## ContractKeeper + +The `ContractKeeper` interface must be implemented by any VM that wants to support IBC callbacks. This allows for separation of concerns +between the middleware which is handling logic intended for all VMs (e.g. setting gas meter, extracting callback data, emitting events), +while the ContractKeeper can handle the specific details of calling into the VM in question. + +The `ContractKeeper` **may** impose additional checks such as ensuring that the contract address is the same as the packet sender in source callbacks. +It may also disable certain callback methods by simply performing a no-op. + +```go +// ContractKeeper defines the entry points exposed to the VM module which invokes a smart contract +type ContractKeeper interface { + // IBCSendPacketCallback is called in the source chain when a PacketSend is executed. The + // packetSenderAddress is determined by the underlying module, and may be empty if the sender is + // unknown or undefined. The contract is expected to handle the callback within the user defined + // gas limit, and handle any errors, or panics gracefully. + // This entry point is called with a cached context. If an error is returned, then the changes in + // this context will not be persisted, and the error will be propagated to the underlying IBC + // application, resulting in a packet send failure. + // + // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform + // validation on the origin of a given packet. It is recommended to perform the same validation + // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This + // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. + // + // The version provided is the base application version for the given packet send. This allows + // contracts to determine how to unmarshal the packetData. + IBCSendPacketCallback( + cachedCtx sdk.Context, + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + packetData []byte, + contractAddress, + packetSenderAddress string, + version string, + ) error + // IBCOnAcknowledgementPacketCallback is called in the source chain when a packet acknowledgement + // is received. The packetSenderAddress is determined by the underlying module, and may be empty if + // the sender is unknown or undefined. The contract is expected to handle the callback within the + // user defined gas limit, and handle any errors, or panics gracefully. + // This entry point is called with a cached context. If an error is returned, then the changes in + // this context will not be persisted, but the packet lifecycle will not be blocked. + // + // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform + // validation on the origin of a given packet. It is recommended to perform the same validation + // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This + // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. + // + // The version provided is the base application version for the given packet send. This allows + // contracts to determine how to unmarshal the packetData. + IBCOnAcknowledgementPacketCallback( + cachedCtx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, + contractAddress, + packetSenderAddress string, + version string, + ) error + // IBCOnTimeoutPacketCallback is called in the source chain when a packet is not received before + // the timeout height. The packetSenderAddress is determined by the underlying module, and may be + // empty if the sender is unknown or undefined. The contract is expected to handle the callback + // within the user defined gas limit, and handle any error, out of gas, or panics gracefully. + // This entry point is called with a cached context. If an error is returned, then the changes in + // this context will not be persisted, but the packet lifecycle will not be blocked. + // + // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform + // validation on the origin of a given packet. It is recommended to perform the same validation + // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This + // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. + // + // The version provided is the base application version for the given packet send. This allows + // contracts to determine how to unmarshal the packetData. + IBCOnTimeoutPacketCallback( + cachedCtx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, + contractAddress, + packetSenderAddress string, + version string, + ) error + // IBCReceivePacketCallback is called in the destination chain when a packet acknowledgement is written. + // The contract is expected to handle the callback within the user defined gas limit. + // This entry point is called with a cached context. If an error is returned, then the error + // will be written as an error acknowledgement. This will cause the context changes made by the contract + // to be reverted along with any state changes made by the underlying application. + // The error acknowledgement will then be relayed to the sending application which can perform + // its error acknowledgement logic (e.g. refunding tokens back to user) + // + // The version provided is the base application version for the given packet send. This allows + // contracts to determine how to unmarshal the packetData. + IBCReceivePacketCallback( + cachedCtx sdk.Context, + packet ibcexported.PacketI, + ack ibcexported.Acknowledgement, + contractAddress string, + version string, + ) error +} +``` + +### PacketCallbacks + +The packet callbacks implemented in the middleware will first call the underlying application and then route to the IBC actor callback in the post-processing step. +It will extract the callback data from the application packet and set the callback gas meter depending on the global limit, the user limit, and the gas left in the transaction gas meter. +The callback will then be routed through the callback keeper which will either panic or return a result (success or failure). In the event of a (non-oog) panic or an error, the callback state changes +are discarded and the transaction is committed. + +If the relayer-defined gas limit is exceeded before the user-defined gas limit or global callback gas limit is exceeded, then the entire transaction is reverted to allow for resubmission. If the chain-defined or user-defined gas limit is reached, +the callback state changes are reverted and the transaction is committed. + +For the `SendPacket` callback, we will revert the entire transaction on any kind of error or panic. This is because the packet lifecycle has not yet started, so we can revert completely to avoid starting the packet lifecycle if the callback is not successful. + +```go +// SendPacket implements source callbacks for sending packets. +// It defers to the underlying application and then calls the contract callback. +// If the contract callback returns an error, panics, or runs out of gas, then +// the packet send is rejected. +func (im IBCMiddleware) SendPacket( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, +) (uint64, error) { + // run underlying app logic first + // IBCActor logic will postprocess + seq, err := im.ics4Wrapper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) + if err != nil { + return 0, err + } + + // use underlying app to get source callback information from packet data + callbackData, err := types.GetSourceCallbackData(im.app, data, sourcePort, ctx.GasMeter().GasRemaining(), im.maxCallbackGas) + // SendPacket is not blocked if the packet does not opt-in to callbacks + if err != nil { + return seq, nil + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCSendPacketCallback( + cachedCtx, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data, callbackData.CallbackAddress, callbackData.SenderAddress, + ) + } + + err = im.processCallback(ctx, types.CallbackTypeSendPacket, callbackData, callbackExecutor) + // contract keeper is allowed to reject the packet send. + if err != nil { + return 0, err + } + + types.EmitCallbackEvent(ctx, sourcePort, sourceChannel, seq, types.CallbackTypeSendPacket, callbackData, nil) + return seq, nil +} + +// WriteAcknowledgement implements the ReceivePacket destination callbacks for the ibc-callbacks middleware +// during asynchronous packet acknowledgement. +// It defers to the underlying application and then calls the contract callback. +// If the contract callback runs out of gas and may be retried with a higher gas limit then the state changes are +// reverted via a panic. +func (im IBCMiddleware) WriteAcknowledgement( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + packet ibcexported.PacketI, + ack ibcexported.Acknowledgement, +) error { + // run underlying app logic first + // IBCActor logic will postprocess + err := im.ics4Wrapper.WriteAcknowledgement(ctx, chanCap, packet, ack) + if err != nil { + return err + } + + // use underlying app to get destination callback information from packet data + callbackData, err := types.GetDestCallbackData( + im.app, packet.GetData(), packet.GetSourcePort(), ctx.GasMeter().GasRemaining(), im.maxCallbackGas, + ) + // WriteAcknowledgement is not blocked if the packet does not opt-in to callbacks + if err != nil { + return nil + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCReceivePacketCallback(cachedCtx, packet, ack, callbackData.CallbackAddress) + } + + // callback execution errors are not allowed to block the packet lifecycle, they are only used in event emissions + err = im.processCallback(ctx, types.CallbackTypeReceivePacket, callbackData, callbackExecutor) + // emit events + types.EmitCallbackEvent( + ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), + types.CallbackTypeAcknowledgementPacket, callbackData, err, + ) + + return nil +} + +// Call the IBCActor recvPacket callback after processing the packet +// if the recvPacket callback exists. If the callback returns an error +// then return an error ack to revert all packet data processing. +func (im IBCMiddleware) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) (ack exported.Acknowledgement) { + // run underlying app logic first + // IBCActor logic will postprocess + ack := im.app.OnRecvPacket(ctx, packet, relayer) + // if ack is nil (asynchronous acknowledgements), then the callback will be handled in WriteAcknowledgement + // if ack is not successful, all state changes are reverted. If a packet cannot be received, then there is + // no need to execute a callback on the receiving chain. + if ack == nil || !ack.Success() { + return ack + } + + // use underlying app to get destination callback information from packet data + callbackData, err := types.GetDestCallbackData( + im.app, packet.GetData(), packet.GetSourcePort(), ctx.GasMeter().GasRemaining(), im.maxCallbackGas, + ) + // OnRecvPacket is not blocked if the packet does not opt-in to callbacks + if err != nil { + return ack + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCReceivePacketCallback(cachedCtx, packet, ack, callbackData.CallbackAddress) + } + + // callback execution errors are not allowed to block the packet lifecycle, they are only used in event emissions + err = im.processCallback(ctx, types.CallbackTypeReceivePacket, callbackData, callbackExecutor) + types.EmitCallbackEvent( + ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), + types.CallbackTypeReceivePacket, callbackData, err, + ) + if err != nil { + return channeltypes.NewErrorAcknowledgement(err) + } + + return ack +} + +// Call the IBCActor acknowledgementPacket callback after processing the packet +// if the ackPacket callback exists and returns an error +// DO NOT return the error upstream. The acknowledgement must complete for the packet +// lifecycle to end, so the custom callback cannot block completion. +// Instead we emit error events and set the error in state +// so that users and on-chain logic can handle this appropriately +func (im IBCModule) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + // we first call the underlying app to handle the acknowledgement + // IBCActor logic will postprocess + err := im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) + if err != nil { + return err + } + + // use underlying app to get source callback information from packet data + callbackData, err := types.GetSourceCallbackData( + im.app, packet.GetData(), packet.GetSourcePort(), ctx.GasMeter().GasRemaining(), im.maxCallbackGas, + ) + // OnAcknowledgementPacket is not blocked if the packet does not opt-in to callbacks + if err != nil { + return nil + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCOnAcknowledgementPacketCallback( + cachedCtx, packet, acknowledgement, relayer, callbackData.CallbackAddress, callbackData.SenderAddress, + ) + } + + // callback execution errors are not allowed to block the packet lifecycle, they are only used in event emissions + err = im.processCallback(ctx, types.CallbackTypeAcknowledgementPacket, callbackData, callbackExecutor) + types.EmitCallbackEvent( + ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), + types.CallbackTypeAcknowledgementPacket, callbackData, err, + ) + + return nil +} + +// Call the IBCActor timeoutPacket callback after processing the packet +// if the timeoutPacket callback exists and returns an error +// DO NOT return the error upstream. The timeout must complete for the packet +// lifecycle to end, so the custom callback cannot block completion. +// Instead we emit error events and set the error in state +// so that users and on-chain logic can handle this appropriately +func (im IBCModule) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) error { + // application-specific onTimeoutPacket logic + err := im.app.OnTimeoutPacket(ctx, packet, relayer) + if err != nil { + return err + } + + // use underlying app to get source callback information from packet data + callbackData, err := types.GetSourceCallbackData( + im.app, packet.GetData(), packet.GetSourcePort(), ctx.GasMeter().GasRemaining(), im.maxCallbackGas, + ) + // OnTimeoutPacket is not blocked if the packet does not opt-in to callbacks + if err != nil { + return nil + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCOnTimeoutPacketCallback(cachedCtx, packet, relayer, callbackData.CallbackAddress, callbackData.SenderAddress) + } + + // callback execution errors are not allowed to block the packet lifecycle, they are only used in event emissions + err = im.processCallback(ctx, types.CallbackTypeTimeoutPacket, callbackData, callbackExecutor) + types.EmitCallbackEvent( + ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), + types.CallbackTypeTimeoutPacket, callbackData, err, + ) + + return nil +} + +// processCallback executes the callbackExecutor and reverts contract changes if the callbackExecutor fails. +// +// Error Precedence and Returns: +// - oogErr: Takes the highest precedence. If the callback runs out of gas, an error wrapped with types.ErrCallbackOutOfGas is returned. +// - panicErr: Takes the second-highest precedence. If a panic occurs and it is not propagated, an error wrapped with types.ErrCallbackPanic is returned. +// - callbackErr: If the callbackExecutor returns an error, it is returned as-is. +// +// panics if +// - the contractExecutor panics for any reason, and the callbackType is SendPacket, or +// - the contractExecutor runs out of gas and the relayer has not reserved gas grater than or equal to +// CommitGasLimit. +func (IBCMiddleware) processCallback( + ctx sdk.Context, callbackType types.CallbackType, + callbackData types.CallbackData, callbackExecutor func(sdk.Context) error, +) (err error) { + cachedCtx, writeFn := ctx.CacheContext() + cachedCtx = cachedCtx.WithGasMeter(storetypes.NewGasMeter(callbackData.ExecutionGasLimit)) + + defer func() { + // consume the minimum of g.consumed and g.limit + ctx.GasMeter().ConsumeGas(cachedCtx.GasMeter().GasConsumedToLimit(), fmt.Sprintf("ibc %s callback", callbackType)) + + // recover from all panics except during SendPacket callbacks + if r := recover(); r != nil { + if callbackType == types.CallbackTypeSendPacket { + panic(r) + } + err = errorsmod.Wrapf(types.ErrCallbackPanic, "ibc %s callback panicked with: %v", callbackType, r) + } + + // if the callback ran out of gas and the relayer has not reserved enough gas, then revert the state + if cachedCtx.GasMeter().IsPastLimit() { + if callbackData.AllowRetry() { + panic(storetypes.ErrorOutOfGas{Descriptor: fmt.Sprintf("ibc %s callback out of gas; commitGasLimit: %d", callbackType, callbackData.CommitGasLimit)}) + } + err = errorsmod.Wrapf(types.ErrCallbackOutOfGas, "ibc %s callback out of gas", callbackType) + } + + // allow the transaction to be committed, continuing the packet lifecycle + }() + + err = callbackExecutor(cachedCtx) + if err == nil { + writeFn() + } + + return err +} +``` + +Chains are expected to specify a `maxCallbackGas` to ensure that callbacks do not consume an arbitrary amount of gas. Thus, it should always be possible for a relayer to complete the packet lifecycle even if the actor callbacks cannot run successfully. + +## Consequences + +### Positive + +- IBC Actors can now programmatically execute logic that involves sending a packet and then performing some additional logic once the packet lifecycle is complete +- Middleware implementing ADR-8 can be generally used for any application +- Leverages a similar callback architecture to the one used between core IBC and IBC applications + +### Negative + +- Callbacks may now have unbounded gas consumption since the actor may execute arbitrary logic. Chains implementing this feature should take care to place limitations on how much gas an actor callback can consume. +- The relayer pays for the callback gas instead of the IBCActor + +### Neutral + +- Application packets that want to support ADR-8 must additionally have their packet data implement `PacketDataProvider` and `PacketData` interfaces. +- Applications must implement `PacketDataUnmarshaler` interface +- Callback receiving module must implement the `ContractKeeper` interface + +## References + +- [Original issue](https://github.com/cosmos/ibc-go/issues/1660) +- [CallbackPacketData interface implementation](https://github.com/cosmos/ibc-go/pull/3287) +- [ICS 20, ICS 27 implementations of the CallbackPacketData interface](https://github.com/cosmos/ibc-go/pull/3287) diff --git a/docs/architecture/adr-009-v6-ics27-msgserver.md b/docs/architecture/adr-009-v6-ics27-msgserver.md new file mode 100644 index 0000000..e1fdd86 --- /dev/null +++ b/docs/architecture/adr-009-v6-ics27-msgserver.md @@ -0,0 +1,115 @@ +# ADR 009: ICS27 message server addition + +## Changelog + +- 2022/09/07: Initial draft + +## Status + +Accepted, implemented in v6 of ibc-go + +## Context + +ICS 27 (Interchain Accounts) brought a cross-chain account management protocol built upon IBC. +It enabled chains to programmatically create accounts on behalf of counterparty chains which may enable a variety of authentication methods for this interchain account. +The initial release of ICS 27 focused on enabling authentication schemes that may not require signing with a private key, such as via on-chain mechanisms like governance. + +Following the initial release of ICS 27 it became evident that: + +- a default authentication module would enable more usage of ICS 27 +- generic authentication modules should be capable of authenticating an interchain account registration +- application logic which wraps ICS 27 packet sends does not need to be associated with the authentication logic + +## Decision + +The controller module should be simplified to remove the correlation between the authentication logic for an interchain account and the application logic for an interchain account. +To minimize disruption to developers working on the original design of the ICS 27 controller module, all changes will be made in a backwards compatible fashion. + +### Msg server + +To achieve this, as stated by [@damiannolan](https://github.com/cosmos/ibc-go/issues/2026#issue-1341640594), it was proposed to: + +> Add a new `MsgServer` to `27-interchain-accounts` which exposes two distinct rpc endpoints: +> +> - `RegisterInterchainAccount` +> - `SendTx` + +This will enable any SDK (authentication) module to register interchain accounts and send transactions on their behalf. +Examples of existing SDK modules which would benefit from this change include: + +- x/auth +- x/gov +- x/group + +The existing go functions: `RegisterInterchainAccount()` and `SendTx()` will remain to operate as they did in previous release versions. + +This will be possible for SDK v0.46.x and above. + +### Allow `nil` underlying applications + +Authentication modules should interact with the controller module via the message server and should not be associated with application logic. +For now, it will be allowed to set a `nil` underlying application. +A future version may remove the underlying application entirely. + +See issue [#2040](https://github.com/cosmos/ibc-go/issues/2040) + +### Channel capability claiming + +The controller module will now claim the channel capability in `OnChanOpenInit`. +Underlying applications will be passed a `nil` capability in `OnChanOpenInit`. + +Channel capability migrations will be added in two steps: + +- Upgrade handler migration which modifies the channel capability owner from the underlying app to the controller module +- ICS 27 module automatic migration which asserts the upgrade handler channel capability migration has been performed successfully + +See issue [#2033](https://github.com/cosmos/ibc-go/issues/2033) + +### Middleware enabled channels + +In order to maintain backwards compatibility and avoid requiring underlying application developers to account for interchain accounts they did not register, a boolean mapping has been added to track the behaviour of how an account was created. + +If the account was created via the legacy API, then the underlying application callbacks will be executed. + +If the account was created with the new API (message server), then the underlying application callbacks will not be executed. + +See issue [#2145](https://github.com/cosmos/ibc-go/issues/2145) + +### Future considerations + +[ADR 008](https://github.com/cosmos/ibc-go/pull/1976) proposes the creation of a middleware which enables callers of an IBC packet send to perform application logic in conjunction with the IBC application. +The underlying application can be removed at the availability of such a middleware as that will be the preferred method for executing application logic upon a ICS 27 packet send. + +### Miscellaneous + +In order to avoid import cycles, the genesis types have been moved to their own directory. +A new protobuf package has been created for the genesis types. + +See PR [#2133](https://github.com/cosmos/ibc-go/pull/2133) + +An additional field has been added to the `ActiveChannel` type to store the `IsMiddlewareEnabled` field upon genesis import/export. + +See issue [#2165](https://github.com/cosmos/ibc-go/issues/2165) + +## Consequences + +### Positive + +- default authentication modules are provided (x/auth, x/group, x/gov) +- any SDK authentication module may now be used with ICS 27 +- separation of authentication from application logic in relation to ICS 27 +- minimized disruption to existing development around ICS 27 controller module +- underlying applications no longer have to handle capabilities +- removal of the underlying application upon the creation of ADR 008 may be done in a minimally disruptive fashion +- only underlying applications which registered the interchain account will perform application logic for that account (underlying applications do not need to be aware of accounts they did not register) + +### Negative + +- the security model has been reduced to that of the SDK. SDK modules may send packets for any interchain account. +- additional maintenance of the messages added and the middleware enabled flag +- underlying applications which will become ADR 008 modules are not required to be aware of accounts they did not register +- calling legacy API vs the new API results in different behaviour for ICS 27 application stacks which have an underlying application + +### Neutral + +- A major release is required diff --git a/docs/architecture/adr-010-light-clients-as-sdk-modules.md b/docs/architecture/adr-010-light-clients-as-sdk-modules.md new file mode 100644 index 0000000..dc8ade7 --- /dev/null +++ b/docs/architecture/adr-010-light-clients-as-sdk-modules.md @@ -0,0 +1,106 @@ +# ADR 010: IBC light clients as SDK modules + +## Changelog + +- 12/12/2022: initial draft + +## Status + +Proposed + +## Context + +ibc-go has 3 main consumers: + +- IBC light clients +- IBC applications +- relayers + +Relayers listen and respond to events emitted by ibc-go while IBC light clients and applications are invoked by core IBC. +Currently there exists two different approaches to callbacks being invoked by core IBC. + +IBC light clients currently are invoked by a `ClientState` and `ConsensusState` interface as defined by [core IBC](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L36). +The 02-client submodule will retrieve the `ClientState` or `ConsensusState` from the IBC store in order to perform callbacks to the light client. +This design requires all required information for the light client to function to be stored in the `ClientState` or `ConsensusState` or potentially under metadata keys for a specific client instance. +Additional information may be provided by core IBC via the defined interface arguments if that information is generic enough to be useful to all IBC light clients. +This constraint has proved problematic as pass through clients (such as wasm) cannot maintain easy access to a VM instance. +In addition, without increasing the size of the defined `ClientState` interface, light clients are unable to take advantage of basic built-in SDK functionality such as genesis import/export and migrations. + +The other approach used to perform callback logic is via registered SDK modules. +This approach is used by core IBC to interact with IBC applications. +IBC applications will register their callbacks on the IBC router at compile time. +When a packet comes in, core IBC will use the IBC router to lookup the registered callback functions for the provided packet. +The benefit of registered callbacks opposed to interface functions is that additional information may be accessed via external keepers. +Because the IBC applications are also SDK modules, they additionally get access to a host of functionality provided by the SDK. +This includes: genesis import/export, migrations, query/transaction CLI commands, type registration, gRPC query registration, and message server registration. + +As described in [ADR 006](./adr-006-02-client-refactor.md), generalizing light client behaviour is difficult. +IBC light clients will obtain greater flexibility and control via the registered SDK module approach. + +## Decision + +Instead of using two different approaches to invoking callbacks, IBC light clients should be invoked as SDK modules. +Over time and as necessary, core IBC should adjust its interactions with light clients such that they are SDK modules as opposed to interfaces. + +One immediate decision that has already been applied is to formalize light client type registration via the inclusion of an `AppModuleBasic` within the `ModuleManager` for a chain. +The [tendermint](https://github.com/cosmos/ibc-go/pull/2825) and [solo machine](https://github.com/cosmos/ibc-go/pull/2826) clients were refactored to include this `AppModuleBasic` implementation and core IBC will no longer include either type as registered by default. + +Longer term solutions include using internal module communication as described in [ADR 033](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-033-protobuf-inter-module-comm.md) on the SDK. +The following functions should become callbacks invoked via intermodule communication: + +- `Status` +- `GetTimestampAtHeight` +- `VerifyMembership` +- `VerifyNonMembership` +- `Initialize` +- `VerifyClientMessage` +- `CheckForMisbehaviour` +- `UpdateStateOnMisbehaviour` +- `UpdateState` +- `CheckSubstituteAndUpdateState` +- `VerifyUpgradeAndUpdateState` + +The ClientState interface should eventually be trimmed down to something along the lines of: + +```go +type ClientState interface { + proto.Message + + ClientType() string + GetLatestHeight() Height + Validate() error + + ZeroCustomFields() ClientState + + // ADDITION + Route() string // route used for intermodule communication +} +``` + +For the most part, any functions which require access to the client store should likely not be an interface function of the `ClientState`. + +`ExportMetadata` should eventually be replaced by a light client's ability to import/export it's own genesis information. + +### Intermodule communication + +To keep the transition from interface callbacks to SDK module callbacks as simple as possible, intermodule communication (when available) should be used to route to light client modules. +Without intermodule communication, a routing system would need to be developed/maintained to register callbacks. +This functionality of routing to another SDK module should and will be provided by the SDK. +Once it is possible to route to SDK modules, a `ClientState` type could expose the function `Route` which returns the callback route used to call the light client module. + +## Consequences + +### Positive + +- use a single approach for interacting with callbacks +- greater flexibility and control for IBC light clients +- does not require developing another routing system + +### Negative + +- requires breaking changes +- requires waiting for intermodule communication + +### Neutral + +N/A diff --git a/docs/architecture/adr-011-transfer-total-escrow-state-entry.md b/docs/architecture/adr-011-transfer-total-escrow-state-entry.md new file mode 100644 index 0000000..24e2f6d --- /dev/null +++ b/docs/architecture/adr-011-transfer-total-escrow-state-entry.md @@ -0,0 +1,145 @@ +# ADR 011: ICS-20 transfer state entry for total amount of tokens in escrow + +## Changelog + +- 2023-05-24: Initial draft + +## Status + +Accepted and applied in v7.1 of ibc-go + +## Context + +Every ICS-20 transfer channel has its own escrow bank account. This account is used to lock tokens that are transferred out of a chain that acts as the source of the tokens (i.e. when the tokens being transferred have not returned to the originating chain). This design makes it easy to query the balance of the escrow accounts and find out the total amount of tokens in escrow in a particular channel. However, there are use cases where it would be useful to determine the total escrowed amount of a given denomination across all channels where those tokens have been transferred out. + +For example: assuming that there are three channels between Cosmos Hub to Osmosis and 10 ATOM have been transferred from the Cosmos Hub to Osmosis on each of those channels, then we would like to know that 30 ATOM have been transferred (i.e. are locked in the escrow accounts of each channel) without needing to iterate over each escrow account to add up the balances of each. + +For a sample use case where this feature would be useful, please refer to Osmosis' rate limiting use case described in [#2664](https://github.com/cosmos/ibc-go/issues/2664). + +## Decision + +### State entry denom -> amount + +The total amount of tokens in escrow (across all transfer channels) for a given denomination is stored in state in an entry keyed by the denomination: `totalEscrowForDenom/{denom}`. + +### Panic if amount is negative + +If a negative amount is ever attempted to be stored, then the keeper function will panic: + +```go +if coin.Amount.IsNegative() { + panic(fmt.Sprintf("amount cannot be negative: %s", coin.Amount)) +} +``` + +### Delete state entry if amount is zero + +When setting the amount for a particular denomination, the value might be zero if all tokens that were transferred out of the chain have been transferred back. If this happens, then the state entry for this particular denomination will be deleted, since Cosmos SDK's `x/bank` module prunes any non-zero balances: + +```go +if coin.Amount.IsZero() { + store.Delete(key) // delete the key since Cosmos SDK x/bank module will prune any non-zero balances + return +} +``` + +### Bundle escrow/unescrow with setting state entry + +Two new functions are implemented that bundle together the operations of escrowing/unescrowing and setting the total escrow amount in state, since these operations need to be executed together. + +For escrowing tokens: + +```go +// escrowToken will send the given token from the provided sender to the escrow address. It will also +// update the total escrowed amount by adding the escrowed token to the current total escrow. +func (k Keeper) escrowToken(ctx sdk.Context, sender, escrowAddress sdk.AccAddress, token sdk.Coin) error { + if err := k.bankKeeper.SendCoins(ctx, sender, escrowAddress, sdk.NewCoins(token)); err != nil { + // failure is expected for insufficient balances + return err + } + + // track the total amount in escrow keyed by denomination to allow for efficient iteration + currentTotalEscrow := k.GetTotalEscrowForDenom(ctx, token.GetDenom()) + newTotalEscrow := currentTotalEscrow.Add(token) + k.SetTotalEscrowForDenom(ctx, newTotalEscrow) + + return nil +} +``` + +For unescrowing tokens: + +```go +// unescrowToken will send the given token from the escrow address to the provided receiver. It will also +// update the total escrow by deducting the unescrowed token from the current total escrow. +func (k Keeper) unescrowToken(ctx sdk.Context, escrowAddress, receiver sdk.AccAddress, token sdk.Coin) error { + if err := k.bankKeeper.SendCoins(ctx, escrowAddress, receiver, sdk.NewCoins(token)); err != nil { + // NOTE: this error is only expected to occur given an unexpected bug or a malicious + // counterparty module. The bug may occur in bank or any part of the code that allows + // the escrow address to be drained. A malicious counterparty module could drain the + // escrow address by allowing more tokens to be sent back then were escrowed. + return errorsmod.Wrap(err, "unable to unescrow tokens, this may be caused by a malicious counterparty module or a bug: please open an issue on counterparty module") + } + + // track the total amount in escrow keyed by denomination to allow for efficient iteration + currentTotalEscrow := k.GetTotalEscrowForDenom(ctx, token.GetDenom()) + newTotalEscrow := currentTotalEscrow.Sub(token) + k.SetTotalEscrowForDenom(ctx, newTotalEscrow) + + return nil +} +``` + +When tokens need to be escrowed in `sendTransfer`, then `escrowToken` is called; when tokens need to be unescrowed on execution of the `OnRecvPacket`, `OnAcknowledgementPacket` or `OnTimeoutPacket` callbacks, then `unescrowToken` is called. + +### gRPC query endpoint and CLI to retrieve amount + +A gRPC query endpoint is added so that it is possible to retrieve the total amount for a given denomination: + +```proto +// TotalEscrowForDenom returns the total amount of tokens in escrow based on the denom. +rpc TotalEscrowForDenom(QueryTotalEscrowForDenomRequest) returns (QueryTotalEscrowForDenomResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denoms/{denom=**}/total_escrow"; +} + +// QueryTotalEscrowForDenomRequest is the request type for TotalEscrowForDenom RPC method. +message QueryTotalEscrowForDenomRequest { + string denom = 1; +} + +// QueryTotalEscrowForDenomResponse is the response type for TotalEscrowForDenom RPC method. +message QueryTotalEscrowForDenomResponse { + cosmos.base.v1beta1.Coin amount = 1 [(gogoproto.nullable) = false]; +} +``` + +And a CLI query is also available to retrieve the total amount via the command line: + +```shell +query ibc-transfer total-escrow [denom] +``` + +## Consequences + +### Positive + +- Possibility to retrieve the total amount of a particular denomination in escrow across all transfer channels without iteration. + +### Negative + +No notable consequences + +### Neutral + +- A new entry is added to state for every denomination that is transferred out of the chain. + +## References + +Issues: + +- [#2664](https://github.com/cosmos/ibc-go/issues/2664) + +PRs: + +- [#3019](https://github.com/cosmos/ibc-go/pull/3019) +- [#3558](https://github.com/cosmos/ibc-go/pull/3558) diff --git a/docs/architecture/adr-015-ibc-packet-receiver.md b/docs/architecture/adr-015-ibc-packet-receiver.md new file mode 100644 index 0000000..37e5b79 --- /dev/null +++ b/docs/architecture/adr-015-ibc-packet-receiver.md @@ -0,0 +1,299 @@ +# ADR 015: IBC Packet Receiver + +## Changelog + +- 2019 Oct 22: Initial Draft + +## Context + +[ICS 26 - Routing Module](https://github.com/cosmos/ibc/tree/master/spec/core/ics-026-routing-module) defines a function [`handlePacketRecv`](https://github.com/cosmos/ibc/tree/master/spec/core/ics-026-routing-module#packet-relay). + +In ICS 26, the routing module is defined as a layer above each application module +which verifies and routes messages to the destination modules. It is possible to +implement it as a separate module, however, we already have the functionality to route +messages upon the destination identifiers in the baseapp. This ADR suggests +to utilize existing `baseapp.router` to route packets to application modules. + +Generally, routing module callbacks have two separate steps in them, +verification and execution. This corresponds to the `AnteHandler`-`Handler` +model inside the SDK. We can do the verification inside the `AnteHandler` +in order to increase developer ergonomics by reducing boilerplate +verification code. + +For atomic multi-message transaction, we want to keep the IBC related +state modification to be preserved even the application side state change +reverts. One of the example might be IBC token sending message following with +stake delegation which uses the tokens received by the previous packet message. +If the token receiving fails for any reason, we might not want to keep +executing the transaction, but we also don't want to abort the transaction +or the sequence and commitment will be reverted and the channel will be stuck. +This ADR suggests new `CodeType`, `CodeTxBreak`, to fix this problem. + +## Decision + +`PortKeeper` will have the capability key that is able to access only the +channels bound to the port. Entities that hold a `PortKeeper` will be +able to call the methods on it which are corresponding with the methods with +the same names on the `ChannelKeeper`, but only with the +allowed port. `ChannelKeeper.Port(string, ChannelChecker)` will be defined to +easily construct a capability-safe `PortKeeper`. This will be addressed in +another ADR and we will use insecure `ChannelKeeper` for now. + +`baseapp.runMsgs` will break the loop over the messages if one of the handlers +returns `!Result.IsOK()`. However, the outer logic will write the cached +store if `Result.IsOK() || Result.Code.IsBreak()`. `Result.Code.IsBreak()` if +`Result.Code == CodeTxBreak`. + +```go +func (app *BaseApp) runTx(tx Tx) (result Result) { + msgs := tx.GetMsgs() + + // AnteHandler + if app.anteHandler != nil { + anteCtx, msCache := app.cacheTxContext(ctx) + newCtx, err := app.anteHandler(anteCtx, tx) + if !newCtx.IsZero() { + ctx = newCtx.WithMultiStore(ms) + } + + if err != nil { + // error handling logic + return res + } + + msCache.Write() + } + + // Main Handler + runMsgCtx, msCache := app.cacheTxContext(ctx) + result = app.runMsgs(runMsgCtx, msgs) + // BEGIN modification made in this ADR + if result.IsOK() || result.IsBreak() { + // END + msCache.Write() + } + + return result +} +``` + +The Cosmos SDK will define an `AnteDecorator` for IBC packet receiving. The +`AnteDecorator` will iterate over the messages included in the transaction, type +`switch` to check whether the message contains an incoming IBC packet, and if so +verify the Merkle proof. + +```go +type ProofVerificationDecorator struct { + clientKeeper ClientKeeper + channelKeeper ChannelKeeper +} + +func (pvr ProofVerificationDecorator) AnteHandle(ctx Context, tx Tx, simulate bool, next AnteHandler) (Context, error) { + for _, msg := range tx.GetMsgs() { + var err error + switch msg := msg.(type) { + case client.MsgUpdateClient: + err = pvr.clientKeeper.UpdateClient(msg.ClientID, msg.Header) + case channel.MsgPacket: + err = pvr.channelKeeper.RecvPacket(msg.Packet, msg.Proofs, msg.ProofHeight) + case channel.MsgAcknowledgement: + err = pvr.channelKeeper.AcknowledgementPacket(msg.Acknowledgement, msg.Proof, msg.ProofHeight) + case channel.MsgTimeoutPacket: + err = pvr.channelKeeper.TimeoutPacket(msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv) + case channel.MsgChannelOpenInit; + err = pvr.channelKeeper.CheckOpen(msg.PortID, msg.ChannelID, msg.Channel) + default: + continue + } + + if err != nil { + return ctx, err + } + } + + return next(ctx, tx, simulate) +} +``` + +Where `MsgUpdateClient`, `MsgPacket`, `MsgAcknowledgement`, `MsgTimeoutPacket` +are `sdk.Msg` types correspond to `handleUpdateClient`, `handleRecvPacket`, +`handleAcknowledgementPacket`, `handleTimeoutPacket` of the routing module, +respectively. + +The side effects of `RecvPacket`, `VerifyAcknowledgement`, +`VerifyTimeout` will be extracted out into separated functions, +`WriteAcknowledgement`, `DeleteCommitment`, `DeleteCommitmentTimeout`, respectively, +which will be called by the application handlers after the execution. + +`WriteAcknowledgement` writes the acknowledgement to the state that can be +verified by the counter-party chain and increments the sequence to prevent +double execution. `DeleteCommitment` will delete the commitment stored, +`DeleteCommitmentTimeout` will delete the commitment and close channel in case +of ordered channel. + +```go +func (keeper ChannelKeeper) WriteAcknowledgement(ctx Context, packet Packet, ack []byte) { + keeper.SetPacketAcknowledgement(ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ack) + keeper.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) +} + +func (keeper ChannelKeeper) DeleteCommitment(ctx Context, packet Packet) { + keeper.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) +} + +func (keeper ChannelKeeper) DeleteCommitmentTimeout(ctx Context, packet Packet) { + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + if channel.Ordering == types.ORDERED [ + channel.State = types.CLOSED + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } +} +``` + +Each application handler should call respective finalization methods on the `PortKeeper` +in order to increase sequence (in case of packet) or remove the commitment +(in case of acknowledgement and timeout). +Calling those functions implies that the application logic has successfully executed. +However, the handlers can return `Result` with `CodeTxBreak` after calling those methods +which will persist the state changes that has been already done but prevent any further +messages to be executed in case of semantically invalid packet. This will keep the sequence +increased in the previous IBC packets(thus preventing double execution) without +proceeding to the following messages. +In any case the application modules should never return state reverting result, +which will make the channel unable to proceed. + +`ChannelKeeper.CheckOpen` method will be introduced. This will replace `onChanOpen*` defined +under the routing module specification. Instead of define each channel handshake callback +functions, application modules can provide `ChannelChecker` function with the `AppModule` +which will be injected to `ChannelKeeper.Port()` at the top level application. +`CheckOpen` will find the correct `ChannelChecker` using the +`PortID` and call it, which will return an error if it is unacceptable by the application. + +The `ProofVerificationDecorator` will be inserted to the top level application. +It is not safe to make each module responsible to call proof verification +logic, whereas application can misbehave(in terms of IBC protocol) by +mistake. + +The `ProofVerificationDecorator` should come right after the default sybil attack +resistant layer from the current `auth.NewAnteHandler`: + +```go +// add IBC ProofVerificationDecorator to the Chain of +func NewAnteHandler( + ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, ibcKeeper ibc.Keeper, + sigGasConsumer SignatureVerificationGasConsumer) sdk.AnteHandler { + return sdk.ChainAnteDecorators( + NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + ... + NewIncrementSequenceDecorator(ak), + ibcante.ProofVerificationDecorator(ibcKeeper.ClientKeeper, ibcKeeper.ChannelKeeper), // innermost AnteDecorator + ) +} +``` + +The implementation of this ADR will also create a `Data` field of the `Packet` of type `[]byte`, which can be deserialised by the receiving module into its own private type. It is up to the application modules to do this according to their own interpretation, not by the IBC keeper. This is crucial for dynamic IBC. + +Example application-side usage: + +```go +type AppModule struct {} + +// CheckChannel will be provided to the ChannelKeeper as ChannelKeeper.Port(module.CheckChannel) +func (module AppModule) CheckChannel(portID, channelID string, channel Channel) error { + if channel.Ordering != UNORDERED { + return ErrUncompatibleOrdering() + } + if channel.CounterpartyPort != "bank" { + return ErrUncompatiblePort() + } + if channel.Version != "" { + return ErrUncompatibleVersion() + } + return nil +} + +func NewHandler(k Keeper) Handler { + return func(ctx Context, msg Msg) Result { + switch msg := msg.(type) { + case MsgTransfer: + return handleMsgTransfer(ctx, k, msg) + case ibc.MsgPacket: + var data PacketDataTransfer + if err := types.ModuleCodec.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + return err + } + return handlePacketDataTransfer(ctx, k, msg, data) + case ibc.MsgTimeoutPacket: + var data PacketDataTransfer + if err := types.ModuleCodec.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + return err + } + return handleTimeoutPacketDataTransfer(ctx, k, packet) + // interface { PortID() string; ChannelID() string; Channel() ibc.Channel } + // MsgChanInit, MsgChanTry implements ibc.MsgChannelOpen + case ibc.MsgChannelOpen: + return handleMsgChannelOpen(ctx, k, msg) + } + } +} + +func handleMsgTransfer(ctx Context, k Keeper, msg MsgTransfer) Result { + err := k.SendTransfer(ctx,msg.PortID, msg.ChannelID, msg.Amount, msg.Sender, msg.Receiver) + if err != nil { + return sdk.ResultFromError(err) + } + + return sdk.Result{} +} + +func handlePacketDataTransfer(ctx Context, k Keeper, packet Packet, data PacketDataTransfer) Result { + err := k.ReceiveTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestinationPort(), packet.GetDestinationChannel(), data) + if err != nil { + // TODO: Source chain sent invalid packet, shutdown channel + } + k.ChannelKeeper.WriteAcknowledgement([]byte{0x00}) // WriteAcknowledgement increases the sequence, preventing double spending + return sdk.Result{} +} + +func handleCustomTimeoutPacket(ctx Context, k Keeper, packet CustomPacket) Result { + err := k.RecoverTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestinationPort(), packet.GetDestinationChannel(), data) + if err != nil { + // This chain sent invalid packet or cannot recover the funds + panic(err) + } + k.ChannelKeeper.DeleteCommitmentTimeout(ctx, packet) + // packet timeout should not fail + return sdk.Result{} +} + +func handleMsgChannelOpen(sdk.Context, k Keeper, msg MsgOpenChannel) Result { + k.AllocateEscrowAddress(ctx, msg.ChannelID()) + return sdk.Result{} +} +``` + +## Status + +Proposed + +## Consequences + +### Positive + +- Intuitive interface for developers - IBC handlers do not need to care about IBC authentication +- State change commitment logic is embedded into `baseapp.runTx` logic + +### Negative + +- Cannot support dynamic ports, routing is tied to the baseapp router + +### Neutral + +- Introduces new `AnteHandler` decorator. +- Dynamic ports can be supported using hierarchical port identifier, see #5290 for detail + +## References + +- Relevant comment: [cosmos/ics#289](https://github.com/cosmos/ibc/issues/289#issuecomment-544533583) +- [ICS26 - Routing Module](https://github.com/cosmos/ibc/tree/master/spec/core/ics-026-routing-module) diff --git a/docs/architecture/adr-025-ibc-passive-channels.md b/docs/architecture/adr-025-ibc-passive-channels.md new file mode 100644 index 0000000..c8f921a --- /dev/null +++ b/docs/architecture/adr-025-ibc-passive-channels.md @@ -0,0 +1,141 @@ +# ADR 025: IBC Passive Channels + +## Changelog + +- 2021-04-23: Change status to "deprecated" +- 2020-05-23: Provide sample Go code and more details +- 2020-05-18: Initial Draft + +## Status + +*deprecated* + +## Context + +The current "naive" IBC Relayer strategy currently establishes a single predetermined IBC channel atop a single connection between two clients (each potentially of a different chain). This strategy then detects packets to be relayed by watching for `send_packet` and `recv_packet` events matching that channel, and sends the necessary transactions to relay those packets. + +We wish to expand this "naive" strategy to a "passive" one which detects and relays both channel handshake messages and packets on a given connection, without the need to know each channel in advance of relaying it. + +In order to accomplish this, we propose adding more comprehensive events to expose channel metadata for each transaction sent from the `x/ibc/core/04-channel/keeper/handshake.go` and `x/ibc/core/04-channel/keeper/packet.go` modules. + +Here is an example of what would be in `ChanOpenInit`: + +```go +const ( + EventTypeChannelMeta = "channel_meta" + AttributeKeyAction = "action" + AttributeKeyHops = "hops" + AttributeKeyOrder = "order" + AttributeKeySrcPort = "src_port" + AttributeKeySrcChannel = "src_channel" + AttributeKeySrcVersion = "src_version" + AttributeKeyDstPort = "dst_port" + AttributeKeyDstChannel = "dst_channel" + AttributeKeyDstVersion = "dst_version" +) +// ... +// Emit Event with Channel metadata for the relayer to pick up and +// relay to the other chain +// This appears immediately before the successful return statement. +ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelMeta, + sdk.NewAttribute(types.AttributeKeyAction, "open_init"), + sdk.NewAttribute(types.AttributeKeySrcConnection, connectionHops[0]), + sdk.NewAttribute(types.AttributeKeyHops, strings.Join(connectionHops, ",")), + sdk.NewAttribute(types.AttributeKeyOrder, order.String()), + sdk.NewAttribute(types.AttributeKeySrcPort, portID), + sdk.NewAttribute(types.AttributeKeySrcChannel, channelID), + sdk.NewAttribute(types.AttributeKeySrcVersion, version), + sdk.NewAttribute(types.AttributeKeyDstPort, counterparty.GetPortID()), + sdk.NewAttribute(types.AttributeKeyDstChannel, counterparty.GetChannelID()), + // The destination version is not yet known, but a value is necessary to pad + // the event attribute offsets + sdk.NewAttribute(types.AttributeKeyDstVersion, ""), + ), +}) +``` + +These metadata events capture all the "header" information needed to route IBC channel handshake transactions without requiring the client to query any data except that of the connection ID that it is willing to relay. It is intended that `channel_meta.src_connection` is the only event key that needs to be indexed for a passive relayer to function. + +### Handling Channel Open Attempts + +In the case of the passive relayer, when one chain sends a `ChanOpenInit`, the relayer should inform the other chain of this open attempt and allow that chain to decide how (and if) it continues the handshake. Once both chains have actively approved the channel opening, then the rest of the handshake can happen as it does with the current "naive" relayer. + +To implement this behavior, we propose replacing the `cbs.OnChanOpenTry` callback with a new `cbs.OnAttemptChanOpenTry` callback which explicitly handles the `MsgChannelOpenTry`, usually by resulting in a call to `keeper.ChanOpenTry`. The typical implementation, in `x/ibc-transfer/module.go` would be compatible with the current "naive" relayer, as follows: + +```go +func (am AppModule) OnAttemptChanOpenTry( + ctx sdk.Context, + chanKeeper channel.Keeper, + portCap *capability.Capability, + msg channel.MsgChannelOpenTry, +) (*sdk.Result, error) { + // Require portID is the portID transfer module is bound to + boundPort := am.keeper.GetPort(ctx) + if boundPort != msg.PortID { + return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", msg.PortID, boundPort) + } + + // BEGIN NEW CODE + // Assert our protocol version, overriding the relayer's suggestion. + msg.Version = types.Version + // Continue the ChanOpenTry. + res, chanCap, err := channel.HandleMsgChannelOpenTry(ctx, chanKeeper, portCap, msg) + if err != nil { + return nil, err + } + // END OF NEW CODE + + // ... the rest of the callback is similar to the existing OnChanOpenTry + // but uses msg.* directly. +``` + +Here is how this callback would be used, in the implementation of `x/ibc/handler.go`: + +```go +// ... +case channel.MsgChannelOpenTry: + // Lookup module by port capability + module, portCap, err := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID) + if err != nil { + return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + // Delegate to the module's OnAttemptChanOpenTry. + return cbs.OnAttemptChanOpenTry(ctx, k.ChannelKeeper, portCap, msg) +``` + +The reason we do not have a more structured interaction between `x/ibc/handler.go` and the port's module (to explicitly negotiate versions, etc) is that we do not wish to constrain the app module to have to finish handling the `MsgChannelOpenTry` during this transaction or even this block. + +## Decision + +- Expose events to allow "passive" connection relayers. +- Enable application-initiated channels via such passive relayers. +- Allow port modules to control how to handle open-try messages. + +## Consequences + +### Positive + +Makes channels into a complete application-level abstraction. + +Applications have full control over initiating and accepting channels, rather than expecting a relayer to tell them when to do so. + +A passive relayer does not have to know what kind of channel (version string, ordering constraints, firewalling logic) the application supports. These are negotiated directly between applications. + +### Negative + +Increased event size for IBC messages. + +### Neutral + +More IBC events are exposed. + +## References + +- The Agoric VM's IBC handler currently [accommodates `attemptChanOpenTry`](https://github.com/Agoric/agoric-sdk/blob/904b3a0423222a1b32893453e44bbde598473960/packages/cosmic-swingset/lib/ag-solo/vats/ibc.js#L546) diff --git a/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md b/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md new file mode 100644 index 0000000..2ab6772 --- /dev/null +++ b/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md @@ -0,0 +1,90 @@ +# ADR 026: IBC Client Recovery Mechanisms + +## Changelog + +- 2020/06/23: Initial version +- 2020/08/06: Revisions per review & to reference version +- 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 +- 2023/09/05: Revision to migrate from gov v1beta1 to gov v1 + +## Status + +*Accepted* + +## Context + +### Summary + +At launch, IBC will be a novel protocol, without an experienced user-base. At the protocol layer, it is not possible to distinguish between client expiry or misbehaviour due to genuine faults (Byzantine behaviour) and client expiry or misbehaviour due to user mistakes (failing to update a client, or accidentally double-signing). In the base IBC protocol and ICS 20 fungible token transfer implementation, if a client can no longer be updated, funds in that channel will be permanently locked and can no longer be transferred. To the degree that it is safe to do so, it would be preferable to provide users with a recovery mechanism which can be utilised in these exceptional cases. + +### Exceptional cases + +The state of concern is where a client associated with connection(s) and channel(s) can no longer be updated. This can happen for several reasons: + +1. The chain which the client is following has halted and is no longer producing blocks/headers, so no updates can be made to the client +1. The chain which the client is following has continued to operate, but no relayer has submitted a new header within the unbonding period, and the client has expired + 1. This could be due to real misbehaviour (intentional Byzantine behaviour) or merely a mistake by validators, but the client cannot distinguish these two cases +1. The chain which the client is following has experienced a misbehaviour event, and the client has been frozen & thus can no longer be updated + +### Security model + +Two-thirds of the validator set (the quorum for governance, module participation) can already sign arbitrary data, so allowing governance to manually force-update a client with a new header after a delay period does not substantially alter the security model. + +## Decision + +We elect not to deal with chains which have actually halted, which is necessarily Byzantine behaviour and in which case token recovery is not likely possible anyways (in-flight packets cannot be timed-out, but the relative impact of that is minor). + +1. Require Tendermint light clients (ICS 07) to be created with the following additional flags + 1. `allow_update_after_expiry` (boolean, default true). Note that this flag has been deprecated, it remains to signal intent but checks against this value will not be enforced. +1. Require Tendermint light clients (ICS 07) to expose the following additional internal query functions + 1. `Expired() boolean`, which returns whether or not the client has passed the trusting period since the last update (in which case no headers can be validated) +1. Require Tendermint light clients (ICS 07) & solo machine clients (ICS 06) to be created with the following additional flags + 1. `allow_update_after_misbehaviour` (boolean, default true). Note that this flag has been deprecated, it remains to signal intent but checks against this value will not be enforced. +1. Require Tendermint light clients (ICS 07) to expose the following additional state mutation functions + 1. `Unfreeze()`, which unfreezes a light client after misbehaviour and clears any frozen height previously set +1. Add a new governance proposal with `MsgRecoverClient`. + 1. Create a new Msg with two client identifiers (`string`) and a signer. + 1. The first client identifier is the proposed client to be updated. This client must be either frozen or expired. + 1. The second client is a substitute client. It carries all the state for the client which may be updated. It must have identical client and chain parameters to the client which may be updated (except for latest height, frozen height, and chain-id). It should be continually updated during the voting period. + 1. If this governance proposal passes, the client on trial will be updated to the latest state of the substitute. + 1. The signer must be the authority set for the ibc module. + + 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 initially 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. + + In versions older than ibc-go v8, `MsgRecoverClient` was a governance proposal type `ClientUpdateProposal`. It has been removed and replaced by `MsgRecoverClient` in the migration from governance v1beta1 to governance v1. + + Note that this should NOT be lightly updated, as there may be a gap in time between when misbehaviour has occurred 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. + +This ADR does not address planned upgrades, which are handled separately as per the [specification](https://github.com/cosmos/ibc/tree/master/spec/client/ics-007-tendermint-client#upgrades). + +## Consequences + +### Positive + +- Establishes a mechanism for client recovery in the case of expiry +- Establishes a mechanism for client recovery in the case of misbehaviour +- Constructing an ClientUpdate Proposal is as difficult as creating a new client + +### Negative + +- Additional complexity in client creation which must be understood by the user +- Coping state of the substitute adds complexity +- Governance participants must vote on a substitute client + +### Neutral + +No neutral consequences. + +## References + +- [Prior discussion](https://github.com/cosmos/ibc/issues/421) +- [Epoch number discussion](https://github.com/cosmos/ibc/issues/439) +- [Upgrade plan discussion](https://github.com/cosmos/ibc/issues/445) +- [Migration from gov v1beta1 to gov v1](https://github.com/cosmos/ibc-go/issues/3672) diff --git a/docs/architecture/adr-027-ibc-wasm.md b/docs/architecture/adr-027-ibc-wasm.md new file mode 100644 index 0000000..122c820 --- /dev/null +++ b/docs/architecture/adr-027-ibc-wasm.md @@ -0,0 +1,167 @@ +# ADR 27: Add support for Wasm based light client + +## Changelog + +- 26/11/2020: Initial Draft +- 26/05/2023: Update after 02-client refactor and re-implementation by Strangelove +- 13/12/2023: Update after upstreaming of module to ibc-go + +## Status + +*Accepted and applied in v0.1.0 of 08-wasm* + +## Abstract + +In the Cosmos SDK light clients are currently hardcoded in Go. This makes upgrading existing IBC light clients or +adding support for new light client a multi step process involving on-chain governance which is time-consuming. + +To remedy this, we are proposing a Wasm VM to host light client bytecode, which allows easier upgrading of +existing IBC light clients as well as adding support for new IBC light clients without requiring a code release and +corresponding hard-fork event. + +## Context + +Currently in ibc-go light clients are defined as part of the codebase and are implemented as modules under +`modules/light-clients`. Adding support for new light clients or updating an existing light client in the event +of a security issue or consensus update is a multi-step process which is both time-consuming and error-prone. +In order to enable new IBC light client implementations it is necessary to modify the codebase of ibc-go (if the light +client is part of its codebase), re-build chains' binaries, pass a governance proposal and validators upgrade their nodes. + +Another problem stemming from the above process is that if a chain wants to upgrade its own consensus, it will +need to convince every chain or hub connected to it to upgrade its light client in order to stay connected. Due +to the time-consuming process required to upgrade a light client, a chain with lots of connections needs to be +disconnected for quite some time after upgrading its consensus, which can be very expensive in terms of time and effort. + +We are proposing simplifying this workflow by integrating a Wasm light client module that makes adding support for +new light clients a simple governance-gated transaction. The light client bytecode, written in Wasm-compilable Rust, +runs inside a Wasm VM. The Wasm light client submodule exposes a proxy light client interface that routes incoming +messages to the appropriate handler function, inside the Wasm VM for execution. + +With the Wasm light client module, anybody can add new IBC light client in the form of Wasm bytecode (provided they are +able to submit the governance proposal transaction and that it passes) as well as instantiate clients using any created +client type. This allows any chain to update its own light client in other chains without going through the steps outlined above. + +## Decision + +We decided to implement the Wasm light client module as a light client proxy that will interface with the actual light client +uploaded as Wasm bytecode. To enable usage of the Wasm light client module, users need to add it to the list of allowed clients +by updating the `AllowedClients` parameter in the 02-client submodule of core IBC. + +```go +params := clientKeeper.GetParams(ctx) +params.AllowedClients = append(params.AllowedClients, exported.Wasm) +clientKeeper.SetParams(ctx, params) +``` + +Adding a new light client contract is governance-gated. To upload a new light client users need to submit +a [governance v1 proposal](https://docs.cosmos.network/main/modules/gov#proposals) that contains the `sdk.Msg` for storing +the Wasm contract's bytecode. The required message is `MsgStoreCode` and the bytecode is provided in the field `wasm_byte_code`: + +```proto +// MsgStoreCode defines the request type for the StoreCode rpc. +message MsgStoreCode { + // signer address + string signer = 1; + // wasm byte code of light client contract. It can be raw or gzip compressed + bytes wasm_byte_code = 2; +} +``` + +The RPC handler processing `MsgStoreCode` will make sure that the signer of the message matches the address of authority allowed to +submit this message (which is normally the address of the governance module). + +```go +// StoreCode defines a rpc handler method for MsgStoreCode +func (k Keeper) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*types.MsgStoreCodeResponse, error) { + if k.GetAuthority() != msg.Signer { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Signer) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + checksum, err := k.storeWasmCode(ctx, msg.WasmByteCode, ibcwasm.GetVM().StoreCode) + if err != nil { + return nil, errorsmod.Wrap(err, "failed to store wasm bytecode") + } + + emitStoreWasmCodeEvent(ctx, checksum) + + return &types.MsgStoreCodeResponse{ + Checksum: checksum, + }, nil +} +``` + +The contract's bytecode is not stored in state (it is actually unnecessary and wasteful to store it, since +the Wasm VM already stores it and can be queried back, if needed). The checksum is simply the hash of the bytecode +of the contract and it is stored in state in an entry with key `checksums` that contains the checksums for the bytecodes that have been stored. + +### How light client proxy works? + +The light client proxy behind the scenes will call a CosmWasm smart contract instance with incoming arguments serialized +in JSON format with appropriate environment information. Data returned by the smart contract is deserialized and +returned to the caller. + +Consider the example of the `VerifyClientMessage` function of `ClientState` interface. Incoming arguments are +packaged inside a payload object that is then JSON serialized and passed to `queryContract`, which executes `WasmVm.Query` +and returns the slice of bytes returned by the smart contract. This data is deserialized and passed as return argument. + +```go +type QueryMsg struct { + Status *StatusMsg `json:"status,omitempty"` + ExportMetadata *ExportMetadataMsg `json:"export_metadata,omitempty"` + TimestampAtHeight *TimestampAtHeightMsg `json:"timestamp_at_height,omitempty"` + VerifyClientMessage *VerifyClientMessageMsg `json:"verify_client_message,omitempty"` + CheckForMisbehaviour *CheckForMisbehaviourMsg `json:"check_for_misbehaviour,omitempty"` +} + +type verifyClientMessageMsg struct { + ClientMessage *ClientMessage `json:"client_message"` +} + +// VerifyClientMessage must verify a ClientMessage. +// A ClientMessage could be a Header, Misbehaviour, or batch update. +// It must handle each type of ClientMessage appropriately. +// Calls to CheckForMisbehaviour, UpdateStaåte, and UpdateStateOnMisbehaviour +// will assume that the content of the ClientMessage has been verified +// and can be trusted. An error should be returned +// if the ClientMessage fails to verify. +func (cs ClientState) VerifyClientMessage( + ctx sdk.Context, + _ codec.BinaryCodec, + clientStore storetypes.KVStore, + clientMsg exported.ClientMessage +) error { + clientMessage, ok := clientMsg.(*ClientMessage) + if !ok { + return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "expected type: %T, got: %T", &ClientMessage{}, clientMsg) + } + + payload := QueryMsg{ + VerifyClientMessage: &VerifyClientMessageMsg{ClientMessage: clientMessage.Data}, + } + _, err := wasmQuery[EmptyResult](ctx, clientStore, &cs, payload) + return err +} +``` + +### Global Wasm VM variable + +The 08-wasm keeper structure keeps a reference to the Wasm VM instantiated in the keeper constructor function. The keeper uses +the Wasm VM to store the bytecode of light client contracts. However, the Wasm VM is also needed in the 08-wasm implementations of +some of the `ClientState` interface functions to initialise a contract, execute calls on the contract and query the contract. Since +the `ClientState` functions do not have access to the 08-wasm keeper, then it has been decided to keep a global pointer variable that +points to the same instance as the one in the 08-wasm keeper. This global pointer variable is then used in the implementations of +the `ClientState` functions. + +## Consequences + +### Positive + +- Adding support for new light client or upgrading existing light client is way easier than before and only requires single transaction instead of a hard-fork. +- Improves maintainability of ibc-go, since no change in codebase is required to support new client or upgrade it. +- The existence of support for Rust dependencies in light clients which may not exist in Go. + +### Negative + +- Light clients written in Rust need to be written in a subset of Rust which could compile in Wasm. +- Introspecting light client code is difficult as only compiled bytecode exists in the blockchain. diff --git a/docs/architecture/adr.template.md b/docs/architecture/adr.template.md new file mode 100644 index 0000000..4a9d2ef --- /dev/null +++ b/docs/architecture/adr.template.md @@ -0,0 +1,38 @@ +# ADR \{ADR-NUMBER\}: \{TITLE\} + +## Changelog + +- \{date\}: \{changelog\} + +## Status + +> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. + +\{Deprecated|Proposed|Accepted\} + +## Context + +> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high-level idea behind the solution. + +## Decision + +> This section explains all of the details of the proposed solution, including implementation details. +It should also describe affects / corollary items that may need to be changed as a part of this. +If the proposed change will be large, please also indicate a way to do the change to maximize ease of review. +(e.g. the optimal split of things to do between separate PR's) + +## Consequences + +> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. + +### Positive + +### Negative + +### Neutral + +## References + +> Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here! + +- \{reference link\} diff --git a/docs/audits/04-channel-upgrades/Atredis Partners - Interchain Foundation IBC-Go Channel Upgrade Feature Assessment - Report v1.1.pdf b/docs/audits/04-channel-upgrades/Atredis Partners - Interchain Foundation IBC-Go Channel Upgrade Feature Assessment - Report v1.1.pdf new file mode 100644 index 0000000000000000000000000000000000000000000000000000000000000000..8af1352d976febff5ebdff2a1d3a12f5c47207d22d28efe03791f8e02cb65f0f GIT binary patch literal 1022554 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
;~E~@`R-keRyUg0x#QvP~{ys7Gs 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�e6ZUNFY`c| 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 z"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 z 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
Xm1hsc*J(RR6`&E`n$z0d@p}VaO{SW}?1J9- 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