Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bridge module #16

Merged
merged 5 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
assetmodulekeeper "github.com/realiotech/realio-network/x/asset/keeper"
assetmoduletypes "github.com/realiotech/realio-network/x/asset/types"

bridgemodule "github.com/realiotech/realio-network/x/bridge"
bridgemodulekeeper "github.com/realiotech/realio-network/x/bridge/keeper"
bridgemoduletypes "github.com/realiotech/realio-network/x/bridge/types"

realionetworktypes "github.com/realiotech/realio-network/types"

// unnamed import of statik for swagger UI support
Expand Down Expand Up @@ -179,6 +183,7 @@
evm.AppModuleBasic{},
feemarket.AppModuleBasic{},
assetmodule.AppModuleBasic{},
bridgemodule.AppModuleBasic{},
consensus.AppModuleBasic{},
// this line is used by starport scaffolding # stargate/app/moduleBasic
)
Expand All @@ -194,6 +199,7 @@
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
assetmoduletypes.ModuleName: {authtypes.Minter, authtypes.Burner},
bridgemoduletypes.ModuleName: {authtypes.Minter, authtypes.Burner},
multistakingtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
// this line is used by starport scaffolding # stargate/app/maccPerms
}
Expand Down Expand Up @@ -264,7 +270,8 @@
ScopedTransferKeeper capabilitykeeper.ScopedKeeper

// Realio Network keepers
AssetKeeper assetmodulekeeper.Keeper
AssetKeeper assetmodulekeeper.Keeper
BridgeKeeper bridgemodulekeeper.Keeper

// mm is the module manager
mm *module.Manager
Expand Down Expand Up @@ -309,7 +316,7 @@
// ibc keys
ibcexported.StoreKey, ibctransfertypes.StoreKey,
// realio network keys
assetmoduletypes.StoreKey,
assetmoduletypes.StoreKey, bridgemoduletypes.StoreKey,
// ethermint keys
evmtypes.StoreKey, feemarkettypes.StoreKey,
// multi-staking keys
Expand Down Expand Up @@ -465,6 +472,14 @@
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

app.BridgeKeeper = bridgemodulekeeper.NewKeeper(
appCodec,
runtime.NewKVStoreService(keys[bridgemoduletypes.StoreKey]),
app.AccountKeeper,
app.BankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

// Add transfer restriction
app.BankKeeper.AppendSendRestriction(app.AssetKeeper.AssetSendRestriction)

Expand Down Expand Up @@ -558,6 +573,7 @@

// realio network
assetmodule.NewAppModule(appCodec, app.AssetKeeper, app.BankKeeper, app.GetSubspace(assetmoduletypes.ModuleName)),
bridgemodule.NewAppModule(appCodec, app.BridgeKeeper),
)

// During begin block slashing happens after distr.BeginBlocker so that
Expand Down Expand Up @@ -589,6 +605,7 @@
paramstypes.ModuleName,
vestingtypes.ModuleName,
assetmoduletypes.ModuleName,
bridgemoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/beginBlockers
)

Expand Down Expand Up @@ -617,6 +634,7 @@
upgradetypes.ModuleName,
// realio modules
assetmoduletypes.ModuleName,
bridgemoduletypes.ModuleName,
)

// NOTE: The genutils module must occur after staking so that pools are
Expand Down Expand Up @@ -651,6 +669,7 @@
feegrant.ModuleName,
// realio modules
assetmoduletypes.ModuleName,
bridgemoduletypes.ModuleName,
// NOTE: crisis module must go at the end to check for invariants on each module
crisistypes.ModuleName,
consensusparamtypes.ModuleName,
Expand All @@ -658,7 +677,7 @@

app.mm.RegisterInvariants(app.CrisisKeeper)
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
app.mm.RegisterServices(app.configurator)

Check failure on line 680 in app/app.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `app.mm.RegisterServices` is not checked (errcheck)

// create the simulation manager and define the order of the modules for deterministic simulations
// NOTE: this is not required apps that don't use the simulator for fuzz testing transactions
Expand All @@ -680,6 +699,7 @@
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, app.GetSubspace(evmtypes.ModuleName)),
feemarket.NewAppModule(app.FeeMarketKeeper, app.GetSubspace(feemarkettypes.ModuleName)),
assetmodule.NewAppModule(appCodec, app.AssetKeeper, app.BankKeeper, app.GetSubspace(assetmoduletypes.ModuleName)),
bridgemodule.NewAppModule(appCodec, app.BridgeKeeper),
// this line is used by starport scaffolding # stargate/app/appModule
)
app.sm.RegisterStoreDecoders()
Expand Down Expand Up @@ -753,7 +773,7 @@
if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
}
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap())

