Skip to content
This repository has been archived by the owner on Nov 13, 2024. It is now read-only.

Commit

Permalink
add execute aireq gas & check report size
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamle2 committed Mar 25, 2021
1 parent f2bb5df commit 2c837d8
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 6 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ oraid start --rpc.laddr tcp://0.0.0.0:26657 --log_level error
oraivisor start --rpc.laddr tcp://0.0.0.0:26657 --log_level error

# start websocket subscribe for processing event log in another terminal
oraid tx websocket subscribe --max-try 10 --from $USER --gas="auto" --gas-adjustment="1.2" --chain-id=Oraichain -y
oraid tx websocket subscribe --max-try 10 --from $USER --gas="auto" --gas-adjustment="1.5" --chain-id=Oraichain -y

# run as a background process
docker-compose exec -d orai ash -c "echo $KEYRING_PASS | oraid tx websocket subscribe --max-try 10 --from $USER --gas="auto" --gas-adjustment="1.2" --chain-id=Oraichain -y"
docker-compose exec -d orai ash -c "echo $KEYRING_PASS | oraid tx websocket subscribe --max-try 10 --from $USER --gas="auto" --gas-adjustment="1.5" --chain-id=Oraichain -y"
```

## Build smart contract and interact with it
Expand Down Expand Up @@ -73,7 +73,7 @@ oraid query wasm contract-state smart orai16at0lzgx3slnqlgvcc7r79056f5wkuczenn09
Run websocket as background process

```bash
echo <passphrase> | oraid tx websocket subscribe --max-try 10 --from $USER --gas="auto" --gas-adjustment="1.2" --chain-id=Oraichain -y
echo <passphrase> | oraid tx websocket subscribe --max-try 10 --from $USER --gas="auto" --gas-adjustment="1.5" --chain-id=Oraichain -y
```

Init smart contracts and create an AI request. To run the script, your current dir must contain the smart-contracts/ directory that already have wasm files built. The directory name with the wasm file should also be consistent. Eg: dir name: classification, then the wasm file is classification.wasm
Expand All @@ -85,7 +85,7 @@ Init smart contracts and create an AI request. To run the script, your current d
Eg: ./scripts/deploy_ai_services.sh classification,cv009 classification_testcase classification_oscript '' '' '{"ai_data_source":["classification","cv009"],"testcase":["classification_testcase"]}' 1 /workspace/oraiwasm 123456789

# open another terminal and run
oraid tx airequest set-aireq oscript_eth "5" "6" 30000orai 1 --from $USER --chain-id Oraichain -y
oraid tx airequest set-aireq oscript_price "5" "6" 30000orai 1 --from $USER --chain-id Oraichain -y

# interact with the AI services
oraid tx airequest set-aireq classification_oscript '{"image":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSfx__RoRYzLDgXDiJxYGxLihJC4zoqV3V0xg&usqp=CAU","model":"inception_v3","name":"test_image"}' "6" 30000orai 1 --from $USER --chain-id Oraichain -y
Expand Down
30 changes: 30 additions & 0 deletions x/websocket/subscribe/gas_prices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package subscribe

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

// MinGasPrices is the struct for querying the minimum gas prices of a node
type MinGasPrices struct {
Price string `json:"minFees"`
}

func getMinGasPrices() (string, error) {
resp, err := http.Get("http://localhost:1317/provider/minfees?OracleScriptName=min_gas_prices&ValNum=0")
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
var minGasPrices MinGasPrices
// collect response from the request
json.Unmarshal(body, &minGasPrices)
fmt.Println("min gas prices: ", minGasPrices.Price)
return minGasPrices.Price, nil
}
20 changes: 19 additions & 1 deletion x/websocket/subscribe/subscriber_airequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,26 @@ func (subscriber *Subscriber) submitReport(msgReport *types.MsgCreateReport) (er
subscriber.log.Error(":exploding_head: Failed to validate basic with error: %s", err.Error())
return err
}

// collect gas prices to create a new report
minGasPrices := subscriber.config.Txf.GasPrices().String()
// if the validator does not specify gas prices then we collect from the api get min gas prices
if minGasPrices == "" {
minGasPrices, err = getMinGasPrices()
if err != nil {
subscriber.log.Error(":exploding_head: Failed to collect the minimum gas prices of your node to create a new report with error: %s", err.Error())
return err
}
// test parsing the gas prices to prevent panic
_, err = sdk.ParseDecCoins(minGasPrices)
if err != nil {
subscriber.log.Error(":exploding_head: Invalid syntax for the minimum gas prices. Expected orai, got error: %s", err.Error())
return err
}
}
txf := subscriber.newTxFactory("websocket")
// add gas prices to pay for the report
txf = txf.WithGasPrices(minGasPrices)
txf = txf.WithGasAdjustment(subscriber.config.Txf.GasAdjustment())
for try := uint64(1); try <= subscriber.config.MaxTry; try++ {
subscriber.log.Info(":e-mail: Try to broadcast report transaction(%d/%d)", try, subscriber.config.MaxTry)
err = tx.BroadcastTx(*subscriber.cliCtx, txf, msgReport)
Expand Down
24 changes: 23 additions & 1 deletion x/websocket/types/tx_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

var (
reporterNameLen = 20000 // 20KB
msgLen = 200000 // 200KB
)

// regex allow only alphabet, numeric and underscore characters
var isStringAlphabetic = regexp.MustCompile(`^[a-zA-Z0-9_]*$`).MatchString

Expand All @@ -19,7 +24,7 @@ func (msg *MsgCreateReport) Type() string { return "create_report" }
// ValidateBasic runs stateless checks on the message
func (msg *MsgCreateReport) ValidateBasic() error {
reporter := msg.GetReporter()
if reporter.GetAddress().Empty() || len(reporter.GetName()) == 0 || !isStringAlphabetic(reporter.GetName()) {
if reporter.GetAddress().Empty() || len(reporter.GetName()) == 0 || !isStringAlphabetic(reporter.GetName()) || len(reporter.GetName()) >= reporterNameLen {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, reporter.String())
} else if len(msg.GetRequestID()) == 0 || reporter.Validator.Empty() {
return sdkerrors.Wrap(ErrMsgReportInvalid, "Request ID / validator address cannot be empty")
Expand All @@ -28,6 +33,23 @@ func (msg *MsgCreateReport) ValidateBasic() error {
} else if msg.GetResultStatus() != ResultSuccess && msg.GetResultStatus() != ResultFailure {
return sdkerrors.Wrap(ErrMsgReportInvalid, "result status of the report is not valid")
} else {
var dsResultSize int
for _, dsResult := range msg.DataSourceResults {
dsResultSize += len(dsResult.Result)
}
var tcResultSize int
for _, tcResult := range msg.TestCaseResults {
for _, dsResult := range tcResult.DataSourceResults {
tcResultSize += len(dsResult.Result)
}
}
aggregatedResultSize := len(msg.AggregatedResult)
requestIdSize := len(msg.RequestID)
finalLen := dsResultSize + tcResultSize + aggregatedResultSize + requestIdSize
if finalLen >= msgLen {
return sdkerrors.Wrap(ErrMsgReportInvalid, "Size of the report should not be larger than 200KB")
}

_, err := sdk.ParseCoinsNormalized(msg.Fees.String())
if err != nil {
return sdkerrors.Wrap(ErrReportFeeTypeInvalid, err.Error())
Expand Down

0 comments on commit 2c837d8

Please sign in to comment.