diff --git a/baseapp/streaming.go b/baseapp/streaming.go index 7d88c2d196..7e2e98db09 100644 --- a/baseapp/streaming.go +++ b/baseapp/streaming.go @@ -37,10 +37,11 @@ const ( // types of streaming listeners. func (app *BaseApp) EnableIndexer(indexerOpts interface{}, keys map[string]*storetypes.KVStoreKey, appModules map[string]any) error { listener, err := indexer.StartIndexing(indexer.IndexingOptions{ - Config: indexerOpts, - Resolver: decoding.ModuleSetDecoderResolver(appModules), - SyncSource: nil, - Logger: app.logger.With(log.ModuleKey, "indexer"), + Config: indexerOpts, + Resolver: decoding.ModuleSetDecoderResolver(appModules), + Logger: app.logger.With(log.ModuleKey, "indexer"), + SyncSource: nil, // TODO: Support catch-up syncs + AddressCodec: app.interfaceRegistry.SigningContext().AddressCodec(), }) if err != nil { return err diff --git a/server/v2/cometbft/server.go b/server/v2/cometbft/server.go index 1182924a4f..02cf66dbf3 100644 --- a/server/v2/cometbft/server.go +++ b/server/v2/cometbft/server.go @@ -151,9 +151,11 @@ func New[T transaction.Tx]( var listener *appdata.Listener if indexerCfg := srv.config.AppTomlConfig.Indexer; len(indexerCfg.Target) > 0 { indexingTarget, err := indexer.StartIndexing(indexer.IndexingOptions{ - Config: indexerCfg, - Resolver: decoderResolver, - Logger: logger.With(log.ModuleKey, "indexer"), + Config: indexerCfg, + Resolver: decoderResolver, + Logger: logger.With(log.ModuleKey, "indexer"), + SyncSource: nil, // TODO: Support catch-up syncs + AddressCodec: appCodecs.AppCodec.InterfaceRegistry().SigningContext().AddressCodec(), }) if err != nil { return nil, fmt.Errorf("failed to start indexing: %w", err) diff --git a/types/collections.go b/types/collections.go index cb7490af13..00e3904357 100644 --- a/types/collections.go +++ b/types/collections.go @@ -8,6 +8,7 @@ import ( "cosmossdk.io/collections" collcodec "cosmossdk.io/collections/codec" "cosmossdk.io/math" + "cosmossdk.io/schema" ) var ( @@ -119,6 +120,28 @@ func (a genericAddressKey[T]) SizeNonTerminal(key T) int { return collections.BytesKey.SizeNonTerminal(key) } +func (a genericAddressKey[T]) SchemaCodec() (collcodec.SchemaCodec[T], error) { + return collcodec.SchemaCodec[T]{ + Fields: []schema.Field{{Kind: schema.AddressKind}}, + ToSchemaType: func(t T) (any, error) { + if len(t) == 0 { + return nil, fmt.Errorf("invalid empty address") + } + return t, nil + }, + FromSchemaType: func(s any) (T, error) { + addr, ok := s.([]byte) + if !ok { + return nil, fmt.Errorf("expected []byte, got %T", s) + } + if len(addr) == 0 { + return nil, fmt.Errorf("invalid empty address") + } + return T(addr), nil + }, + }, nil +} + // Deprecated: lengthPrefixedAddressKey is a special key codec used to retain state backwards compatibility // when a generic address key (be: AccAddress, ValAddress, ConsAddress), is used as an index key. // More docs can be found in the LengthPrefixedAddressKey function. @@ -221,6 +244,26 @@ func (i intValueCodec) ValueType() string { return Int } +func (i intValueCodec) SchemaCodec() (collcodec.SchemaCodec[math.Int], error) { + return collcodec.SchemaCodec[math.Int]{ + Fields: []schema.Field{{Kind: schema.IntegerKind}}, + ToSchemaType: func(t math.Int) (any, error) { + return t.String(), nil + }, + FromSchemaType: func(s any) (math.Int, error) { + sz, ok := s.(string) + if !ok { + return math.Int{}, fmt.Errorf("expected string, got %T", s) + } + t, ok := math.NewIntFromString(sz) + if !ok { + return math.Int{}, fmt.Errorf("failed to parse Int from string: %s", sz) + } + return t, nil + }, + }, nil +} + type uintValueCodec struct{} func (i uintValueCodec) Encode(value math.Uint) ([]byte, error) {