-
Notifications
You must be signed in to change notification settings - Fork 52
/
oracle.go
110 lines (96 loc) · 3.81 KB
/
oracle.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package oracle
import (
errorsmod "cosmossdk.io/errors"
"github.com/bandprotocol/bandchain-packet/obi"
"github.com/bandprotocol/bandchain-packet/packet"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
"github.com/elys-network/elys/x/oracle/types"
)
// handleOraclePacket handles the result of the received BandChain oracles
// packet and saves the data into the KV database
func (im IBCModule) handleOraclePacket(
ctx sdk.Context,
modulePacket channeltypes.Packet,
) (channeltypes.Acknowledgement, error) {
var ack channeltypes.Acknowledgement
var modulePacketData packet.OracleResponsePacketData
if err := types.ModuleCdc.UnmarshalJSON(modulePacket.GetData(), &modulePacketData); err != nil {
return ack, nil
}
switch modulePacketData.GetClientID() {
case types.BandPriceClientIDKey:
var BandPriceResult types.BandPriceResult
if err := obi.Decode(modulePacketData.Result, &BandPriceResult); err != nil {
ack = channeltypes.NewErrorAcknowledgement(err)
return ack, errorsmod.Wrap(sdkerrors.ErrUnknownRequest, "cannot decode the BandPrice received packet")
}
reqID := types.OracleRequestID(modulePacketData.RequestID)
im.keeper.SetBandPriceResult(ctx, reqID, BandPriceResult)
params := im.keeper.GetParams(ctx)
request, err := im.keeper.GetBandRequest(ctx, reqID)
if err != nil {
return ack, errorsmod.Wrap(sdkerrors.ErrUnknownRequest, "historical request does not exist")
}
if len(request.Symbols) != len(BandPriceResult.Rates) {
return ack, errorsmod.Wrap(sdkerrors.ErrUnknownRequest, "request and result count does not match")
}
for index, symbol := range request.Symbols {
im.keeper.SetPrice(ctx, types.Price{
Asset: symbol,
Price: sdk.NewDecWithPrec(int64(BandPriceResult.Rates[index]), int64(params.Multiplier)),
Source: types.BAND,
Provider: "automation",
Timestamp: uint64(ctx.BlockTime().Unix()),
BlockHeight: uint64(ctx.BlockHeight()),
})
}
default:
err := errorsmod.Wrapf(sdkerrors.ErrJSONUnmarshal, "oracle received packet not found: %s", modulePacketData.GetClientID())
ack = channeltypes.NewErrorAcknowledgement(err)
return ack, err
}
ack = channeltypes.NewResultAcknowledgement(
types.ModuleCdc.MustMarshalJSON(
packet.NewOracleRequestPacketAcknowledgement(modulePacketData.RequestID),
),
)
return ack, nil
}
// handleOracleAcknowledgment handles the acknowledgment result from the BandChain
// request and saves the request-id into the KV database
func (im IBCModule) handleOracleAcknowledgment(
ctx sdk.Context,
ack channeltypes.Acknowledgement,
modulePacket channeltypes.Packet,
) (*sdk.Result, error) {
switch resp := ack.Response.(type) {
case *channeltypes.Acknowledgement_Result:
var oracleAck packet.OracleRequestPacketAcknowledgement
err := types.ModuleCdc.UnmarshalJSON(resp.Result, &oracleAck)
if err != nil {
return nil, nil
}
var data packet.OracleRequestPacketData
if err = types.ModuleCdc.UnmarshalJSON(modulePacket.GetData(), &data); err != nil {
return nil, nil
}
requestID := types.OracleRequestID(oracleAck.RequestID)
switch data.GetClientID() {
case types.BandPriceClientIDKey:
var RequestBandPrice types.BandPriceCallData
if err = obi.Decode(data.GetCalldata(), &RequestBandPrice); err != nil {
return nil, errorsmod.Wrap(err, "cannot decode the BandPrice oracle acknowledgment packet")
}
im.keeper.SetLastBandRequestId(ctx, requestID)
im.keeper.SetBandRequest(ctx, requestID, RequestBandPrice)
return &sdk.Result{}, nil
// this line is used by starport scaffolding # oracle/module/ack
default:
return nil, errorsmod.Wrapf(sdkerrors.ErrJSONUnmarshal,
"oracle acknowledgment packet not found: %s", data.GetClientID())
}
}
return nil, nil
}