Skip to content

Commit

Permalink
feat: add layer2 crosschain module (#106)
Browse files Browse the repository at this point in the history
Co-authored-by: fx0x55 <80245546+fx0x55@users.noreply.github.com>
  • Loading branch information
zakir-code and fx0x55 authored Oct 31, 2023
1 parent 7cfe371 commit 179c9eb
Show file tree
Hide file tree
Showing 12 changed files with 283 additions and 4 deletions.
2 changes: 1 addition & 1 deletion app/genesis_test.go

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import (
fxtransfer "github.com/functionx/fx-core/v6/x/ibc/applications/transfer"
fxtransferkeeper "github.com/functionx/fx-core/v6/x/ibc/applications/transfer/keeper"
"github.com/functionx/fx-core/v6/x/ibc/ibcrouter"
layer2types "github.com/functionx/fx-core/v6/x/layer2/types"
migratekeeper "github.com/functionx/fx-core/v6/x/migrate/keeper"
migratetypes "github.com/functionx/fx-core/v6/x/migrate/types"
optimismtypes "github.com/functionx/fx-core/v6/x/optimism/types"
Expand All @@ -90,6 +91,7 @@ type CrossChainKeepers struct {
TronKeeper tronkeeper.Keeper
ArbitrumKeeper crosschainkeeper.Keeper
OptimismKeeper crosschainkeeper.Keeper
Layer2Keeper crosschainkeeper.Keeper
}

type AppKeepers struct {
Expand Down Expand Up @@ -411,6 +413,19 @@ func NewAppKeeper(
appKeepers.AccountKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
appKeepers.Layer2Keeper = crosschainkeeper.NewKeeper(
appCodec,
layer2types.ModuleName,
appKeepers.keys[layer2types.StoreKey],
appKeepers.StakingKeeper,
stakingkeeper.NewMsgServerImpl(appKeepers.StakingKeeper.Keeper),
distrkeeper.NewMsgServerImpl(appKeepers.DistrKeeper),
appKeepers.BankKeeper,
appKeepers.IBCTransferKeeper,
appKeepers.Erc20Keeper,
appKeepers.AccountKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
appKeepers.TronKeeper = tronkeeper.NewKeeper(crosschainkeeper.NewKeeper(
appCodec,
trontypes.ModuleName,
Expand All @@ -434,6 +449,7 @@ func NewAppKeeper(
AddRoute(ethtypes.ModuleName, crosschainkeeper.NewModuleHandler(appKeepers.EthKeeper)).
AddRoute(arbitrumtypes.ModuleName, crosschainkeeper.NewModuleHandler(appKeepers.ArbitrumKeeper)).
AddRoute(optimismtypes.ModuleName, crosschainkeeper.NewModuleHandler(appKeepers.OptimismKeeper)).
AddRoute(layer2types.ModuleName, crosschainkeeper.NewModuleHandler(appKeepers.Layer2Keeper)).
AddRoute(trontypes.ModuleName, tronkeeper.NewModuleHandler(appKeepers.TronKeeper))

appKeepers.CrosschainKeeper = crosschainkeeper.NewRouterKeeper(crosschainRouter)
Expand Down Expand Up @@ -485,6 +501,7 @@ func NewAppKeeper(
AddRoute(avalanchetypes.ModuleName, appKeepers.AvalancheKeeper).
AddRoute(arbitrumtypes.ModuleName, appKeepers.ArbitrumKeeper).
AddRoute(optimismtypes.ModuleName, appKeepers.OptimismKeeper).
AddRoute(layer2types.ModuleName, appKeepers.Layer2Keeper).
AddRoute(erc20types.ModuleName, appKeepers.Erc20Keeper)
appKeepers.FxTransferKeeper = appKeepers.FxTransferKeeper.SetRouter(*ibcTransferRouter)
appKeepers.FxTransferKeeper = appKeepers.FxTransferKeeper.SetRefundHook(appKeepers.Erc20Keeper)
Expand Down
2 changes: 2 additions & 0 deletions app/keepers/keepers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
bsctypes "github.com/functionx/fx-core/v6/x/bsc/types"
erc20types "github.com/functionx/fx-core/v6/x/erc20/types"
ethtypes "github.com/functionx/fx-core/v6/x/eth/types"
layer2types "github.com/functionx/fx-core/v6/x/layer2/types"
optimismtypes "github.com/functionx/fx-core/v6/x/optimism/types"
polygontypes "github.com/functionx/fx-core/v6/x/polygon/types"
trontypes "github.com/functionx/fx-core/v6/x/tron/types"
Expand Down Expand Up @@ -54,6 +55,7 @@ func TestNewAppKeeper(t *testing.T) {
trontypes.ModuleName: {authtypes.Minter, authtypes.Burner},
arbitrumtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
optimismtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
layer2types.ModuleName: {authtypes.Minter, authtypes.Burner},
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
erc20types.ModuleName: {authtypes.Minter, authtypes.Burner},
}
Expand Down
6 changes: 4 additions & 2 deletions app/keepers/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
ethtypes "github.com/functionx/fx-core/v6/x/eth/types"
precompilescrosschain "github.com/functionx/fx-core/v6/x/evm/precompiles/crosschain"
precompilesstaking "github.com/functionx/fx-core/v6/x/evm/precompiles/staking"
layer2types "github.com/functionx/fx-core/v6/x/layer2/types"
migratetypes "github.com/functionx/fx-core/v6/x/migrate/types"
optimismtypes "github.com/functionx/fx-core/v6/x/optimism/types"
polygontypes "github.com/functionx/fx-core/v6/x/polygon/types"
Expand All @@ -47,7 +48,7 @@ func (appKeepers *AppKeepers) generateKeys() {
evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey,
feegrant.StoreKey, authzkeeper.StoreKey,
bsctypes.StoreKey, polygontypes.StoreKey, avalanchetypes.StoreKey, ethtypes.StoreKey, trontypes.StoreKey,
arbitrumtypes.ModuleName, optimismtypes.ModuleName,
arbitrumtypes.ModuleName, optimismtypes.ModuleName, layer2types.ModuleName,
evmtypes.StoreKey, feemarkettypes.StoreKey,
erc20types.StoreKey, migratetypes.StoreKey,
)
Expand Down Expand Up @@ -94,7 +95,8 @@ func (appKeepers *AppKeepers) EvmPrecompiled() {
AddRoute(trontypes.ModuleName, appKeepers.TronKeeper).
AddRoute(avalanchetypes.ModuleName, appKeepers.AvalancheKeeper).
AddRoute(arbitrumtypes.ModuleName, appKeepers.ArbitrumKeeper).
AddRoute(optimismtypes.ModuleName, appKeepers.OptimismKeeper)
AddRoute(optimismtypes.ModuleName, appKeepers.OptimismKeeper).
AddRoute(layer2types.ModuleName, appKeepers.Layer2Keeper)
precompiled[precompilescrosschain.GetAddress()] = func(ctx sdk.Context) vm.PrecompiledContract {
return precompilescrosschain.NewPrecompiledContract(
ctx,
Expand Down
9 changes: 9 additions & 0 deletions app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ import (
fxgov "github.com/functionx/fx-core/v6/x/gov"
fxibctransfer "github.com/functionx/fx-core/v6/x/ibc/applications/transfer"
fxibctransfertypes "github.com/functionx/fx-core/v6/x/ibc/applications/transfer/types"
"github.com/functionx/fx-core/v6/x/layer2"
layer2types "github.com/functionx/fx-core/v6/x/layer2/types"
"github.com/functionx/fx-core/v6/x/migrate"
migratetypes "github.com/functionx/fx-core/v6/x/migrate/types"
"github.com/functionx/fx-core/v6/x/optimism"
Expand All @@ -81,6 +83,7 @@ func init() {
crosschaintypes.RegisterValidateBasic(trontypes.ModuleName, trontypes.TronMsgValidate{})
crosschaintypes.RegisterValidateBasic(arbitrumtypes.ModuleName, crosschaintypes.MsgValidate{})
crosschaintypes.RegisterValidateBasic(optimismtypes.ModuleName, crosschaintypes.MsgValidate{})
crosschaintypes.RegisterValidateBasic(layer2types.ModuleName, crosschaintypes.MsgValidate{})
}

// module account permissions
Expand All @@ -99,6 +102,7 @@ var maccPerms = map[string][]string{
trontypes.ModuleName: {authtypes.Minter, authtypes.Burner},
arbitrumtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
optimismtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
layer2types.ModuleName: {authtypes.Minter, authtypes.Burner},
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
erc20types.ModuleName: {authtypes.Minter, authtypes.Burner},
}
Expand Down Expand Up @@ -145,6 +149,7 @@ var ModuleBasics = module.NewBasicManager(
tron.AppModuleBasic{},
arbitrum.AppModule{},
optimism.AppModule{},
layer2.AppModule{},
fxevm.AppModuleBasic{},
feemarket.AppModuleBasic{},
erc20.AppModuleBasic{},
Expand Down Expand Up @@ -185,6 +190,7 @@ func appModules(
tron.NewAppModule(app.TronKeeper, app.GetSubspace(trontypes.ModuleName)),
arbitrum.NewAppModule(app.ArbitrumKeeper),
optimism.NewAppModule(app.OptimismKeeper),
layer2.NewAppModule(app.Layer2Keeper),
fxevm.NewAppModule(app.EvmKeeper, app.AccountKeeper, app.LegacyAmino(), app.GetKey(paramstypes.StoreKey), app.GetSubspace(evmtypes.ModuleName)),
feemarket.NewAppModule(app.FeeMarketKeeper, app.GetSubspace(feemarkettypes.ModuleName)),
erc20.NewAppModule(app.Erc20Keeper, app.GetSubspace(erc20types.ModuleName)),
Expand Down Expand Up @@ -223,6 +229,7 @@ func orderBeginBlockers() []string {
ethtypes.ModuleName,
arbitrumtypes.ModuleName,
optimismtypes.ModuleName,
layer2types.ModuleName,

feemarkettypes.ModuleName, // begin
evmtypes.ModuleName, // begin
Expand Down Expand Up @@ -261,6 +268,7 @@ func orderEndBlockers() []string {
ethtypes.ModuleName, // end
arbitrumtypes.ModuleName, // end
optimismtypes.ModuleName, // end
layer2types.ModuleName, // end

evmtypes.ModuleName, // end
feemarkettypes.ModuleName, // end
Expand Down Expand Up @@ -299,6 +307,7 @@ func orderInitBlockers() []string {
ethtypes.ModuleName,
arbitrumtypes.ModuleName,
optimismtypes.ModuleName,
layer2types.ModuleName,

feemarkettypes.ModuleName,
evmtypes.ModuleName,
Expand Down
5 changes: 4 additions & 1 deletion app/upgrades/v6/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import (
storetypes "github.com/cosmos/cosmos-sdk/store/types"

"github.com/functionx/fx-core/v6/app/upgrades"
layer2types "github.com/functionx/fx-core/v6/x/layer2/types"
)

var Upgrade = upgrades.Upgrade{
UpgradeName: "v6.0.x",
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: func() *storetypes.StoreUpgrades {
return &storetypes.StoreUpgrades{}
return &storetypes.StoreUpgrades{
Added: []string{layer2types.ModuleName},
}
},
}
21 changes: 21 additions & 0 deletions x/layer2/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cli

import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/spf13/cobra"

"github.com/functionx/fx-core/v6/x/crosschain/client/cli"
"github.com/functionx/fx-core/v6/x/layer2/types"
)

func GetQueryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: types.ModuleName,
Short: "Querying commands for the layer2 module",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
cmd.AddCommand(cli.GetQuerySubCmds(types.ModuleName)...)
return cmd
}
21 changes: 21 additions & 0 deletions x/layer2/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cli

import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/spf13/cobra"

"github.com/functionx/fx-core/v6/x/crosschain/client/cli"
"github.com/functionx/fx-core/v6/x/layer2/types"
)

func GetTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: types.ModuleName,
Short: "Layer2 transaction subcommands",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
cmd.AddCommand(cli.GetTxSubCmds(types.ModuleName)...)
return cmd
}
137 changes: 137 additions & 0 deletions x/layer2/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package layer2

import (
"encoding/json"
"fmt"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/gorilla/mux"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra"
abci "github.com/tendermint/tendermint/abci/types"

crosschainkeeper "github.com/functionx/fx-core/v6/x/crosschain/keeper"
crosschaintypes "github.com/functionx/fx-core/v6/x/crosschain/types"
"github.com/functionx/fx-core/v6/x/layer2/client/cli"
"github.com/functionx/fx-core/v6/x/layer2/types"
)

// type check to ensure the interface is properly implemented
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.EndBlockAppModule = AppModule{}
)

// ----------------------------------------------------------------------------
// AppModuleBasic
// ----------------------------------------------------------------------------

// AppModuleBasic object for module implementation
type AppModuleBasic struct{}

// Name implements app module basic
func (AppModuleBasic) Name() string { return types.ModuleName }

// DefaultGenesis implements app module basic
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
return cdc.MustMarshalJSON(types.DefaultGenesisState())
}

// ValidateGenesis implements app module basic
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, data json.RawMessage) error {
var state crosschaintypes.GenesisState
if err := cdc.UnmarshalJSON(data, &state); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}
return state.ValidateBasic()
}

// RegisterLegacyAminoCodec implements app module basic
func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {}

// RegisterRESTRoutes implements app module basic
func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {}

// RegisterGRPCGatewayRoutes registers the gRPC Gateway
func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {}

// GetQueryCmd implements app module basic
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
return cli.GetQueryCmd()
}

// GetTxCmd implements app module basic
func (AppModuleBasic) GetTxCmd() *cobra.Command {
return cli.GetTxCmd()
}

// RegisterInterfaces implements app bmodule basic
func (AppModuleBasic) RegisterInterfaces(_ codectypes.InterfaceRegistry) {}

// ----------------------------------------------------------------------------
// AppModule
// ----------------------------------------------------------------------------

// AppModule object for module implementation
type AppModule struct {
AppModuleBasic
keeper crosschainkeeper.Keeper
}

// NewAppModule creates a new AppModule Object
func NewAppModule(keeper crosschainkeeper.Keeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
}
}

// RegisterInvariants implements app module
func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}

// Deprecated: Route returns the message routing key
func (am AppModule) Route() sdk.Route {
return sdk.Route{}
}

// QuerierRoute implements app module
func (am AppModule) QuerierRoute() string { return "" }

// LegacyQuerierHandler returns no sdk.Querier
func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier {
return nil
}

// RegisterServices registers module services.
func (am AppModule) RegisterServices(_ module.Configurator) {}

// InitGenesis initializes the genesis state for this module and implements app module.
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
var genesisState crosschaintypes.GenesisState
cdc.MustUnmarshalJSON(data, &genesisState)

crosschainkeeper.InitGenesis(ctx, am.keeper, &genesisState)
return []abci.ValidatorUpdate{}
}

// ExportGenesis exports the current genesis state to a json.RawMessage
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
state := crosschainkeeper.ExportGenesis(ctx, am.keeper)
return cdc.MustMarshalJSON(state)
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (am AppModule) ConsensusVersion() uint64 {
return 1
}

// EndBlock implements app module
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
am.keeper.EndBlocker(ctx)
return []abci.ValidatorUpdate{}
}
14 changes: 14 additions & 0 deletions x/layer2/types/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package types

import (
crosschaintypes "github.com/functionx/fx-core/v6/x/crosschain/types"
)

func DefaultGenesisState() *crosschaintypes.GenesisState {
params := crosschaintypes.DefaultParams()
params.GravityId = "fx-layer2-bridge"
params.AverageExternalBlockTime = 2_000
return &crosschaintypes.GenesisState{
Params: params,
}
}
Loading

0 comments on commit 179c9eb

Please sign in to comment.