Skip to content

Commit

Permalink
refactor(indexer/base): move to cosmossdk.io/schema (#20744)
Browse files Browse the repository at this point in the history
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
aaronc and coderabbitai[bot] authored Jun 26, 2024
1 parent ad52b41 commit 38c1d6a
Show file tree
Hide file tree
Showing 24 changed files with 76 additions and 62 deletions.
32 changes: 0 additions & 32 deletions indexer/base/README.md

This file was deleted.

Empty file removed indexer/base/go.sum
Empty file.
File renamed without changes.
13 changes: 13 additions & 0 deletions schema/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Logical State Schema Framework

The `cosmossdk.io/schema` base module is designed to provide a stable, **zero-dependency** base layer for specifying the **logical representation of module state schemas** and implementing **state indexing**. This is intended to be used primarily for indexing modules in external databases and providing a standard human-readable state representation for genesis import and export.

The schema defined in this library does not aim to be general purpose and cover all types of schemas, such as those used for defining transactions. For instance, this schema does not include many types of composite objects such as nested objects and arrays. Rather, the schema defined here aims to cover _state_ schemas only which are implemented as key-value pairs and usually have direct mappings to relational database tables or objects in a document store.

Also, this schema does not cover physical state layout and byte-level encoding, but simply describes a common logical format.

## `HasModuleCodec` Interface

Any module which supports logical decoding and/or encoding should implement the `HasModuleCodec` interface. This interface provides a way to get the codec for the module, which can be used to decode the module's state and/or apply logical updates.

State frameworks such as `collections` or `orm` should directly provide `ModuleCodec` implementations so that this functionality basically comes for free if a compatible framework is used. Modules that do not use one of these frameworks can choose to manually implement logical decoding and/or encoding.
32 changes: 32 additions & 0 deletions schema/appdata/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# App Data

The `appdata` package defines the basic types for streaming blockchain event and state data to external listeners, with a specific focus on supporting logical decoding and indexing of state.

A blockchain data source should accept a `Listener` instance and invoke the provided callbacks in the correct order. A downstream listener should provide a `Listener` instance and perform operations based on the data passed to its callbacks.

## `Listener` Callback Order

`Listener` callbacks should be called in this order

```mermaid
sequenceDiagram
actor Source
actor Target
Source ->> Target: Initialize
Source -->> Target: InitializeModuleSchema
loop Block
Source ->> Target: StartBlock
Source ->> Target: OnBlockHeader
Source -->> Target: OnTx
Source -->> Target: OnEvent
Source -->> Target: OnKVPair
Source -->> Target: OnObjectUpdate
Source ->> Target: Commit
end
```

`Initialize` must be called before any other method and should only be invoked once. `InitializeModuleSchema` should be called at most once for every module with logical data.

Sources will generally only call `InitializeModuleSchema` and `OnObjectUpdate` if they have native logical decoding capabilities. Usually, the indexer framework will provide this functionality based on `OnKVPair` data and `schema.HasModuleCodec` implementations.

`StartBlock` and `OnBlockHeader` should be called only once at the beginning of a block, and `Commit` should be called only once at the end of a block. The `OnTx`, `OnEvent`, `OnKVPair` and `OnObjectUpdate` must be called after `OnBlockHeader`, may be called multiple times within a block and indexers should not assume that the order is logical unless `InitializationData.HasEventAlignedWrites` is true.
8 changes: 5 additions & 3 deletions indexer/base/listener.go → schema/appdata/listener.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package indexerbase
package appdata

import (
"encoding/json"

"cosmossdk.io/schema"
)

// Listener is an interface that defines methods for listening to both raw and logical blockchain data.
Expand Down Expand Up @@ -45,12 +47,12 @@ type Listener struct {
// migrations) required to receive OnObjectUpdate events for the given module. If the
// indexer's schema is incompatible with the module's on-chain schema, the listener should return
// an error. Module names must conform to the NameFormat regular expression.
InitializeModuleSchema func(module string, schema ModuleSchema) error
InitializeModuleSchema func(moduleName string, moduleSchema schema.ModuleSchema) error

// OnObjectUpdate is called whenever an object is updated in a module's state. This is only called
// when logical data is available. It should be assumed that the same data in raw form
// is also passed to OnKVPair. Module names must conform to the NameFormat regular expression.
OnObjectUpdate func(module string, update ObjectUpdate) error
OnObjectUpdate func(moduleName string, update schema.ObjectUpdate) error
}

// InitializationData represents initialization data that is passed to a listener.
Expand Down
19 changes: 9 additions & 10 deletions indexer/base/decoder.go → schema/decoder.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
package indexerbase
package schema

// DecodableModule is an interface that modules can implement to provide a ModuleDecoder.
// HasModuleCodec is an interface that modules can implement to provide a ModuleCodec.
// Usually these modules would also implement appmodule.AppModule, but that is not included
// to keep this package free of any dependencies.
type DecodableModule interface {
// ModuleDecoder returns a ModuleDecoder for the module.
ModuleDecoder() (ModuleDecoder, error)
type HasModuleCodec interface {
// ModuleCodec returns a ModuleCodec for the module.
ModuleCodec() (ModuleCodec, error)
}

// ModuleDecoder is a struct that contains the schema and a KVDecoder for a module.
type ModuleDecoder struct {
// Schema is the schema for the module.
// ModuleCodec is a struct that contains the schema and a KVDecoder for a module.
type ModuleCodec struct {
// Schema is the schema for the module. It is required.
Schema ModuleSchema

// KVDecoder is a function that decodes a key-value pair into an ObjectUpdate.
// If modules pass logical updates directly to the engine and don't require logical decoding of raw bytes,
// then this function should be nil.
// If it is nil, the module doesn't support state decoding directly.
KVDecoder KVDecoder
}

Expand Down
2 changes: 1 addition & 1 deletion indexer/base/enum.go → schema/enum.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "fmt"

Expand Down
2 changes: 1 addition & 1 deletion indexer/base/enum_test.go → schema/enum_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import (
"strings"
Expand Down
2 changes: 1 addition & 1 deletion indexer/base/field.go → schema/field.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "fmt"

Expand Down
2 changes: 1 addition & 1 deletion indexer/base/field_test.go → schema/field_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import (
"strings"
Expand Down
2 changes: 1 addition & 1 deletion indexer/base/fields.go → schema/fields.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "fmt"

Expand Down
2 changes: 1 addition & 1 deletion indexer/base/fields_test.go → schema/fields_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import (
"strings"
Expand Down
2 changes: 1 addition & 1 deletion indexer/base/go.mod → schema/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module cosmossdk.io/indexer/base
module cosmossdk.io/schema

// NOTE: this go.mod should have zero dependencies and remain on go 1.12 to stay compatible
// with all known production releases of the Cosmos SDK. This is to ensure that all historical
Expand Down
2 changes: 1 addition & 1 deletion indexer/base/kind.go → schema/kind.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import (
"encoding/json"
Expand Down
2 changes: 1 addition & 1 deletion indexer/base/kind_test.go → schema/kind_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import (
"encoding/json"
Expand Down
2 changes: 1 addition & 1 deletion indexer/base/module_schema.go → schema/module_schema.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "fmt"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import (
"strings"
Expand Down
2 changes: 1 addition & 1 deletion indexer/base/name.go → schema/name.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "regexp"

Expand Down
2 changes: 1 addition & 1 deletion indexer/base/name_test.go → schema/name_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "testing"

Expand Down
2 changes: 1 addition & 1 deletion indexer/base/object_type.go → schema/object_type.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "fmt"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import (
"strings"
Expand Down
2 changes: 1 addition & 1 deletion indexer/base/object_update.go → schema/object_update.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "sort"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indexerbase
package schema

import "testing"

Expand Down

0 comments on commit 38c1d6a

Please sign in to comment.