8000 feat(module): bandchain oracle support by Pantani · Pull Request #1343 · ignite/cli · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

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 48 commits into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
f4f7ecc
oracle template files
Pantani Jul 7, 2021
f3dd2f2
add placeholders and missing templates
Pantani Jul 7, 2021
ebdcfc9
add module placeholders
Pantani Jul 7, 2021
af19d3f
add oracle placeholder and code chunk
Pantani Jul 7, 2021
8c354c1
remove unused scaffold data and import as a module
Pantani Jul 8, 2021
d0ffa3a
remove obi package
Pantani Jul 8, 2021
ae87155
fix folder unbox
Pantani Jul 8, 2021
0c2c15c
fix scaffold issues
Pantani Jul 9, 2021
8e57bde
force ibc module if the oracle is enable
Pantani Jul 9, 2021
9b56c77
add oracle integration test
Pantani Jul 9, 2021
a5cc866
create band cli command
Pantani Jul 9, 2021
7a5ac92
fix template name
Pantani Jul 9, 2021
34a09a9
add custom oracle name
Pantani Jul 9, 2021
11dcb31
add dev TODO flags
Pantani Jul 9, 2021
159f420
add comments to the templates
Pantani Jul 9, 2021
4e5e52e
fix integration tests
Pantani Jul 9, 2021
3fe7abb
fix oracle packet handler
Pantani Jul 10, 2021
42a9219
fix placeholders
Pantani Jul 10, 2021
9b15f10
fix lint
Pantani Jul 10, 2021
8910cca
integration tests
Pantani Jul 10, 2021
9f7f3a3
fix multiple oracle conflicts
Pantani Jul 10, 2021
6fd2447
fix integration
Pantani Jul 10, 2021
119f613
solve kepper keys conflicts
Pantani Jul 10, 2021
aaa77d2
fix integration tests
Pantani Jul 10, 2021
25e7a16
add more tests
Pantani Jul 10, 2021
b791dcd
fix Wrapf call has arguments but no formatting directives
Pantani Jul 11, 2021
9ad96b2
fix oracle handler parser
Pantani Jul 11, 2021
22634af
add Bandchain oracle doc
Pantani Jul 11, 2021
f27c5c6
improve docs
Pantani Jul 12, 2021
7b44dc1
fix doc links
Pantani Jul 12, 2021
e7461db
docs: fix relayer target-version
Pantani Jul 12, 2021
c022264
fix templates name and PR discussions
Pantani Jul 12, 2021
c26f5e2
move template names
Pantani Jul 12, 2021
cd2cc45
fix gofmt
Pantani Jul 12, 2021
efa8dbb
improve cli description
Pantani Jul 12, 2021
89773ea
fix cli command
Pantani Jul 12, 2021
bb5abba
improve/fix docs
Pantani Jul 12, 2021
1ddd63c
update docs and comments
Pantani Jul 12, 2021
79c0d6c
feat(cmd/relayer): upgrade confio/relayer and add gaslimit opt (#1359)
ilgooz Jul 13, 2021
c6b7db2
Merge branch 'develop' into feat/bandchain-oracle-support
ilgooz Jul 13, 2021
b0912e6
update docs and comments
Pantani Jul 13, 2021
3143653
fix oracle complete log
Pantani Jul 13, 2021
2345b24
fix multiple bandchain oracles conflicts adding the client id parameter
Pantani Jul 13, 2021
dd76107
fix oracle parser error
Pantani Jul 13, 2021
0c1e787
fix BandChain name case
Pantani Jul 13, 2021
04cf78d
fix error no module description
Pantani Jul 14, 2021
f13f393
Set client update gas limit to 600000
lumtis Jul 15, 2021
56c7db9
Merge branch 'develop' into feat/bandchain-oracle-support
lumtis Jul 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 248 additions & 0 deletions docs/scaffold/band.md
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
```
62 changes: 62 additions & 0 deletions integration/cmd_ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,68 @@ func TestCreateModuleWithIBC(t *testing.T) {
env.EnsureAppIsSteady(path)
}

func TestCreateIBCOracle(t *testing.T) {

var (
env = newEnv(t)
path = env.Scaffold("ibcoracle")
)

env.Must(env.Exec("create an IBC module",
step.NewSteps(step.New(
step.Exec("starport", "s", "module", "foo", "--ibc", "--require-registration"),
step.Workdir(path),
)),
))

env.Must(env.Exec("create the first BandChain oracle integration",
step.NewSteps(step.New(
step.Exec("starport", "s", "band", "oracleone", "--module", "foo"),
step.Workdir(path),
)),
))

env.Must(env.Exec("create the second BandChain oracle integration",
step.NewSteps(step.New(
step.Exec("starport", "s", "band", "oracletwo", "--module", "foo"),
step.Workdir(path),
)),
))

env.Must(env.Exec("should prevent creating a BandChain oracle with no module specified",
step.NewSteps(step.New(
step.Exec("starport", "s", "band", "invalidOracle"),
step.Workdir(path),
)),
ExecShouldError(),
))

env.Must(env.Exec("should prevent creating a BandChain oracle in a non existent module",
step.NewSteps(step.New(
step.Exec("starport", "s", "band", "invalidOracle", "--module", "nomodule"),
step.Workdir(path),
)),
ExecShouldError(),
))

env.Must(env.Exec("create a non-IBC module",
step.NewSteps(step.New(
step.Exec("starport", "s", "module", "bar", "--require-registration"),
step.Workdir(path),
)),
))

env.Must(env.Exec("should prevent creating a BandChain oracle in a non IBC module",
step.NewSteps(step.New(
step.Exec("starport", "s", "band", "invalidOracle", "--module", "bar"),
step.Workdir(path),
)),
ExecShouldError(),
))

env.EnsureAppIsSteady(path)
}

func TestCreateIBCPacket(t *testing.T) {

var (
Expand Down
Loading
0