Skip to content

fix(app): wire address codec into InterfaceRegistry (fixes broken staking/distribution txs on v4.0.0) - #210

Merged
ECHOAD merged 3 commits into
envadiv:v4.0.xfrom
Ninjaxan:fix/interface-registry-address-codec
Jul 9, 2026
Merged

fix(app): wire address codec into InterfaceRegistry (fixes broken staking/distribution txs on v4.0.0)#210
ECHOAD merged 3 commits into
envadiv:v4.0.xfrom
Ninjaxan:fix/interface-registry-address-codec

Conversation

@Ninjaxan

@Ninjaxan Ninjaxan commented Jul 9, 2026

Copy link
Copy Markdown

Problem

On v4.0.x (Cosmos SDK v0.50), every staking and distribution transaction fails network-wide with:

InterfaceRegistry requires a proper address codec implementation to do address conversion

Affected messages are all those that carry a validator (…valoper) address:
MsgDelegate, MsgUndelegate, MsgBeginRedelegate, MsgWithdrawDelegatorReward.
Plain MsgSend (bank) is unaffected, which is what makes this easy to miss.

Root cause

app/params/proto.go builds the InterfaceRegistry with the codec-less
types.NewInterfaceRegistry(). Under SDK v0.50 the registry must be created
with an address codec via SigningOptions, or any address conversion during
tx build/decode/sign fails.

This encoding config is not test-only despite the name — it flows into both:

  • the CLI: cmd/passage/cmd/root.goapp.MakeEncodingConfig()params.MakeTestEncodingConfig()
  • the node: NewPassageApp(...)bApp.SetInterfaceRegistry(encodingConfig.InterfaceRegistry)

so the missing codec breaks both client-side tx building and server-side tx
processing. The correctly-wired codecs already exist for autocli in
app.go, but the app/CLI codec path never receives them.

Fix

Construct the registry with NewInterfaceRegistryWithOptions and the
pasg / pasgvaloper bech32 codecs.

Verification

go build ./cmd/passage passes, and the CLI now generates the previously
failing transactions:

$ passage tx distribution withdraw-rewards <valoper> --from <addr> --generate-only
{"body":{"messages":[{"@type":"/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", ...}]}}   # was: address-codec error
$ passage tx staking delegate <valoper> 1000000upasg --from <addr> --generate-only
{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate", ...}]}}                      # was: address-codec error
$ passage tx bank send <addr> <addr> 1upasg --generate-only
{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend", ...}]}}                             # still works

Note: main carries the same defect and needs the same change.

MakeTestEncodingConfig built the InterfaceRegistry with the codec-less
types.NewInterfaceRegistry(). Under Cosmos SDK v0.50 the registry must carry
an address codec via SigningOptions, otherwise every message that references a
validator (valoper) address — MsgDelegate, MsgUndelegate, MsgBeginRedelegate,
MsgWithdrawDelegatorReward — fails with:

  InterfaceRegistry requires a proper address codec implementation to do
  address conversion

This encoding config feeds both the CLI (app.MakeEncodingConfig) and the node
(NewPassageApp -> SetInterfaceRegistry), so the missing codec silently breaks
all staking and distribution transactions network-wide while plain bank sends
keep working. Construct the registry with NewInterfaceRegistryWithOptions and
the pasg / pasgvaloper bech32 codecs.

Verified: go build passes and the CLI now generates MsgWithdrawDelegatorReward
and MsgDelegate txs that previously errored.
@Ninjaxan

Ninjaxan commented Jul 9, 2026

Copy link
Copy Markdown
Author

The three failing checks (Build / Tests / golangci-lint) are pre-existing CI breakage unrelated to this change — they fail on the base branch for any PR.

The workflows install an older Go than the code requires:

  • .github/workflows/build.yml and test.yml pin go-version: 1.19
  • .github/workflows/lint.yml pins go-version: "1.20"
  • but go.mod declares go 1.21, and the SDK v0.50 dependency tree uses crypto/ecdh (Go 1.20), maps and slices (Go 1.21)

Hence the build errors like package slices is not in GOROOT (.../go/1.19.13/...) — the toolchain can't compile the module at all, independent of this diff.

This one-file change builds and runs cleanly on Go 1.21:

$ go build ./cmd/passage            # OK
$ passage tx distribution withdraw-rewards <valoper> --from <addr> --generate-only
{"body":{"messages":[{"@type":"/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", ...}]}}
$ passage tx staking delegate <valoper> 1000000upasg --from <addr> --generate-only
{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate", ...}]}}

Bumping the CI go-version to 1.21 (a separate concern from this fix) would let these checks run meaningfully. Happy to include that here or in a separate PR — whichever you prefer.

ibc-go v8 no longer bundles the light-client modules inside
ibc.AppModuleBasic. Without ibctm registered, any decode of an
/ibc.lightclients.tendermint.v1.ClientState Any fails with
"no concrete type registered for type URL ... against interface
*exported.ClientState" - breaking IBC client-state queries and
transfer timeout resolution on both client and node.

Verified: full message-surface battery (one generate-only tx per
wired module incl. ibc-transfer with absolute timeouts) passes
18/18 on the patched binary; the staking/distribution messages
and IBC client-state decode all fail on unpatched v4.0.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Ninjaxan

Ninjaxan commented Jul 9, 2026

Copy link
Copy Markdown
Author

Pushed a second commit — this PR now fixes TWO v4.0.0 registry bugs, not one.

While gate-testing the first fix with a full message-surface battery (one --generate-only tx per wired module), we found IBC is also broken on v4.0.0: the ibc-go v7→v8 migration means ibc.AppModuleBasic{} no longer registers the light-client modules, and ibctm (07-tendermint) was never added to ModuleBasics. Any decode of an /ibc.lightclients.tendermint.v1.ClientState fails with:

no concrete type registered for type URL /ibc.lightclients.tendermint.v1.ClientState against interface *exported.ClientState

This breaks IBC client-state queries and ibc-transfer timeout resolution on both the CLI and the node (reproducible against any live v4.0.0 RPC — the error comes back from the node side).

Fix is 4 lines in app/app.go: import + register ibctm.AppModuleBasic{} and solomachine.AppModuleBasic{} (mirrors ibc-go v8 simapp).

Verification (patched binary): 18/18 battery pass — bank send, staking delegate/unbond/redelegate, distribution withdraw/set-withdraw-addr, gov vote, authz grant, feegrant grant, ibc-transfer (absolute timeouts), wasm execute, plus the LCD query battery. On unpatched v4.0.0 the same battery fails exactly the 5 staking/distribution messages (address-codec bug) and the IBC client-state decode (this bug).

Given both staking/distribution AND IBC are affected network-wide, we'd suggest treating this as release-blocking for a coordinated v4.0.1. Happy to help coordinate — we have reproducible-build infrastructure ready from the v4.0.0 release.

The 0.47->0.50 port dropped cosmwasm_1_3 from availableCapabilities
(v3.0.0 had "iterator,staking,stargate,cosmwasm_1_1,cosmwasm_1_2,
cosmwasm_1_3"; v4.0.0 shipped without cosmwasm_1_3). Contracts
requiring 1_3 features that v3.0.0 accepted at store-code would be
rejected on v4.0.0. wasmvm 1.5.x fully supports cosmwasm_1_3.
Restores exact v3.0.0 parity; no new capabilities introduced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Ninjaxan
Ninjaxan force-pushed the fix/interface-registry-address-codec branch from 438bb68 to bd51aff Compare July 9, 2026 14:42
@Ninjaxan

Ninjaxan commented Jul 9, 2026

Copy link
Copy Markdown
Author

Third fix pushed: the 0.47->0.50 port also dropped \cosmwasm_1_3\ from the wasm \�vailableCapabilities\ (v3.0.0 had it; v4.0.0 shipped without). Contracts requiring 1_3 features that v3.0.0 accepted would be rejected at store-code on v4.0.0. Restored to exact v3.0.0 parity - no new capabilities introduced. Also audited every module in the module manager against ModuleBasics registrations: no further gaps of the ibctm class. Extended verification battery (tx construction x11 modules, direct + amino-json signing, stored-Any decode of all historical gov proposals and vesting accounts, LCD query battery) passes 22/22 on the branch head.

@ECHOAD
ECHOAD merged commit fd7bcad into envadiv:v4.0.x Jul 9, 2026
2 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants