Skip to content

Commit

Permalink
feat x/bridge: added AssetInfo (#7753)
Browse files Browse the repository at this point in the history
* updated proto contracts

* added asset info

* added unit tests for the types package

* made fees and needed_voters global

* code review 1

* refactored x/bridge types tests

* Generated protofile changes

---------

Co-authored-by: github-actions <github-actions@github.com>
  • Loading branch information
keruch and github-actions authored Mar 19, 2024
1 parent be76d37 commit 3e8d0d4
Show file tree
Hide file tree
Showing 21 changed files with 1,597 additions and 462 deletions.
52 changes: 32 additions & 20 deletions proto/osmosis/bridge/v1beta1/bridge.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,41 @@ message Params {
repeated string signers = 1 [ (gogoproto.moretags) = "yaml:\"signers\"" ];
// Assets is a list used to create tokenfactory denoms
// for corresponding trading pairs
repeated AssetWithStatus assets = 2 [
repeated Asset assets = 2 [
(gogoproto.moretags) = "yaml:\"assets\"",
(gogoproto.nullable) = false
];
// VotesNeeded marks how many signers out of the list of signers need
// to sign until a tx can be considered finalized
uint64 votes_needed = 3 [ (gogoproto.moretags) = "yaml:\"votes_needed\"" ];
// Fee defines a param for fee that go towards the validator set
// signing the incoming/outgoing txs. The fee is measured as a ratio,
// so its value lies between 0 and 1.
string fee = 4 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.moretags) = "yaml:\"fee\"",
(gogoproto.nullable) = false
];
}

// AssetID defines a pair of the source chain name and its Osmosis
// representation denoted by denom. AssetID is a primary key for Asset.
message AssetID {
// SourceChain is a source chain name
string source_chain = 1 [ (gogoproto.moretags) = "yaml:\"source_chain\"" ];
// Denom is the Osmosis representation of the SourceChain
string denom = 2 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
}

// Asset is a representation of the asset.
message Asset {
// ID is the asset's primary key
AssetID id = 1
[ (gogoproto.moretags) = "yaml:\"id\"", (gogoproto.nullable) = false ];
// Status is a current status of the asset
AssetStatus status = 2 [ (gogoproto.moretags) = "yaml:\"status\"" ];
// Exponent represents the power of 10 used for coin representation
uint64 exponent = 3 [ (gogoproto.moretags) = "yaml:\"exponent\"" ];
}

