Skip to content

Commit

Permalink
implement deviation & heartbeat logic
Browse files Browse the repository at this point in the history
  • Loading branch information
adamewozniak committed Sep 30, 2024
1 parent b4639dc commit 9156064
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 59 deletions.
9 changes: 7 additions & 2 deletions proto/ojo/gmp/v1/gmp.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ message Payment {
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];

// deviation is how much the price can deviate from the last updated price before triggering an update.
int64 deviation = 5;
// deviation is a percentage of how much the price can deviate before triggering an update.
// 100 = 100%.
string deviation = 5 [
(gogoproto.moretags) = "yaml:\"deviation\"",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];

// heartbeat is how often the price will be updated in Ojo blocks, regardless of whether the price has deviated or not.
int64 heartbeat = 6;
Expand Down
3 changes: 2 additions & 1 deletion x/gmp/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strconv"
"strings"

"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
Expand Down Expand Up @@ -216,7 +217,7 @@ func GetCmdCreatePayment() *cobra.Command {
return err
}

deviation, err := strconv.ParseInt(args[2], 10, 64)
deviation, err := math.LegacyNewDecFromStr(args[2])
if err != nil {
return err
}
Expand Down
19 changes: 12 additions & 7 deletions x/gmp/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,10 @@ func (k Keeper) ProcessPayment(
gasEstimate, err := k.GasEstimateKeeper.GetGasEstimate(ctx, payment.DestinationChain)
if err != nil {
k.Logger(ctx).With(err).Error("error getting gas estimate. using default gas estimates")
return err
} else {
gasAmount = math.NewInt(gasEstimate.GasEstimate)
}

// estimate gas for the axelar relay
coins := sdk.Coin{
Denom: payment.Token.Denom,
Amount: gasAmount,
Expand All @@ -275,7 +273,7 @@ func (k Keeper) ProcessPayment(
k.Logger(ctx).With(err).Error("error getting relayer address")
return err
}
if payment.Token.Amount.LT(coins.Amount) {
if payment.Token.Amount.LTE(coins.Amount) {
k.Logger(ctx).With(err).Debug("payment amount is less than gas estimate, returning funds and deleting payment")
err := k.BankKeeper.SendCoinsFromModuleToAccount(
ctx,
Expand All @@ -294,14 +292,13 @@ func (k Keeper) ProcessPayment(
authtypes.NewModuleAddress(types.ModuleName).String(),
payment.DestinationChain,
contractAddress,
"0x001",
types.EmptyContract,
coins,
[]string{payment.Denom},
[]byte(""),
[]byte(""),
types.EmptyByteSlice,
types.EmptyByteSlice,
ctx.BlockHeight(),
)

_, err = k.RelayPrice(goCtx, msg)
if err != nil {
k.Logger(ctx).With(err).Error("error relaying price")
Expand All @@ -311,6 +308,14 @@ func (k Keeper) ProcessPayment(

// update payment in the store with the amount paid
payment.Token.Amount = payment.Token.Amount.Sub(coins.Amount)
lastPrice, err := k.oracleKeeper.GetExchangeRate(ctx, payment.Denom)
if err != nil {
k.Logger(ctx).With(err).Error("error getting exchange rate")
return err
}
payment.LastPrice = lastPrice
payment.LastBlock = ctx.BlockHeight()

k.SetPayment(ctx, payment)
k.Logger(ctx).Info("payment updated", "payment", payment)

Expand Down
12 changes: 11 additions & 1 deletion x/gmp/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,17 @@ func (am AppModule) EndBlock(goCtx context.Context) ([]abci.ValidatorUpdate, err
ctx := sdk.UnwrapSDKContext(goCtx)
payments := am.keeper.GetAllPayments(ctx)
for _, payment := range payments {
am.keeper.ProcessPayment(goCtx, payment)
rate, err := am.oracleKeeper.GetExchangeRate(ctx, payment.Denom)
if err != nil {
continue
}
// if the last price has deviated by more than the deviation percentage, trigger an update
if payment.LastPrice.Sub(rate).Abs().GT(payment.Deviation) {
am.keeper.ProcessPayment(goCtx, payment)
} else if payment.LastBlock < ctx.BlockHeight()-payment.Heartbeat {
am.keeper.ProcessPayment(goCtx, payment)
}

}
return []abci.ValidatorUpdate{}, nil
}
Expand Down
111 changes: 66 additions & 45 deletions x/gmp/types/gmp.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions x/gmp/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package types
import (
fmt "fmt"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/ojo-network/ojo/util/checkers"
Expand Down Expand Up @@ -108,7 +109,7 @@ func NewMsgCreatePayment(
destinationChain string,
denom string,
token sdk.Coin,
deviation int64,
deviation math.LegacyDec,
heartbeat int64,
) *MsgCreatePayment {
return &MsgCreatePayment{
Expand Down Expand Up @@ -146,8 +147,9 @@ func (msg MsgCreatePayment) ValidateBasic() error {
if msg.Payment.Token.IsZero() {
return fmt.Errorf("token cannot be zero")
}
if msg.Payment.Deviation <= 0 {
return fmt.Errorf("deviation must be greater than 0")
// deviation must be between 0.5 and 50
if msg.Payment.Deviation.LT(math.LegacyNewDecWithPrec(5, 1)) || msg.Payment.Deviation.GT(math.LegacyNewDec(50)) {
return fmt.Errorf("deviation must be between 0.5 and 50")
}
if msg.Payment.Heartbeat <= 0 {
return fmt.Errorf("heartbeat must be greater than 0")
Expand Down
2 changes: 2 additions & 0 deletions x/gmp/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ var (
DefaultTimeout = int64(1)
DefaultFeeRecipient = "axelar1zl3rxpp70lmte2xr6c4lgske2fyuj3hupcsvcd"
DefaultGasEstimate = int64(1000000)
EmptyByteSlice = []byte{}
EmptyContract = "0x0000000000000000000000000000000000000000"
)

func DefaultParams() Params {
Expand Down

0 comments on commit 9156064

Please sign in to comment.