README ¶
Oracle Module
x/oracle
provides a way to receive external information(real world price, events from other chains, etc.) with validators' vote. Each validator make transaction which contains those informations, and Oracle aggregates them until the supermajority signed on it. After then, Oracle sends the information to the actual module that processes the information, and prune the votes from the state.
Integration
See x/oracle/oracle_test.go
for the code that using Oracle
To use Oracle in your module, first define a payload
. It should implement oracle.Payload
and contain nessesary information for your module. Including nonce is recommended.
type MyPayload struct {
Data int
Nonce int
}
When you write a payload, its .Type()
should return same name with your module is registered on the router. It is because oracle.Msg
inherits .Type()
from its embedded payload and it should be handled on the user modules.
Then route every incoming oracle.Msg
to oracle.Keeper.Handler()
with the function that implements oracle.Handler
.
func NewHandler(keeper Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
switch msg := msg.(type) {
case oracle.Msg:
return keeper.oracle.Handle(ctx sdk.Context, p oracle.Payload) sdk.Error {
switch p := p.(type) {
case MyPayload:
return handleMyPayload(ctx, keeper, p)
}
}
}
}
}
In the previous example, the keeper has an oracle.Keeper
. oracle.Keeper
s are generated by NewKeeper
.
func NewKeeper(key sdk.StoreKey, cdc *wire.Codec, valset sdk.ValidatorSet, supermaj sdk.Rat, timeout int64) Keeper {
return Keeper {
cdc: cdc,
key: key,
// ValidatorSet to get validators infor
valset: valset,
// The keeper will pass payload
// when more than 2/3 signed on it
supermaj: supermaj,
// The keeper will prune votes after 100 blocks from last sign
timeout: timeout,
}
}
Now the validators can send oracle.Msg
s with MyPayload
when they want to witness external events.
Documentation ¶
Index ¶
- Constants
- func ErrAlreadyProcessed(codespace sdk.CodespaceType) sdk.Error
- func ErrAlreadySigned(codespace sdk.CodespaceType) sdk.Error
- func ErrNotValidator(codespace sdk.CodespaceType, address sdk.AccAddress) sdk.Error
- func GetInfoKey(p Payload, cdc *wire.Codec) []byte
- func GetSignKey(p Payload, signer sdk.AccAddress, cdc *wire.Codec) []byte
- func GetSignPrefix(p Payload, cdc *wire.Codec) []byte
- type Handler
- type Info
- type InfoStatus
- type Keeper
- type Msg
- type Payload
Constants ¶
const ( CodeNotValidator sdk.CodeType = 1101 CodeAlreadyProcessed sdk.CodeType = 1102 CodeAlreadySigned sdk.CodeType = 1103 CodeUnknownRequest sdk.CodeType = sdk.CodeUnknownRequest )
Oracle errors reserve 1101-1199
const ( Pending = InfoStatus(iota) Processed Timeout )
Define InfoStatus
Variables ¶
This section is empty.
Functions ¶
func ErrAlreadyProcessed ¶
func ErrAlreadyProcessed(codespace sdk.CodespaceType) sdk.Error
ErrAlreadyProcessed called when a payload is already processed
func ErrAlreadySigned ¶
func ErrAlreadySigned(codespace sdk.CodespaceType) sdk.Error
ErrAlreadySigned called when the signer is trying to double signing
func ErrNotValidator ¶
func ErrNotValidator(codespace sdk.CodespaceType, address sdk.AccAddress) sdk.Error
ErrNotValidator called when the signer of a Msg is not a validator
func GetInfoKey ¶
GetInfoKey returns the key for OracleInfo
func GetSignKey ¶
GetSignKey returns the key for sign
Types ¶
type Info ¶
type Info struct { Power sdk.Rat Hash []byte LastSigned int64 Status InfoStatus }
Info for each payload
type Keeper ¶
type Keeper struct {
// contains filtered or unexported fields
}
Keeper of the oracle store
func NewKeeper ¶
func NewKeeper(key sdk.KVStoreGetter, cdc *wire.Codec, valset sdk.ValidatorSet, supermaj sdk.Rat, timeout int64) Keeper
NewKeeper constructs a new keeper