diff --git a/x/tx/CHANGELOG.md b/x/tx/CHANGELOG.md index 54a09a50e7..951ee0b521 100644 --- a/x/tx/CHANGELOG.md +++ b/x/tx/CHANGELOG.md @@ -37,6 +37,7 @@ Since v0.13.0, x/tx follows Cosmos SDK semver: https://github.com/cosmos/cosmos- * SDK v0.53.x support. * [#23708](https://github.com/cosmos/cosmos-sdk/pull/23708) Add unordered transaction support. +* [#24409](https://github.com/cosmos/cosmos-sdk/pull/24409) Fallback to injected resolver for placeholder descriptors. ## [v0.13.8](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.8) - 2025-01-28 diff --git a/x/tx/decode/unknown.go b/x/tx/decode/unknown.go index acc994f87a..3a30ef8987 100644 --- a/x/tx/decode/unknown.go +++ b/x/tx/decode/unknown.go @@ -96,6 +96,17 @@ func doRejectUnknownFields( if fieldMessage == nil { continue } + // if a message descriptor is a placeholder resolve it using the injected resolver. + // this can happen when a descriptor has been registered in the + // "google.golang.org/protobuf" resgistry but not in "github.com/cosmos/gogoproto". + // fixes: https://github.com/cosmos/cosmos-sdk/issues/22574 + if fieldMessage.IsPlaceholder() { + gogoDesc, err := resolver.FindDescriptorByName(fieldMessage.FullName()) + if err != nil { + return hasUnknownNonCriticals, fmt.Errorf("could not resolve placeholder descriptor: %v: %w", fieldMessage, err) + } + fieldMessage = gogoDesc.(protoreflect.MessageDescriptor) + } // consume length prefix of nested message _, o := protowire.ConsumeVarint(fieldBytes)