icaoracle

package
v13.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2023 License: Apache-2.0 Imports: 21 Imported by: 0

README


title: "ICA Oracle" excerpt: "" category: 6392913957c533007128548e

ICA Oracle Module

Overview

The icaoracle facilities trustless data publication to cosmwasm outposts on adjacent chains. The full ICA Oracle solution consists of two components: the icaoracle module deployed on the source chain (described here), as well as a corresponding cosmwasm oracle contract deployed on the destination chain. The contract features a standard key-value store, that accepts push messages from this module via interchain accounts. The data sent is referred to as a Metric. For Stride, the primary application of this module is to enable integrations to trustlessly retrieve the redemption rate (internal exchange rate) of stTokens.

Some key features of this module are:

  • Trustless: The solution uses interchain accounts which allows the data to be transmitted and retrieved with the same trust properties as IBC
  • Easy adoption to other chains: Since the destination chain's oracle is deployed as a contract, it can be easily added to any chain with cosmwasm. There is no need for those chains to upgrade.
  • Generic key-value store: While the immediate use case of this module is for the redemption rate, the oracle uses a generic key-value format that should work with any metric
  • High throughput/low latency: ICAs are triggered as soon as possible, which eliminates a hop compared to interchain queries
  • Support for multiple oracles: Each metric can be simultaneously pushed to multiple CW outposts

Setup

Before data can be transmitted, there are a few setup steps required:

  1. The contract must be stored on the cosmwasm chain (destination chain)
  2. A connection must exist between the source and destination chain
  3. The oracle must be added to the source chain using the add-oracle transaction. This transaction will begin the registration on the source chain and create an interchain account on the destination chain. The interchain account will be responsible for instantiating the contract and posting metrics.
  4. After the oracle is added, the instantiate-oracle transaction must be submitted which will submit an interchain account message (MsgInstantiateContract) to instantiate the oracle contract with the interchain account's address as the contract admin.

Pushing Metrics

After an oracle is registered, metrics can be posted on-chain using the QueueMetricUpdate function. This will queue the data so that it can be pushed to each registered oracle. In the EndBlocker after the metric is queued, an interchain account message (MsgExecuteContract{MsgPostMetric}) will be submitted to post the value to the oracle.

Diagrams

Setup

alt text

Pushing Metrics

alt text

Metric Status

alt text

Implementation

State

Oracle
  ChainId string
  ConnectionId string
  ChannelId string
  PortId string
  ICAAddress string
  ContractAddress string
  Active bool

Metric
  Key string
  Value string
  MetricType string
  UpdateTime int64 
  BlockHeight int64 
  Attributes string
  DestinationOracle string
  Status (enum: QUEUED/IN_PROGRESS)

Keeper functions

Oracles
// Stores/updates an oracle object in the store
func SetOracle(oracle types.Oracle) 

// Grabs and returns an oracle object from the store using the chain-id
func GetOracle(chainId string) (oracle types.Oracle, found bool) 

// Returns all oracles
func GetAllOracles() []types.Oracle 

// Removes an oracle from the store
func RemoveOracle(chainId string) 

// Toggle whether an oracle is active
func ToggleOracle(chainId string, active bool) error 

// Grab's an oracle from it's connectionId
func GetOracleFromConnectionId(connectionId string) (oracle types.Oracle, found bool) 

// Checks if the oracle ICA channel is open
func IsOracleICAChannelOpen(oracle types.Oracle) bool 
Metrics
// Stores a metric in the main metric store and then either
// adds the metric to the queue or removes it from the queue
// depending on the status of the metric
func SetMetric(metric types.Metric) 

// Gets a specifc metric from the store
func GetMetric(metricId string) (metric types.Metric, found bool) 

// Returns all metrics from the store
func GetAllMetrics() (metrics []types.Metric) 

// Removes a metric from the store
func RemoveMetric(metricId string) 

// Updates the status of a metric which will consequently move it either
// in or out of the queue
func UpdateMetricStatus(, metric types.Metric, status types.MetricStatus) 

// Adds a metric to the queue, which acts as an index for all metrics
// that should be submitted to it's relevant oracle
func addMetricToQueue(metricKey []byte)

// Removes a metric from the queue
func removeMetricFromQueue(, metricKey []byte) 

// Returns all metrics from the index queue
func GetAllQueuedMetrics() (metrics []types.Metric) 

Transactions

// Adds a new oracle
AddOracle(connectionId string)

// Instantiates the oracle's CW contract
InstantiateOracle(oracleChainId string, contractCodeId uint64)

// Restore's a closed ICA channel for a given oracle
RestoreOracleICA(oracleChainId string)

// Toggle's whether an oracle is active and should receive metric updates
ToggleOracle(oracleChainId string, active bool) [Governance]

// Removes an oracle completely
RemoveOracle(oracleChainId string) [Governance]

Queries

// Query a specific oracle
//   /Stride-Labs/stride/icaoracle/oracle/{chain_id}
Oracle(oracleChainId string)

// Query all oracles
//   /Stride-Labs/stride/icaoracle/oracles
AllOracles()

// Query metrics with optional filters
//
// Ex:
// - /Stride-Labs/stride/icaoracle/metrics
// - /Stride-Labs/stride/icaoracle/metrics?metric_key=X
// - /Stride-Labs/stride/icaoracle/metrics?oracle_chain_id=Y
Metrics(metricKey, oracleChainId string)

Business Logic

// Queues an metric update across each active oracle
// One metric record is created for each oracle, in status QUEUED
// This is called by the modules that want to publish metrics
func QueueMetricUpdate(key, value, metricType, attributes string) 

// For each queued metric, submit an ICA to each oracle, and then flag the metric as IN_PROGRESS
// This is called each block in the EndBlocker
func PostAllQueuedMetrics() 

ICA Callbacks

// Callback after an oracle is instantiated
func InstantiateOracleCallback()

// Callback after a metric is published
func UpdateOracleCallback()

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppModule

type AppModule struct {
	AppModuleBasic
	// contains filtered or unexported fields
}

AppModule implements the AppModule interface for the capability module.

func NewAppModule

func NewAppModule(
	cdc codec.Codec,
	keeper keeper.Keeper,
) AppModule

func (AppModule) BeginBlock

func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock)

BeginBlock executes all ABCI BeginBlock logic respective to the capability module.

func (AppModule) ConsensusVersion

func (AppModule) ConsensusVersion() uint64

ConsensusVersion implements ConsensusVersion.

func (AppModule) EndBlock

EndBlock executes all ABCI EndBlock logic respective to the capability module. It returns no validator updates.

func (AppModule) ExportGenesis

func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage

ExportGenesis returns the capability module's exported genesis state as raw JSON bytes.

func (AppModule) InitGenesis

func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate

InitGenesis performs the capability module's genesis initialization It returns no validator updates.

func (AppModule) Name

func (am AppModule) Name() string

Name returns the capability module's name.

func (AppModule) RegisterInvariants

func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry)

RegisterInvariants registers the capability module's invariants.

func (AppModule) RegisterServices

func (am AppModule) RegisterServices(cfg module.Configurator)

RegisterServices registers a GRPC query service to respond to the module-specific GRPC queries.

type AppModuleBasic

type AppModuleBasic struct {
	// contains filtered or unexported fields
}

AppModuleBasic implements the AppModuleBasic interface for the capability module.

func NewAppModuleBasic

func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic

func (AppModuleBasic) DefaultGenesis

func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage

DefaultGenesis returns the capability module's default genesis state.

func (AppModuleBasic) GetQueryCmd

func (AppModuleBasic) GetQueryCmd() *cobra.Command

GetQueryCmd returns the capability module's root query command.

func (AppModuleBasic) GetTxCmd

func (a AppModuleBasic) GetTxCmd() *cobra.Command

GetTxCmd returns the capability module's root tx command.

func (AppModuleBasic) Name

func (AppModuleBasic) Name() string

Name returns the capability module's name.

func (AppModuleBasic) RegisterGRPCGatewayRoutes

func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux)

RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module.

func (AppModuleBasic) RegisterInterfaces

func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry)

RegisterInterfaces registers the module's interface types

func (AppModuleBasic) RegisterLegacyAminoCodec

func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)

func (AppModuleBasic) RegisterRESTRoutes

func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router)

RegisterRESTRoutes registers the capability module's REST service handlers.

func (AppModuleBasic) ValidateGenesis

func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error

ValidateGenesis performs genesis state validation for the capability module.

type IBCMiddleware

type IBCMiddleware struct {
	// contains filtered or unexported fields
}

func NewIBCMiddleware

func NewIBCMiddleware(app porttypes.IBCModule, k keeper.Keeper) IBCMiddleware

NewIBCMiddleware creates a new IBCMiddleware given the keeper

func (IBCMiddleware) GetAppVersion

func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool)

GetAppVersion implements the ICS4 Wrapper interface but is not utilized in the bottom of ICA stack

func (IBCMiddleware) OnAcknowledgementPacket

func (im IBCMiddleware) OnAcknowledgementPacket(
	ctx sdk.Context,
	packet channeltypes.Packet,
	acknowledgement []byte,
	relayer sdk.AccAddress,
) error

OnAcknowledgementPacket simply passes down the to next middleware stack The Ack handling and routing is managed by icacallbacks

func (IBCMiddleware) OnChanCloseConfirm

func (im IBCMiddleware) OnChanCloseConfirm(
	ctx sdk.Context,
	portID,
	channelID string,
) error

OnChanCloseConfirm simply passes down the to next middleware stack

func (IBCMiddleware) OnChanCloseInit

func (im IBCMiddleware) OnChanCloseInit(
	ctx sdk.Context,
	portID,
	channelID string,
) error

OnChanCloseInit simply passes down the to next middleware stack

func (IBCMiddleware) OnChanOpenAck

func (im IBCMiddleware) OnChanOpenAck(
	ctx sdk.Context,
	portID string,
	channelID string,
	counterpartyChannelID string,
	counterpartyVersion string,
) error

OnChanOpenAck implements the IBCMiddleware interface

func (IBCMiddleware) OnChanOpenConfirm

func (im IBCMiddleware) OnChanOpenConfirm(
	ctx sdk.Context,
	portID,
	channelID string,
) error

OnChanOpenConfirm simply passes down the to next middleware stack

func (IBCMiddleware) OnChanOpenInit

func (im IBCMiddleware) OnChanOpenInit(
	ctx sdk.Context,
	order channeltypes.Order,
	connectionHops []string,
	portID string,
	channelID string,
	channelCap *capabilitytypes.Capability,
	counterparty channeltypes.Counterparty,
	version string,
) (string, error)

OnChanOpenInit implements the IBCMiddleware interface

func (IBCMiddleware) OnChanOpenTry

func (im IBCMiddleware) OnChanOpenTry(
	ctx sdk.Context,
	order channeltypes.Order,
	connectionHops []string,
	portID,
	channelID string,
	chanCap *capabilitytypes.Capability,
	counterparty channeltypes.Counterparty,
	counterpartyVersion string,
) (string, error)

OnChanOpenTry simply passes down the to next middleware stack

func (IBCMiddleware) OnRecvPacket

func (im IBCMiddleware) OnRecvPacket(
	ctx sdk.Context,
	packet channeltypes.Packet,
	relayer sdk.AccAddress,
) ibcexported.Acknowledgement

OnRecvPacket simply passes down the to next middleware stack

func (IBCMiddleware) OnTimeoutPacket

func (im IBCMiddleware) OnTimeoutPacket(
	ctx sdk.Context,
	packet channeltypes.Packet,
	relayer sdk.AccAddress,
) error

OnTimeoutPacket simply passes down the to next middleware stack The Ack handling and routing is managed by icacallbacks

func (IBCMiddleware) SendPacket

func (im IBCMiddleware) SendPacket(
	ctx sdk.Context,
	chanCap *capabilitytypes.Capability,
	sourcePort string,
	sourceChannel string,
	timeoutHeight clienttypes.Height,
	timeoutTimestamp uint64,
	data []byte,
) (sequence uint64, err error)

SendPacket implements the ICS4 Wrapper interface but is not utilized in the ICA stack

func (IBCMiddleware) WriteAcknowledgement

func (im IBCMiddleware) WriteAcknowledgement(
	ctx sdk.Context,
	chanCap *capabilitytypes.Capability,
	packet ibcexported.PacketI,
	ack ibcexported.Acknowledgement,
) error

WriteAcknowledgement implements the ICS4 Wrapper interface but is not utilized in the bottom of ICA stack

Directories

Path Synopsis
client
cli
Package types is a reverse proxy.
Package types is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL