Skip to content

Commit 7c0e225

Browse files
committed
feat: add asset related messages in oracle module
1 parent 6008db8 commit 7c0e225

File tree

7 files changed

+1605
-72
lines changed

7 files changed

+1605
-72
lines changed

proto/sentinel/oracle/v1/msg.proto

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,43 @@ option go_package = "github.com/sentinel-official/hub/v12/x/oracle/types/v1";
88
option (gogoproto.equal_all) = false;
99
option (gogoproto.goproto_getters_all) = false;
1010

11+
message MsgAddAssetRequest {
12+
string from = 1;
13+
string denom = 2;
14+
int64 decimals = 3;
15+
string base_asset_denom = 4;
16+
string quote_asset_denom = 5;
17+
}
18+
19+
message MsgDeleteAssetRequest {
20+
string from = 1;
21+
string denom = 2;
22+
}
23+
24+
message MsgUpdateAssetRequest {
25+
string from = 1;
26+
string denom = 2;
27+
int64 decimals = 3;
28+
string base_asset_denom = 4;
29+
string quote_asset_denom = 5;
30+
}
31+
1132
message MsgUpdateParamsRequest {
1233
string from = 1;
1334
Params params = 2 [(gogoproto.nullable) = false];
1435
}
1536

37+
message MsgAddAssetResponse {}
38+
39+
message MsgDeleteAssetResponse {}
40+
41+
message MsgUpdateAssetResponse {}
42+
1643
message MsgUpdateParamsResponse {}
1744

1845
service MsgService {
46+
rpc MsgAddAsset(MsgAddAssetRequest) returns (MsgAddAssetResponse);
47+
rpc MsgDeleteAsset(MsgDeleteAssetRequest) returns (MsgDeleteAssetResponse);
48+
rpc MsgUpdateAsset(MsgUpdateAssetRequest) returns (MsgUpdateAssetResponse);
1949
rpc MsgUpdateParams(MsgUpdateParamsRequest) returns (MsgUpdateParamsResponse);
2050
}

x/oracle/keeper/asset.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ func (k *Keeper) GetAsset(ctx sdk.Context, denom string) (v v1.Asset, found bool
3333
return v, true
3434
}
3535

36+
// HasAsset checks if an asset with the given denomination exists in the module's KVStore.
37+
func (k *Keeper) HasAsset(ctx sdk.Context, denom string) bool {
38+
store := k.Store(ctx)
39+
key := types.AssetKey(denom)
40+
41+
return store.Has(key)
42+
}
43+
3644
// DeleteAsset removes an asset from the module's KVStore based on the asset denomination.
3745
func (k *Keeper) DeleteAsset(ctx sdk.Context, denom string) {
3846
store := k.Store(ctx)

x/oracle/keeper/msg_handler.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,68 @@
11
package keeper
22

33
import (
4+
sdkmath "cosmossdk.io/math"
45
sdk "github.com/cosmos/cosmos-sdk/types"
56

67
"github.com/sentinel-official/hub/v12/x/oracle/types"
78
"github.com/sentinel-official/hub/v12/x/oracle/types/v1"
89
)
910

11+
func (k *Keeper) HandleMsgAddAsset(ctx sdk.Context, msg *v1.MsgAddAssetRequest) (*v1.MsgAddAssetResponse, error) {
12+
authority := k.GetAuthority()
13+
if msg.From != authority {
14+
return nil, types.NewErrorInvalidSigner(msg.From, authority)
15+
}
16+
17+
if k.HasAsset(ctx, msg.Denom) {
18+
return nil, types.NewErrorDuplicateAsset(msg.Denom)
19+
}
20+
21+
asset := v1.Asset{
22+
Denom: msg.Denom,
23+
Decimals: msg.Decimals,
24+
PoolID: 0,
25+
BaseAssetDenom: msg.BaseAssetDenom,
26+
QuoteAssetDenom: msg.QuoteAssetDenom,
27+
Price: sdkmath.ZeroInt(),
28+
}
29+
30+
k.SetAsset(ctx, asset)
31+
32+
return &v1.MsgAddAssetResponse{}, nil
33+
}
34+
35+
func (k *Keeper) HandleMsgDeleteAsset(ctx sdk.Context, msg *v1.MsgDeleteAssetRequest) (*v1.MsgDeleteAssetResponse, error) {
36+
authority := k.GetAuthority()
37+
if msg.From != authority {
38+
return nil, types.NewErrorInvalidSigner(msg.From, authority)
39+
}
40+
41+
k.DeleteAsset(ctx, msg.Denom)
42+
43+
return &v1.MsgDeleteAssetResponse{}, nil
44+
}
45+
46+
func (k *Keeper) HandleMsgUpdateAsset(ctx sdk.Context, msg *v1.MsgUpdateAssetRequest) (*v1.MsgUpdateAssetResponse, error) {
47+
authority := k.GetAuthority()
48+
if msg.From != authority {
49+
return nil, types.NewErrorInvalidSigner(msg.From, authority)
50+
}
51+
52+
asset, found := k.GetAsset(ctx, msg.Denom)
53+
if !found {
54+
return nil, types.NewErrorAssetNotFound(msg.Denom)
55+
}
56+
57+
asset.Decimals = msg.Decimals
58+
asset.BaseAssetDenom = msg.BaseAssetDenom
59+
asset.QuoteAssetDenom = msg.QuoteAssetDenom
60+
61+
k.SetAsset(ctx, asset)
62+
63+
return &v1.MsgUpdateAssetResponse{}, nil
64+
}
65+
1066
func (k *Keeper) HandleMsgUpdateParams(ctx sdk.Context, msg *v1.MsgUpdateParamsRequest) (*v1.MsgUpdateParamsResponse, error) {
1167
authority := k.GetAuthority()
1268
if msg.From != authority {

x/oracle/services/v1/msg_server.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ func NewMsgServiceServer(k keeper.Keeper) v1.MsgServiceServer {
2121
return &msgServer{k}
2222
}
2323

24+
func (m *msgServer) MsgAddAsset(c context.Context, req *v1.MsgAddAssetRequest) (*v1.MsgAddAssetResponse, error) {
25+
ctx := sdk.UnwrapSDKContext(c)
26+
return m.HandleMsgAddAsset(ctx, req)
27+
}
28+
29+
func (m *msgServer) MsgDeleteAsset(c context.Context, req *v1.MsgDeleteAssetRequest) (*v1.MsgDeleteAssetResponse, error) {
30+
ctx := sdk.UnwrapSDKContext(c)
31+
return m.HandleMsgDeleteAsset(ctx, req)
32+
}
33+
34+
func (m *msgServer) MsgUpdateAsset(c context.Context, req *v1.MsgUpdateAssetRequest) (*v1.MsgUpdateAssetResponse, error) {
35+
ctx := sdk.UnwrapSDKContext(c)
36+
return m.HandleMsgUpdateAsset(ctx, req)
37+
}
38+
2439
func (m *msgServer) MsgUpdateParams(c context.Context, req *v1.MsgUpdateParamsRequest) (*v1.MsgUpdateParamsResponse, error) {
2540
ctx := sdk.UnwrapSDKContext(c)
2641
return m.HandleMsgUpdateParams(ctx, req)

x/oracle/types/errors.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import (
1111
var (
1212
ErrorInvalidMessage = sdkerrors.Register(ModuleName, 101, "invalid message")
1313

14-
ErrorAssetNotFound = sdkerrors.Register(ModuleName, 201, "asset not found")
15-
ErrorDenomNotFound = sdkerrors.Register(ModuleName, 202, "denom not found")
14+
ErrorAssetNotFound = sdkerrors.Register(ModuleName, 201, "asset not found")
15+
ErrorDenomNotFound = sdkerrors.Register(ModuleName, 202, "denom not found")
16+
ErrorDuplicateAsset = sdkerrors.Register(ModuleName, 203, "duplicate asset")
1617
)
1718

1819
func NewErrorInvalidVersion(version, expected string) error {
@@ -42,3 +43,7 @@ func NewErrorDenomtNotFound(portID, channelID string, sequence uint64) error {
4243
func NewErrorInvalidSigner(from, expected string) error {
4344
return sdkerrors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority %s; expected %s", from, expected)
4445
}
46+
47+
func NewErrorDuplicateAsset(denom string) error {
48+
return sdkerrors.Wrapf(ErrorDuplicateAsset, "asset %s already exists", denom)
49+
}

x/oracle/types/v1/msg.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,99 @@ import (
88
)
99

1010
var (
11+
_ sdk.Msg = (*MsgAddAssetRequest)(nil)
12+
_ sdk.Msg = (*MsgDeleteAssetRequest)(nil)
13+
_ sdk.Msg = (*MsgUpdateAssetRequest)(nil)
1114
_ sdk.Msg = (*MsgUpdateParamsRequest)(nil)
1215
)
1316

17+
func (m *MsgAddAssetRequest) ValidateBasic() error {
18+
if m.From == "" {
19+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "from cannot be empty")
20+
}
21+
if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
22+
return sdkerrors.Wrap(types.ErrorInvalidMessage, err.Error())
23+
}
24+
if err := sdk.ValidateDenom(m.Denom); err != nil {
25+
return sdkerrors.Wrap(types.ErrorInvalidMessage, err.Error())
26+
}
27+
if m.Decimals < 0 {
28+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "decimals cannot be negative")
29+
}
30+
if m.BaseAssetDenom == "" {
31+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "base_asset_denom cannot be empty")
32+
}
33+
if m.QuoteAssetDenom == "" {
34+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "quote_asset_denom cannot be empty")
35+
}
36+
37+
return nil
38+
}
39+
40+
func (m *MsgAddAssetRequest) GetSigners() []sdk.AccAddress {
41+
from, err := sdk.AccAddressFromBech32(m.From)
42+
if err != nil {
43+
panic(err)
44+
}
45+
46+
return []sdk.AccAddress{from.Bytes()}
47+
}
48+
49+
func (m *MsgDeleteAssetRequest) ValidateBasic() error {
50+
if m.From == "" {
51+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "from cannot be empty")
52+
}
53+
if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
54+
return sdkerrors.Wrap(types.ErrorInvalidMessage, err.Error())
55+
}
56+
if err := sdk.ValidateDenom(m.Denom); err != nil {
57+
return sdkerrors.Wrap(types.ErrorInvalidMessage, err.Error())
58+
}
59+
60+
return nil
61+
}
62+
63+
func (m *MsgDeleteAssetRequest) GetSigners() []sdk.AccAddress {
64+
from, err := sdk.AccAddressFromBech32(m.From)
65+
if err != nil {
66+
panic(err)
67+
}
68+
69+
return []sdk.AccAddress{from.Bytes()}
70+
}
71+
72+
func (m *MsgUpdateAssetRequest) ValidateBasic() error {
73+
if m.From == "" {
74+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "from cannot be empty")
75+
}
76+
if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
77+
return sdkerrors.Wrap(types.ErrorInvalidMessage, err.Error())
78+
}
79+
if err := sdk.ValidateDenom(m.Denom); err != nil {
80+
return sdkerrors.Wrap(types.ErrorInvalidMessage, err.Error())
81+
}
82+
if m.Decimals < 0 {
83+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "decimals cannot be negative")
84+
}
85+
if m.BaseAssetDenom == "" {
86+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "base_asset_denom cannot be empty")
87+
}
88+
if m.QuoteAssetDenom == "" {
89+
return sdkerrors.Wrap(types.ErrorInvalidMessage, "quote_asset_denom cannot be empty")
90+
}
91+
92+
return nil
93+
}
94+
95+
func (m *MsgUpdateAssetRequest) GetSigners() []sdk.AccAddress {
96+
from, err := sdk.AccAddressFromBech32(m.From)
97+
if err != nil {
98+
panic(err)
99+
}
100+
101+
return []sdk.AccAddress{from.Bytes()}
102+
}
103+
14104
func (m *MsgUpdateParamsRequest) ValidateBasic() error {
15105
if m.From == "" {
16106
return sdkerrors.Wrap(types.ErrorInvalidMessage, "from cannot be empty")

0 commit comments

Comments
 (0)