-
Notifications
You must be signed in to change notification settings - Fork 564
feat(module): bandchain oracle support #1343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
f4f7ecc
oracle template files
Pantani f3dd2f2
add placeholders and missing templates
Pantani ebdcfc9
add module placeholders
Pantani af19d3f
add oracle placeholder and code chunk
Pantani 8c354c1
remove unused scaffold data and import as a module
Pantani d0ffa3a
remove obi package
Pantani ae87155
fix folder unbox
Pantani 0c2c15c
fix scaffold issues
Pantani 8e57bde
force ibc module if the oracle is enable
Pantani 9b56c77
add oracle integration test
Pantani a5cc866
create band cli command
Pantani 7a5ac92
fix template name
Pantani 34a09a9
add custom oracle name
Pantani 11dcb31
add dev TODO flags
Pantani 159f420
add comments to the templates
Pantani 4e5e52e
fix integration tests
Pantani 3fe7abb
fix oracle packet handler
Pantani 42a9219
fix placeholders
Pantani 9b15f10
fix lint
Pantani 8910cca
integration tests
Pantani 9f7f3a3
fix multiple oracle conflicts
Pantani 6fd2447
fix integration
Pantani 119f613
solve kepper keys conflicts
Pantani aaa77d2
fix integration tests
Pantani 25e7a16
add more tests
Pantani b791dcd
fix Wrapf call has arguments but no formatting directives
Pantani 9ad96b2
fix oracle handler parser
Pantani 22634af
add Bandchain oracle doc
Pantani f27c5c6
improve docs
Pantani 7b44dc1
fix doc links
Pantani e7461db
docs: fix relayer target-version
Pantani c022264
fix templates name and PR discussions
Pantani c26f5e2
move template names
Pantani cd2cc45
fix gofmt
Pantani efa8dbb
improve cli description
Pantani 89773ea
fix cli command
Pantani bb5abba
improve/fix docs
Pantani 1ddd63c
update docs and comments
Pantani 79c0d6c
feat(cmd/relayer): upgrade confio/relayer and add gaslimit opt (#1359)
ilgooz c6b7db2
Merge branch 'develop' into feat/bandchain-oracle-support
ilgooz b0912e6
update docs and comments
Pantani 3143653
fix oracle complete log
Pantani 2345b24
fix multiple bandchain oracles conflicts adding the client id parameter
Pantani dd76107
fix oracle parser error
Pantani 0c1e787
fix BandChain name case
Pantani 04cf78d
fix error no module description
Pantani f13f393
Set client update gas limit to 600000
lumtis 56c7db9
Merge branch 'develop' into feat/bandchain-oracle-support
lumtis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
--- | ||
order: 7 | ||
description: IBC oracle integration with BandChain | ||
--- | ||
|
||
# BandChain Oracle Scaffold | ||
|
||
BandChain’s Oracle module is a communication module built-in compliance with IBC protocol which can query data points of various types from BandChain. In addition, other chains can ask our Oracle module for real-time information according to their needs. | ||
BandChain has multiples scripts deployed into the network, and we can request any data using the script id. | ||
|
||
## IBC Module Packet Scaffold | ||
|
||
BandChain oracle queries can be scaffolded only in IBC modules. | ||
|
||
To scaffold an oracle: | ||
|
||
``` | ||
starport scaffold band [queryName] --module [moduleName] | ||
``` | ||
|
||
### Acknowledgement | ||
|
||
The BandChain oracle will return the ack messages with the request's id, and we save the last request id for future queries. | ||
|
||
## Files and Directories | ||
|
||
When you scaffold a BandChain oracle, the following files and directories are created and modified: | ||
|
||
- `proto`: oracle request and response data. | ||
- `x/module_name/keeper`: IBC hooks, gRPC message server. | ||
- `x/module_name/types`: message types, IBC events. | ||
- `x/module_name/client/cli`: CLI command to broadcast a transaction containing a message with a packet. | ||
- `x/module_name/oracle.go`: BandChain oracle packet handlers. | ||
|
||
## BandChain Oracle Scaffold Example | ||
|
||
The following command scaffolds the IBC-enabled oracle. by default, the starport scaffold oracle for [coin rates](https://laozi-testnet2.cosmoscan.io/oracle-script/37#bridge) request and result. | ||
|
||
```shell | ||
$ starport scaffold chain github.com/test/ibcoracle && cd ibcoracle | ||
$ starport scaffold module consuming --ibc | ||
$ starport s band coinRates --module consuming | ||
``` | ||
|
||
Note: BandChain module uses version "bandchain-1". Make sure to update the `keys.go` file accordingly. | ||
|
||
`x/ibcoracle/types/keys.go` | ||
```go | ||
const Version = "bandchain-1" | ||
``` | ||
|
||
After scaffold and change the data, configure and run the starport relayer. | ||
```shell | ||
$ starport relayer configure -a \ | ||
--source-rpc "http://rpc-laozi-testnet2.bandchain.org:26657" \ | ||
--source-faucet "https://laozi-testnet2.bandchain.org/faucet/request" \ | ||
--source-port "oracle" \ | ||
--source-gasprice "0uband" \ | ||
--source-gaslimit 5000000 \ | ||
--source-prefix "band" \ | ||
--source-version "bandchain-1" \ | ||
--target-rpc "http://localhost:26657" \ | ||
--target-faucet "http://localhost:4500" \ | ||
--target-port "consuming" \ | ||
--target-gasprice "0.0stake" \ | ||
--target-gaslimit 300000 \ | ||
--target-prefix "cosmos" \ | ||
--target-version "bandchain-1" | ||
|
||
$ starport relayer connect | ||
``` | ||
|
||
Make a request transaction, passing the script id. | ||
```shell | ||
# Coin Rates (script 37 into the testnet) | ||
$ ibcoracled tx consuming coin-rates-data 37 4 3 --channel channel-0 --symbols "BTC,ETH,XRP,BCH" --multiplier 1000000 --fee-limit 30uband --request-key "random_string" --prepare-gas 600000 --execute-gas 600000 --from alice --chain-id ibcoracle | ||
``` | ||
|
||
You can check the last reque 5DA8 st id returned by ack. | ||
```shell | ||
$ ibcoracled query consuming last-coin-rates-id | ||
request_id: "101276" | ||
``` | ||
|
||
Furthermore, check the data by request id receive the data packet. | ||
```shell | ||
$ ibcoracled query consuming coin-rates-result 101276 | ||
``` | ||
|
||
### Multiple oracles | ||
|
||
You can scaffold multiples oracles by module. After scaffold, you must change the `Calldata` and `Result` parameters into the proto file `moduleName.proto` and adapt the request into the `cli/client/tx_module_name.go` file. Let's create an example to return the [gold price](https://laozi-testnet2.cosmoscan.io/oracle-script/33#bridge): | ||
|
||
```shell | ||
$ starport s band goldPrice --module consuming | ||
``` | ||
|
||
`proto/gold_price.proto`: | ||
```protobuf | ||
syntax = "proto3"; | ||
package test.ibcoracle.consuming; | ||
|
||
option go_package = "github.com/test/ibcoracle/x/consuming/types"; | ||
|
||
message GoldPriceCallData { | ||
uint64 multiplier = 2; | ||
} | ||
|
||
message GoldPriceResult { | ||
uint64 price = 1; | ||
} | ||
``` | ||
|
||
`x/cli/client/tx_gold_price.go`: | ||
```go | ||
package cli | ||
|
||
import ( | ||
"strconv" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
"github.com/cosmos/cosmos-sdk/client/tx" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/tendermint/test/x/consuming/types" | ||
) | ||
|
||
// CmdRequestGoldPriceData creates and broadcast a GoldPrice request transaction | ||
func CmdRequestGoldPriceData() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "gold-price-data [oracle-script-id] [requested-validator-count] [sufficient-validator-count]", | ||
Short: "Make a new GoldPrice query request via an existing BandChain oracle script", | ||
Args: cobra.ExactArgs(3), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
// retrieve the oracle script id. | ||
int64OracleScriptID, err := strconv.ParseInt(args[0], 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
oracleScriptID := types.OracleScriptID(int64OracleScriptID) | ||
|
||
// retrieve the requested validator count. | ||
askCount, err := strconv.ParseUint(args[1], 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// retrieve the sufficient(minimum) validator count. | ||
minCount, err := strconv.ParseUint(args[2], 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
channel, err := cmd.Flags().GetString(flagChannel) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// retrieve the multiplier for the symbols' price. | ||
multiplier, err := cmd.Flags().GetUint64(flagMultiplier) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
calldata := &types.GoldPriceCallData{ | ||
Multiplier: multiplier, | ||
} | ||
|
||
// retrieve the amount of coins allowed to be paid for oracle request fee from the pool account. | ||
coinStr, err := cmd.Flags().GetString(flagFeeLimit) | ||
if err != nil { | ||
return err | ||
} | ||
feeLimit, err := sdk.ParseCoinsNormalized(coinStr) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// retrieve the request key corresponding to the pool account (used to pay fee) on BandChain. | ||
requestKey, err := cmd.Flags().GetString(flagRequestkey) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// retrieve the amount of gas allowed for the prepare step of the oracle script. | ||
prepareGas, err := cmd.Flags().GetUint64(flagPrepareGas) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// retrieve the amount of gas allowed for the execute step of the oracle script. | ||
executeGas, err := cmd.Flags().GetUint64(flagExecuteGas) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
clientCtx, err := client.GetClientTxContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
msg := types.NewMsgGoldPriceData( | ||
clientCtx.GetFromAddress().String(), | ||
oracleScriptID, | ||
channel, | ||
calldata, | ||
askCount, | ||
minCount, | ||
feeLimit, | ||
requestKey, | ||
prepareGas, | ||
executeGas, | ||
) | ||
if err := msg.ValidateBasic(); err != nil { | ||
return err | ||
} | ||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) | ||
}, | ||
} | ||
|
||
cmd.Flags().String(flagChannel, "", "The channel id") | ||
cmd.MarkFlagRequired(flagChannel) | ||
cmd.Flags().Uint64(flagMultiplier, 1000000, "Multiplier used in calling the oracle script") | ||
cmd.Flags().String(flagFeeLimit, "", "the maximum tokens that will be paid to all data source providers") | ||
cmd.Flags().String(flagRequestkey, "", "Key for generating escrow address") | ||
cmd.Flags().Uint64(flagPrepareGas, 200000, "Prepare gas used in fee counting for prepare request") | ||
cmd.Flags().Uint64(flagExecuteGas, 200000, "Execute gas used in fee counting for execute request") | ||
flags.AddTxFlagsToCmd(cmd) | ||
|
||
return cmd | ||
} | ||
``` | ||
|
||
Make the request transaction. | ||
```shell | ||
# Gold Price (script 33 into the testnet) | ||
$ ibcoracled tx consuming gold-price-data 33 4 3 --channel channel-0 --multiplier 1000000 --fee-limit 30uband --request-key "random_string" --prepare-gas 600000 --execute-gas 600000 --from alice --chain-id ibcoracle | ||
``` | ||
|
||
Check the last request id returned by ack and the package data. | ||
```shell | ||
$ ibcoracled query consuming last-gold-price-id | ||
request_id: "101290" | ||
|
||
$ ibcoracled query consuming gold-price-result 101290 | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.