cosmos-sdk/schema/api.go
Aaron Craelius 73ee336359
feat(schema): add API descriptors, struct, oneof & list types, and wire encoding spec (#21482)
Co-authored-by: marbar3778 <marbar3778@yahoo.com>
Co-authored-by: Marko <marko@baricevic.me>
2024-10-01 07:40:42 +00:00

99 lines
4.7 KiB
Go

package schema
// APIDescriptor is a public versioned descriptor of an API.
//
// An APIDescriptor can be used as a native descriptor of an API's encoding.
// The native binary encoding of API requests and responses is to encode the input and output
// fields using value binary encoding.
// The native JSON encoding would be to encode the fields as a JSON object, canonically
// sorted by field name with no extra whitespace.
// Thus, APIDefinitions have deterministic binary and JSON encodings.
//
// APIDefinitions have a strong definition of compatibility between different versions
// of the same API.
// It is an INCOMPATIBLE change to add new input fields to existing methods or to remove or modify
// existing input or output fields.
// Input fields also cannot reference any unsealed structs, directly or transitively,
// because these types allow adding new fields.
// Adding new input fields to a method introduces the possibility that a newer client
// will send an incomprehensible message to an older server.
// The only safe ways that input field schemas can be extended are by adding
// new values to EnumType's and new cases to OneOfType's.
// It is a COMPATIBLE change to add new methods to an API and to add new output fields
// to existing methods.
// Output fields can reference any sealed or unsealed StructType, directly or transitively.
//
// Existing protobuf APIs could also be mapped into APIDefinitions, and used in the following ways:
// - to produce, user-friendly deterministic JSON
// - to produce a deterministic binary encoding
// - to check for compatibility in a way that is more appropriate to blockchain applications
// - to use any code generators designed to support this spec as an alternative to protobuf
// Also, a standardized way of serializing schema types as protobuf could be defined which
// maps to the original protobuf encoding, so that schemas can be used as an interop
// layer between different less expressive encoding systems.
//
// Existing EVM contract APIs expressed in Solidity could be mapped into APIDefinitions, and
// a mapping of all schema values to ABI encoding could be defined which preserves the
// original ABI encoding.
//
// In this way, we can define an interop layer between contracts in the EVM world,
// SDK modules accepting protobuf types, and any API using this schema system natively.
type APIDescriptor struct {
// Name is the versioned name of the API.
Name string
// Methods is the list of methods in the API.
// It is a COMPATIBLE change to add new methods to an API.
// If a newer client tries to call a method that an older server does not recognize it,
// an error will simply be returned.
Methods []MethodDescriptor
}
// MethodDescriptor describes a method in the API.
type MethodDescriptor struct {
// Name is the name of the method.
Name string
// InputFields is the list of input fields for the method.
//
// It is an INCOMPATIBLE change to add, remove or update input fields to a method.
// The addition of new fields introduces the possibility that a newer client
// will send an incomprehensible message to an older server.
// InputFields can only reference sealed StructTypes, either directly and transitively.
//
// As a special case to represent protobuf service definitions, there can be a single
// unnamed struct input field that code generators can choose to either reference
// as a named struct or to expand inline as function arguments.
InputFields []Field
// OutputFields is the list of output fields for the method.
//
// It is a COMPATIBLE change to add new output fields to a method,
// but existing output fields should not be removed or modified.
// OutputFields can reference any sealed or unsealed StructType, directly or transitively.
// If a newer client tries to call a method on an older server, the newer expected result output
// fields will simply be populated with the default values for that field kind.
//
// As a special case to represent protobuf service definitions, there can be a single
// unnamed struct output field.
// In this case, adding new output fields is an INCOMPATIBLE change (because protobuf service definitions
// don't allow this), but new fields can be added to the referenced struct if it is unsealed.
OutputFields []Field
// Volatility is the volatility of the method.
Volatility Volatility
}
// Volatility is the volatility of a method.
type Volatility int
const (
// PureVolatility indicates that the method can neither read nor write state.
PureVolatility Volatility = iota
// ReadonlyVolatility indicates that the method can read state but not write state.
ReadonlyVolatility
// VolatileVolatility indicates that the method can read and write state.
VolatileVolatility
)