Contribuições Go upstream ao Cosmos SDK AutoCLI e IBC-Go

Minhas contribuições Go upstream ao Cosmos SDK e ao IBC-Go trataram dois problemas de integração de aplicações: decodificação de comandos AutoCLI com metadados protobuf incompletos e inspeção de escopos de capabilities antes de criá-los. Uma mudou a origem dos descritores de arquivos protobuf; a outra adicionou um helper restrito de consulta. Ambas ficam nas fronteiras entre interfaces geradas e composição da aplicação.

AutoCLI: a falha de decodificação relatada

O PR #24330 do Cosmos SDK relatava falhas de decodificação em comandos AutoCLI de novos módulos após um upgrade do Go e a remoção de Pulsar da aplicação. AutoCLI monta interfaces de linha de comando a partir de descrições protobuf. O diagnóstico relatado era que o registro de interfaces, quando usado como resolvedor de arquivos, podia expor descritores incompletos de uma mensagem também referenciada dentro de outra mensagem.

O PR usou uma mensagem AddressList referenciada por uma mensagem Genesis para ilustrar o problema. Seu diagnóstico descrevia descritores placeholder e ordem de registro: um comando podia encontrar metadados incompletos do tipo que precisava decodificar. A implementação tratou o resolvedor usado durante a construção dos comandos, portanto a mudança ficou no builder compartilhado do AutoCLI, em vez de nos comandos gerados de um módulo específico.

Trocar o resolvedor de arquivos

O patch aceito chamou a função de registro combinado do gogoproto antes de construir o builder AutoCLI. Se a construção do registro falhasse, retornava o erro. O registro resultante passou a ser o FileResolver do builder, enquanto seu TypeResolver continuou sendo o registro global de tipos. Um resolvedor de arquivos fornece descritores de arquivos protobuf; nessa mudança, ele era uma dependência distinta do resolvedor usado para tipos de mensagens.

A mudança ajustou a origem dos metadados na fronteira de construção de comandos, em vez de adicionar contornos a cada comando gerado. Isso concentrou a correção, mas tornou a construção do registro um ponto explícito de falha. Retornar seu erro significava que o builder não continuaria com esse registro indisponível. A distinção entre resolução de arquivos e de tipos também permaneceu intacta: o patch mudou uma dependência e preservou a outra.

IBC-Go: inspecionar um escopo antes de criá-lo

No PR #6716 do IBC-Go, adicionei HasModule(moduleName string) bool ao keeper de capabilities. Sua implementação verificava se o nome do módulo existia no map scopedModules do keeper. Scoped keeper é o escopo de capabilities específico de um módulo nesse código. A documentação de ScopeToModule diz que criar um escopo para um módulo já registrado causa panic. O novo helper expôs uma verificação de existência para a composição da aplicação antes de tentar essa operação.

O teste adicionado criava um escopo para o módulo bank, verificava que HasModule retornava true para ele e false para um nome de módulo inválido. Isso demonstra o comportamento coberto pelo teste e a interface intencionalmente restrita: quem chama pode inspecionar a existência do escopo. A contribuição não transformou ScopeToModule em uma operação que reutiliza silenciosamente um escopo existente.

O trade-off da composição

Um pequeno helper de consulta preservou o contrato de criação de escopos existente e deu ao código da aplicação uma forma de evitar uma criação duplicada acidental. Alterar a criação para reutilizar um escopo existente mudaria um contrato mais amplo. Com HasModule, quem chama ainda decide como tratar um escopo existente. A verificação sozinha não oferece garantia de concorrência nem impede a criação duplicada por chamadores que a ignoram; sua responsabilidade é informar a presença atual do módulo no keeper.

Escopo das contribuições

As mudanças vinculadas foram integradas upstream: IBC-Go #6716 em julho de 2024 e Cosmos SDK #24330 em abril de 2025. Elas documentam contribuições Go específicas em interfaces para desenvolvedores e composição de módulos. Uma fornece outra origem de metadados para a construção de comandos; a outra expõe um estado necessário aos chamadores ao compor uma aplicação. Seu escopo são essas mudanças aceitas, e não implantação downstream ou desempenho de rede.

Fontes públicas