enum AssetStatus {
Expand All @@ -23,23 +54,4 @@ enum AssetStatus {
ASSET_STATUS_BLOCKED_INBOUND = 2;
ASSET_STATUS_BLOCKED_OUTBOUND = 3;
ASSET_STATUS_BLOCKED_BOTH = 4;
}

// AssetWithStatus defines a pair of the asset and its current status.
message AssetWithStatus {
Asset asset = 1
[ (gogoproto.moretags) = "yaml:\"asset\"", (gogoproto.nullable) = false ];
AssetStatus asset_status = 2
[ (gogoproto.moretags) = "yaml:\"asset_status\"" ];
}

// Asset defines a pair of the source chain name and its Osmosis representation
// denoted by denom. It also includes a precision used for coins representation.
message Asset {
// SourceChain is a source chain name
string source_chain = 1 [ (gogoproto.moretags) = "yaml:\"source_chain\"" ];
// Denom is the Osmosis representation of the SourceChain
string denom = 2 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
// Precision used for coins representation
uint64 precision = 3 [ (gogoproto.moretags) = "yaml:\"precision\"" ];
}
26 changes: 16 additions & 10 deletions proto/osmosis/bridge/v1beta1/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ message EventInboundTransfer {
string sender = 1;
// DestAddr is a destination Osmosis address
string dest_addr = 2;
// Asset contains a source chain and a target denom
Asset asset = 3 [ (gogoproto.nullable) = false ];
// AssetID is the ID of the asset being transferred
AssetID asset_id = 3 [ (gogoproto.nullable) = false ];
// Amount of coins to transfer
string amount = 4 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
Expand All @@ -25,8 +25,8 @@ message EventOutboundTransfer {
string sender = 1;
// DestAddr is a destination Osmosis address
string dest_addr = 2;
// Asset contains a source chain and a target denom
Asset asset = 3 [ (gogoproto.nullable) = false ];
// AssetID is the ID of the asset being transferred
AssetID asset_id = 3 [ (gogoproto.nullable) = false ];
// Amount of coins to transfer
string amount = 4 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
Expand All @@ -39,14 +39,20 @@ message EventUpdateParams {
repeated string created_signers = 2;
repeated string deleted_signers = 3;

repeated AssetWithStatus new_assets = 4 [ (gogoproto.nullable) = false ];
repeated AssetWithStatus created_assets = 5 [ (gogoproto.nullable) = false ];
repeated AssetWithStatus deleted_assets = 6 [ (gogoproto.nullable) = false ];
repeated Asset new_assets = 4 [ (gogoproto.nullable) = false ];
repeated Asset created_assets = 5 [ (gogoproto.nullable) = false ];
repeated Asset deleted_assets = 6 [ (gogoproto.nullable) = false ];

uint64 new_votes_needed = 7;
string new_fee = 8 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

message EventChangeAssetStatus {
string sender = 1;
Asset asset = 2 [ (gogoproto.nullable) = false ];
AssetStatus old_asset_status = 3;
AssetStatus new_asset_status = 4;
AssetID asset_id = 2 [ (gogoproto.nullable) = false ];
AssetStatus old_status = 3;
AssetStatus new_status = 4;
}
29 changes: 17 additions & 12 deletions proto/osmosis/bridge/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ message MsgInboundTransfer {
string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ];
// DestAddr is a destination Osmosis address
string dest_addr = 2 [ (gogoproto.moretags) = "yaml:\"dest_addr\"" ];
// Asset contains a source chain and a target denom
Asset asset = 3
[ (gogoproto.moretags) = "yaml:\"asset\"", (gogoproto.nullable) = false ];
// AssetID is the ID of the asset being transferred
AssetID asset_id = 3 [
(gogoproto.moretags) = "yaml:\"asset_id\"",
(gogoproto.nullable) = false
];
// Amount of coins to transfer
string amount = 4 [
(gogoproto.moretags) = "yaml:\"amount\"",
Expand All @@ -63,9 +65,11 @@ message MsgOutboundTransfer {
string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ];
// DestAddr is a destination address
string dest_addr = 2 [ (gogoproto.moretags) = "yaml:\"dest_addr\"" ];
// Asset contains a target chain and a source denom
Asset asset = 3
[ (gogoproto.moretags) = "yaml:\"asset\"", (gogoproto.nullable) = false ];
// AssetID is the ID of the asset being transferred
AssetID asset_id = 3 [
(gogoproto.moretags) = "yaml:\"asset_id\"",
(gogoproto.nullable) = false
];
// Amount of coins to transfer
string amount = 4 [
(gogoproto.moretags) = "yaml:\"amount\"",
Expand Down Expand Up @@ -100,13 +104,14 @@ message MsgChangeAssetStatus {

// Sender is a sender's address
string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ];
// Asset is an asset to update.
// AssetID is the ID of the asset to update.
// The asset should be known; otherwise, the method will failed.
Asset asset = 2
[ (gogoproto.moretags) = "yaml:\"asset\"", (gogoproto.nullable) = false ];
// NewAssetStatus is a new asset's status.
AssetStatus new_asset_status = 3
[ (gogoproto.moretags) = "yaml:\"new_asset_status\"" ];
AssetID asset_id = 2 [
(gogoproto.moretags) = "yaml:\"asset_id\"",
(gogoproto.nullable) = false
];
// NewStatus is a new asset's status.
AssetStatus new_status = 3 [ (gogoproto.moretags) = "yaml:\"new_status\"" ];
}

message MsgChangeAssetStatusResponse {}
26 changes: 12 additions & 14 deletions x/bridge/keeper/assets.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package keeper

import (
"slices"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"

Expand All @@ -17,28 +19,24 @@ type ChangeAssetStatusResult struct {
// Returns error if the provided asset is not found in the module params.
func (k Keeper) ChangeAssetStatus(
ctx sdk.Context,
asset types.Asset,
assetID types.AssetID,
newStatus types.AssetStatus,
) (ChangeAssetStatusResult, error) {
// get current params
params := k.GetParams(ctx)

// check if the specified asset is known
const notFoundIdx = -1
var assetIdx = notFoundIdx
for i := range params.Assets {
if params.Assets[i].Asset == asset {
assetIdx = i
break
}
}
assetIdx := slices.IndexFunc(params.Assets, func(v types.Asset) bool {
return v.Id == assetID
})
if assetIdx == notFoundIdx {
return ChangeAssetStatusResult{}, errorsmod.Wrapf(types.ErrInvalidAsset, "Asset not found")
return ChangeAssetStatusResult{}, errorsmod.Wrapf(types.ErrInvalidAssetID, "Asset not found")
}

// update assetIdx asset status
oldStatus := params.Assets[assetIdx].AssetStatus
params.Assets[assetIdx].AssetStatus = newStatus
oldStatus := params.Assets[assetIdx].Status
params.Assets[assetIdx].Status = newStatus
k.SetParam(ctx, types.KeyAssets, params.Assets)

return ChangeAssetStatusResult{
Expand All @@ -48,7 +46,7 @@ func (k Keeper) ChangeAssetStatus(
}

// createAssets creates tokenfactory denoms for all provided assets
func (k Keeper) createAssets(ctx sdk.Context, assets []types.AssetWithStatus) error {
func (k Keeper) createAssets(ctx sdk.Context, assets []types.Asset) error {
bridgeModuleAddr := k.accountKeeper.GetModuleAddress(types.ModuleName)

handler := k.router.Handler(new(tokenfactorytypes.MsgCreateDenom))
Expand All @@ -59,7 +57,7 @@ func (k Keeper) createAssets(ctx sdk.Context, assets []types.AssetWithStatus) er
for _, asset := range assets {
msgCreateDenom := &tokenfactorytypes.MsgCreateDenom{
Sender: bridgeModuleAddr.String(),
Subdenom: asset.Asset.Name(),
Subdenom: asset.Name(),
}

// ignore resp since it is not needed in this method
Expand All @@ -68,7 +66,7 @@ func (k Keeper) createAssets(ctx sdk.Context, assets []types.AssetWithStatus) er
if err != nil {
return errorsmod.Wrapf(
types.ErrTokenfactory,
"Can't execute a create denom message for %s: %s", asset.Asset.Name(), err,
"Can't execute a create denom message for %s: %s", asset.Name(), err,
)
}
}
Expand Down
20 changes: 11 additions & 9 deletions x/bridge/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ func (m msgServer) InboundTransfer(
return nil, errorsmod.Wrapf(sdkerrors.ErrorInvalidSigner, "Sender is not part of the signer set")
}

err := m.k.InboundTransfer(ctx, msg.DestAddr, msg.Asset, msg.Amount)
err := m.k.InboundTransfer(ctx, msg.DestAddr, msg.AssetId, msg.Amount)
if err != nil {
return nil, err
}
err = ctx.EventManager().EmitTypedEvent(&types.EventInboundTransfer{
Sender: msg.Sender,
DestAddr: msg.DestAddr,
Asset: msg.Asset,
AssetId: msg.AssetId,
Amount: msg.Amount,
})
if err != nil {
Expand All @@ -58,14 +58,14 @@ func (m msgServer) OutboundTransfer(

// Don't need to check the signature here since every user could be the sender

err := m.k.OutboundTransfer(ctx, msg.Sender, msg.Asset, msg.Amount)
err := m.k.OutboundTransfer(ctx, msg.Sender, msg.AssetId, msg.Amount)
if err != nil {
return nil, err
}
err = ctx.EventManager().EmitTypedEvent(&types.EventOutboundTransfer{
Sender: msg.Sender,
DestAddr: msg.DestAddr,
Asset: msg.Asset,
AssetId: msg.AssetId,
Amount: msg.Amount,
})
if err != nil {
Expand Down Expand Up @@ -99,6 +99,8 @@ func (m msgServer) UpdateParams(
NewAssets: msg.NewParams.Assets,
CreatedAssets: result.assetsToCreate,
DeletedAssets: result.assetsToDelete,
NewVotesNeeded: msg.NewParams.VotesNeeded,
NewFee: msg.NewParams.Fee,
})
if err != nil {
return nil, err
Expand All @@ -113,16 +115,16 @@ func (m msgServer) ChangeAssetStatus(
) (*types.MsgChangeAssetStatusResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

result, err := m.k.ChangeAssetStatus(ctx, msg.Asset, msg.NewAssetStatus)
result, err := m.k.ChangeAssetStatus(ctx, msg.AssetId, msg.NewStatus)
if err != nil {
return nil, err
}

err = ctx.EventManager().EmitTypedEvent(&types.EventChangeAssetStatus{
Sender: msg.Sender,
Asset: msg.Asset,
OldAssetStatus: result.OldStatus,
NewAssetStatus: result.NewStatus,
Sender: msg.Sender,
AssetId: msg.AssetId,
OldStatus: result.OldStatus,
NewStatus: result.NewStatus,
})
if err != nil {
return nil, err
Expand Down
8 changes: 4 additions & 4 deletions x/bridge/keeper/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
type UpdateParamsResult struct {
signersToCreate []string
signersToDelete []string
assetsToCreate []types.AssetWithStatus
assetsToDelete []types.AssetWithStatus
assetsToCreate []types.Asset
assetsToDelete []types.Asset
}

// UpdateParams properly updates params of the module.
Expand All @@ -34,10 +34,10 @@ func (k Keeper) UpdateParams(ctx sdk.Context, newParams types.Params) (UpdatePar

// disable deleted assets
for _, asset := range assetsToDelete {
_, err = k.ChangeAssetStatus(ctx, asset.Asset, types.AssetStatus_ASSET_STATUS_BLOCKED_BOTH)
_, err = k.ChangeAssetStatus(ctx, asset.Id, types.AssetStatus_ASSET_STATUS_BLOCKED_BOTH)
if err != nil {
return UpdateParamsResult{},
errorsmod.Wrapf(types.ErrCantChangeAssetStatus, "Can't disable asset %s: %s", asset.Asset.Name(), err)
errorsmod.Wrapf(types.ErrCantChangeAssetStatus, "Can't disable asset %s: %s", asset.Name(), err)
}
}

Expand Down
Loading

0 comments on commit 3e8d0d4

Please sign in to comment.