Check failure on line 776 in app/app.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `app.UpgradeKeeper.SetModuleVersionMap` is not checked (errcheck)
return app.mm.InitGenesis(ctx, app.appCodec, genesisState)
}

Expand Down
10 changes: 10 additions & 0 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
multistakingtypes "github.com/realio-tech/multi-staking-module/x/multi-staking/types"
"github.com/realiotech/realio-network/cmd/config"
"github.com/realiotech/realio-network/types"
bridgetypes "github.com/realiotech/realio-network/x/bridge/types"
minttypes "github.com/realiotech/realio-network/x/mint/types"
)

Expand Down Expand Up @@ -247,6 +248,15 @@ func GenesisStateWithValSet(app *RealioNetwork, genesisState simapp.GenesisState
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{})
genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis)

bridgeGenesis := bridgetypes.DefaultGenesis()
bridgeGenesis.RatelimitEpochInfo.CurrentEpochStartHeight = 5
bridgeGenesis.RegisteredCoins = []sdk.Coin{
sdk.NewCoin(MultiStakingCoinA.Denom, math.NewInt(1000000000)),
sdk.NewCoin(MultiStakingCoinB.Denom, math.NewInt(1000000000)),
}
bridgeGenesis.Params.Authority = genAccs[0].GetAddress().String()
genesisState[bridgetypes.ModuleName] = app.AppCodec().MustMarshalJSON(bridgeGenesis)

return genesisState
}

Expand Down
24 changes: 24 additions & 0 deletions proto/realionetwork/bridge/v1/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
syntax = "proto3";
package realionetwork.bridge.v1;

import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "cosmos/base/v1beta1/coin.proto";
import "realionetwork/bridge/v1/params.proto";
import "realionetwork/bridge/v1/ratelimit.proto";

option go_package = "github.com/realiotech/realio-network/x/bridge/types";

// GenesisState defines the bridge module's genesis state.
message GenesisState {
Params params = 1 [ (gogoproto.nullable) = false ];
// registered denoms and its rate limit
repeated cosmos.base.v1beta1.Coin registered_coins = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];

// rate limit epoch info
EpochInfo ratelimit_epoch_info = 3 [ (gogoproto.nullable) = false ];
}
12 changes: 12 additions & 0 deletions proto/realionetwork/bridge/v1/params.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
syntax = "proto3";
package realionetwork.bridge.v1;

import "gogoproto/gogo.proto";

option go_package = "github.com/realiotech/realio-network/x/bridge/types";

// Params defines the parameters for the module.
message Params {
option (gogoproto.goproto_stringer) = false;
string authority = 1;
}
69 changes: 69 additions & 0 deletions proto/realionetwork/bridge/v1/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
syntax = "proto3";
package realionetwork.bridge.v1;

import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "realionetwork/bridge/v1/params.proto";
import "realionetwork/bridge/v1/ratelimit.proto";

option go_package = "github.com/realiotech/realio-network/x/bridge/types";

// Query defines the gRPC querier service.
service Query {
// Parameters queries the parameters of the module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/realionetwork/bridge/v1/params";
}

// Parameters queries the ratelimits of the module.
rpc RateLimits(QueryRateLimitsRequest) returns (QueryRateLimitsResponse) {
option (google.api.http).get = "/realionetwork/bridge/v1/ratelimits";
}

// Parameters queries the ratelimit of a specific denom of the module.
rpc RateLimit(QueryRateLimitRequest) returns (QueryRateLimitResponse) {
option (google.api.http).get =
"/realionetwork/bridge/v1/ratelimits/{denom}";
}

// Parameters queries the epoch info of the module.
rpc EpochInfo(QueryEpochInfoRequest) returns (QueryEpochInfoResponse) {
option (google.api.http).get = "/realionetwork/bridge/v1/epoch_info";
}
}

// QueryParamsRequest is request type for the Query/Params RPC method.
message QueryParamsRequest {}

// QueryParamsResponse is response type for the Query/Params RPC method.
message QueryParamsResponse {
// params holds all the parameters of this module.
Params params = 1 [ (gogoproto.nullable) = false ];
}

// QueryRateLimitsRequest is request type for the Query/RateLimits RPC method.
message QueryRateLimitsRequest {}

// QueryRateLimitsResponse is response type for the Query/RateLimits RPC method.
message QueryRateLimitsResponse {
repeated RateLimit ratelimits = 1 [ (gogoproto.nullable) = false ];
}

// QueryRateLimitRequest is request type for the Query/RateLimit RPC method.
message QueryRateLimitRequest {
// denom of the coin to query for.
string denom = 1;
}

// QueryRateLimitResponse is response type for the Query/RateLimit RPC method.
message QueryRateLimitResponse {
RateLimit ratelimit = 1 [ (gogoproto.nullable) = false ];
}

// QueryEpochInfoRequest is request type for the Query/EpochInfo RPC method.
message QueryEpochInfoRequest {}

// QueryEpochInfoResponse is response type for the Query/EpochInfo RPC method.
message QueryEpochInfoResponse {
EpochInfo epoch_info = 1 [ (gogoproto.nullable) = false ];
}
47 changes: 47 additions & 0 deletions proto/realionetwork/bridge/v1/ratelimit.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
syntax = "proto3";
package realionetwork.bridge.v1;

import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "cosmos/base/v1beta1/coin.proto";
import "realionetwork/bridge/v1/params.proto";

option go_package = "github.com/realiotech/realio-network/x/bridge/types";

// EpochInfo defines the rate limit epoch info
message EpochInfo {
// start_time is the time at which the timer first ever ticks.
// If start_time is in the future, the epoch will not begin until the start
// time.
google.protobuf.Timestamp start_time = 1
[ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ];

// duration is the time in between epoch ticks.
// In order for intended behavior to be met, duration should
// be greater than the chains expected block time.
// Duration must be non-zero.
google.protobuf.Duration duration = 2 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.jsontag) = "duration,omitempty"
];
google.protobuf.Timestamp current_epoch_start_time = 3
[ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ];
// epoch_counting_started is a boolean, that indicates whether this
// epoch timer has began yet.
bool epoch_counting_started = 4;
int64 current_epoch_start_height = 5;
}

message RateLimit {
string ratelimit = 1 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];

string current_inflow = 2 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];
}
84 changes: 84 additions & 0 deletions proto/realionetwork/bridge/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
syntax = "proto3";
package realionetwork.bridge.v1;

import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";
import "cosmos/base/v1beta1/coin.proto";
import "realionetwork/bridge/v1/params.proto";

option go_package = "github.com/realiotech/realio-network/x/bridge/types";

// Msg defines the Msg service.
service Msg {
rpc BridgeIn(MsgBridgeIn) returns (MsgBridgeInResponse);
rpc BridgeOut(MsgBridgeOut) returns (MsgBridgeOutResponse);
rpc RegisterNewCoins(MsgRegisterNewCoins) returns (MsgRegisterNewCoinsResponse);
rpc DeregisterCoins(MsgDeregisterCoins) returns (MsgDeregisterCoinsResponse);
rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);
rpc UpdateEpochDuration(MsgUpdateEpochDuration)
returns (MsgUpdateEpochDurationResponse);
}

message MsgBridgeIn {
string authority = 1;
cosmos.base.v1beta1.Coin coin = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin"
];
}

message MsgBridgeInResponse {}

message MsgBridgeOut {
string signer = 1;
cosmos.base.v1beta1.Coin coin = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin"
];
}

message MsgBridgeOutResponse {}

message MsgRegisterNewCoins {
string authority = 1;
repeated cosmos.base.v1beta1.Coin coins = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

message MsgRegisterNewCoinsResponse {}

message MsgDeregisterCoins {
string authority = 1;
repeated string denoms = 2;
}

message MsgDeregisterCoinsResponse {}

message MsgUpdateParams {
// authority is the address that controls the module (defaults to x/gov unless
// overwritten).
string authority = 1;

// params defines the x/mint parameters to update.
//
// NOTE: All parameters must be supplied.
Params params = 2 [ (gogoproto.nullable) = false ];
}

message MsgUpdateParamsResponse {}

message MsgUpdateEpochDuration {
// authority is the address that controls the module (defaults to x/gov unless
// overwritten).
string authority = 1;

google.protobuf.Duration duration = 2 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.jsontag) = "duration,omitempty"
];
}

message MsgUpdateEpochDurationResponse {}
Loading
Loading