diff --git a/app/genesis_test.go b/app/genesis_test.go index 912e0ffa9..f35ea7aa3 100644 --- a/app/genesis_test.go +++ b/app/genesis_test.go @@ -12,7 +12,7 @@ import ( func TestNewDefaultGenesisByDenom(t *testing.T) { // bank -> denom_metadata -> "uri":"", "uri_hash":"" - const genesisData = `{"arbitrum":{"params":{"gravity_id":"fx-arbitrum-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"500","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"auth":{"params":{"max_memo_characters":"256","tx_sig_limit":"7","tx_size_cost_per_byte":"10","sig_verify_cost_ed25519":"590","sig_verify_cost_secp256k1":"1000"},"accounts":[]},"authz":{"authorization":[]},"avalanche":{"params":{"gravity_id":"fx-avalanche-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"2000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"bank":{"params":{"send_enabled":[],"default_send_enabled":true},"balances":[{"address":"cosmos1c602zv38ht8xu8u2qcmymyl55mcyvvjrzq9ur3","coins":[{"denom":"FX","amount":"378600525462891000000000000"}]}],"supply":[{"denom":"FX","amount":"378604525462891000000000000"}],"denom_metadata":[{"description":"The native staking token of the Function X","denom_units":[{"denom":"FX","exponent":0,"aliases":[]}],"base":"FX","display":"FX","name":"Function X","symbol":"FX","uri":"","uri_hash":""}]},"bsc":{"params":{"gravity_id":"fx-bsc-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"3000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"capability":{"index":"1","owners":[]},"crisis":{"constant_fee":{"denom":"FX","amount":"13333000000000000000000"}},"distribution":{"params":{"community_tax":"0.400000000000000000","base_proposer_reward":"0.010000000000000000","bonus_proposer_reward":"0.040000000000000000","withdraw_addr_enabled":true},"fee_pool":{"community_pool":[]},"delegator_withdraw_infos":[],"previous_proposer":"","outstanding_rewards":[],"validator_accumulated_commissions":[],"validator_historical_rewards":[],"validator_current_rewards":[],"delegator_starting_infos":[],"validator_slash_events":[]},"erc20":{"params":{"enable_erc20":true,"enable_evm_hook":true,"ibc_timeout":"43200s"},"token_pairs":[]},"eth":{"params":{"gravity_id":"fx-bridge-eth","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"15000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"evidence":{"evidence":[]},"evm":{"accounts":[],"params":{"evm_denom":"FX","enable_create":true,"enable_call":true,"extra_eips":[],"chain_config":{"homestead_block":"0","dao_fork_block":"0","dao_fork_support":true,"eip150_block":"0","eip150_hash":"0x0000000000000000000000000000000000000000000000000000000000000000","eip155_block":"0","eip158_block":"0","byzantium_block":"0","constantinople_block":"0","petersburg_block":"0","istanbul_block":"0","muir_glacier_block":"0","berlin_block":"0","london_block":"0","arrow_glacier_block":"0","gray_glacier_block":"0","merge_netsplit_block":"0","shanghai_block":"0","cancun_block":"0"},"allow_unprotected_txs":false}},"feegrant":{"allowances":[]},"feemarket":{"params":{"no_base_fee":false,"base_fee_change_denominator":8,"elasticity_multiplier":2,"enable_height":"0","base_fee":"500000000000","min_gas_price":"500000000000.000000000000000000","min_gas_multiplier":"0.000000000000000000"},"block_gas":"0"},"fxtransfer":{},"genutil":{"gen_txs":[]},"gov":{"starting_proposal_id":"1","deposits":[],"votes":[],"proposals":[],"deposit_params":{"min_deposit":[{"denom":"FX","amount":"10000000000000000000000"}],"max_deposit_period":"1209600s"},"voting_params":{"voting_period":"1209600s"},"tally_params":{"quorum":"0.400000000000000000","threshold":"0.500000000000000000","veto_threshold":"0.334000000000000000"}},"ibc":{"client_genesis":{"clients":[],"clients_consensus":[],"clients_metadata":[],"params":{"allowed_clients":["07-tendermint"]},"create_localhost":false,"next_client_sequence":"0"},"connection_genesis":{"connections":[],"client_connection_paths":[],"next_connection_sequence":"0","params":{"max_expected_time_per_block":"30000000000"}},"channel_genesis":{"channels":[],"acknowledgements":[],"commitments":[],"receipts":[],"send_sequences":[],"recv_sequences":[],"ack_sequences":[],"next_channel_sequence":"0"}},"migrate":{},"mint":{"minter":{"inflation":"0.350000000000000000","annual_provisions":"0.000000000000000000"},"params":{"mint_denom":"FX","inflation_rate_change":"0.300000000000000000","inflation_max":"0.416762000000000000","inflation_min":"0.170000000000000000","goal_bonded":"0.510000000000000000","blocks_per_year":"6311520"}},"optimism":{"params":{"gravity_id":"fx-optimism-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"500","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"params":{},"polygon":{"params":{"gravity_id":"fx-polygon-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"2000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"slashing":{"params":{"signed_blocks_window":"20000","min_signed_per_window":"0.050000000000000000","downtime_jail_duration":"600s","slash_fraction_double_sign":"0.050000000000000000","slash_fraction_downtime":"0.001000000000000000"},"signing_infos":[],"missed_blocks":[]},"staking":{"params":{"unbonding_time":"1814400s","max_validators":20,"max_entries":7,"historical_entries":20000,"bond_denom":"FX","min_commission_rate":"0.000000000000000000"},"last_total_power":"0","last_validator_powers":[],"validators":[],"delegations":[],"unbonding_delegations":[],"redelegations":[],"exported":false,"allowances":[]},"transfer":{"port_id":"transfer","denom_traces":[],"params":{"send_enabled":true,"receive_enabled":true}},"tron":{"params":{"gravity_id":"fx-tron-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"3000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"upgrade":{},"vesting":{}}` + const genesisData = `{"arbitrum":{"params":{"gravity_id":"fx-arbitrum-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"500","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"auth":{"params":{"max_memo_characters":"256","tx_sig_limit":"7","tx_size_cost_per_byte":"10","sig_verify_cost_ed25519":"590","sig_verify_cost_secp256k1":"1000"},"accounts":[]},"authz":{"authorization":[]},"avalanche":{"params":{"gravity_id":"fx-avalanche-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"2000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"bank":{"params":{"send_enabled":[],"default_send_enabled":true},"balances":[{"address":"cosmos1c602zv38ht8xu8u2qcmymyl55mcyvvjrzq9ur3","coins":[{"denom":"FX","amount":"378600525462891000000000000"}]}],"supply":[{"denom":"FX","amount":"378604525462891000000000000"}],"denom_metadata":[{"description":"The native staking token of the Function X","denom_units":[{"denom":"FX","exponent":0,"aliases":[]}],"base":"FX","display":"FX","name":"Function X","symbol":"FX","uri":"","uri_hash":""}]},"bsc":{"params":{"gravity_id":"fx-bsc-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"3000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"capability":{"index":"1","owners":[]},"crisis":{"constant_fee":{"denom":"FX","amount":"13333000000000000000000"}},"distribution":{"params":{"community_tax":"0.400000000000000000","base_proposer_reward":"0.010000000000000000","bonus_proposer_reward":"0.040000000000000000","withdraw_addr_enabled":true},"fee_pool":{"community_pool":[]},"delegator_withdraw_infos":[],"previous_proposer":"","outstanding_rewards":[],"validator_accumulated_commissions":[],"validator_historical_rewards":[],"validator_current_rewards":[],"delegator_starting_infos":[],"validator_slash_events":[]},"erc20":{"params":{"enable_erc20":true,"enable_evm_hook":true,"ibc_timeout":"43200s"},"token_pairs":[]},"eth":{"params":{"gravity_id":"fx-bridge-eth","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"15000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"evidence":{"evidence":[]},"evm":{"accounts":[],"params":{"evm_denom":"FX","enable_create":true,"enable_call":true,"extra_eips":[],"chain_config":{"homestead_block":"0","dao_fork_block":"0","dao_fork_support":true,"eip150_block":"0","eip150_hash":"0x0000000000000000000000000000000000000000000000000000000000000000","eip155_block":"0","eip158_block":"0","byzantium_block":"0","constantinople_block":"0","petersburg_block":"0","istanbul_block":"0","muir_glacier_block":"0","berlin_block":"0","london_block":"0","arrow_glacier_block":"0","gray_glacier_block":"0","merge_netsplit_block":"0","shanghai_block":"0","cancun_block":"0"},"allow_unprotected_txs":false}},"feegrant":{"allowances":[]},"feemarket":{"params":{"no_base_fee":false,"base_fee_change_denominator":8,"elasticity_multiplier":2,"enable_height":"0","base_fee":"500000000000","min_gas_price":"500000000000.000000000000000000","min_gas_multiplier":"0.000000000000000000"},"block_gas":"0"},"fxtransfer":{},"genutil":{"gen_txs":[]},"gov":{"starting_proposal_id":"1","deposits":[],"votes":[],"proposals":[],"deposit_params":{"min_deposit":[{"denom":"FX","amount":"10000000000000000000000"}],"max_deposit_period":"1209600s"},"voting_params":{"voting_period":"1209600s"},"tally_params":{"quorum":"0.400000000000000000","threshold":"0.500000000000000000","veto_threshold":"0.334000000000000000"}},"ibc":{"client_genesis":{"clients":[],"clients_consensus":[],"clients_metadata":[],"params":{"allowed_clients":["07-tendermint"]},"create_localhost":false,"next_client_sequence":"0"},"connection_genesis":{"connections":[],"client_connection_paths":[],"next_connection_sequence":"0","params":{"max_expected_time_per_block":"30000000000"}},"channel_genesis":{"channels":[],"acknowledgements":[],"commitments":[],"receipts":[],"send_sequences":[],"recv_sequences":[],"ack_sequences":[],"next_channel_sequence":"0"}},"layer2":{"params":{"gravity_id":"fx-layer2-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"2000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"migrate":{},"mint":{"minter":{"inflation":"0.350000000000000000","annual_provisions":"0.000000000000000000"},"params":{"mint_denom":"FX","inflation_rate_change":"0.300000000000000000","inflation_max":"0.416762000000000000","inflation_min":"0.170000000000000000","goal_bonded":"0.510000000000000000","blocks_per_year":"6311520"}},"optimism":{"params":{"gravity_id":"fx-optimism-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"500","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"params":{},"polygon":{"params":{"gravity_id":"fx-polygon-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"2000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"slashing":{"params":{"signed_blocks_window":"20000","min_signed_per_window":"0.050000000000000000","downtime_jail_duration":"600s","slash_fraction_double_sign":"0.050000000000000000","slash_fraction_downtime":"0.001000000000000000"},"signing_infos":[],"missed_blocks":[]},"staking":{"params":{"unbonding_time":"1814400s","max_validators":20,"max_entries":7,"historical_entries":20000,"bond_denom":"FX","min_commission_rate":"0.000000000000000000"},"last_total_power":"0","last_validator_powers":[],"validators":[],"delegations":[],"unbonding_delegations":[],"redelegations":[],"exported":false,"allowances":[]},"transfer":{"port_id":"transfer","denom_traces":[],"params":{"send_enabled":true,"receive_enabled":true}},"tron":{"params":{"gravity_id":"fx-tron-bridge","average_block_time":"7000","external_batch_timeout":"43200000","average_external_block_time":"3000","signed_window":"30000","slash_fraction":"0.800000000000000000","oracle_set_update_power_change_percent":"0.100000000000000000","ibc_transfer_timeout_height":"20000","oracles":[],"delegate_threshold":{"denom":"FX","amount":"10000000000000000000000"},"delegate_multiple":"10"},"last_observed_event_nonce":"0","last_observed_block_height":{"external_block_height":"0","block_height":"0"},"oracles":[],"oracle_sets":[],"bridge_tokens":[],"unbatched_transfers":[],"batches":[],"oracle_set_confirms":[],"batch_confirms":[],"attestations":[],"proposal_oracle":{"oracles":[]},"last_observed_oracle_set":{"nonce":"0","members":[],"height":"0"},"last_slashed_batch_block":"0","last_slashed_oracle_set_nonce":"0"},"upgrade":{},"vesting":{}}` encodingConfig := app.MakeEncodingConfig() genAppState := app.NewDefAppGenesisByDenom(fxtypes.DefaultDenom, encodingConfig.Codec) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index ec640feb6..760a85a84 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -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" @@ -90,6 +91,7 @@ type CrossChainKeepers struct { TronKeeper tronkeeper.Keeper ArbitrumKeeper crosschainkeeper.Keeper OptimismKeeper crosschainkeeper.Keeper + Layer2Keeper crosschainkeeper.Keeper } type AppKeepers struct { @@ -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, @@ -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) @@ -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) diff --git a/app/keepers/keepers_test.go b/app/keepers/keepers_test.go index a00f1bc5e..77aefe9fb 100644 --- a/app/keepers/keepers_test.go +++ b/app/keepers/keepers_test.go @@ -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" @@ -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}, } diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 2aa9832b2..9cd3422ae 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -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" @@ -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, ) @@ -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, diff --git a/app/modules.go b/app/modules.go index 1a3983347..626c278e5 100644 --- a/app/modules.go +++ b/app/modules.go @@ -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" @@ -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 @@ -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}, } @@ -145,6 +149,7 @@ var ModuleBasics = module.NewBasicManager( tron.AppModuleBasic{}, arbitrum.AppModule{}, optimism.AppModule{}, + layer2.AppModule{}, fxevm.AppModuleBasic{}, feemarket.AppModuleBasic{}, erc20.AppModuleBasic{}, @@ -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)), @@ -223,6 +229,7 @@ func orderBeginBlockers() []string { ethtypes.ModuleName, arbitrumtypes.ModuleName, optimismtypes.ModuleName, + layer2types.ModuleName, feemarkettypes.ModuleName, // begin evmtypes.ModuleName, // begin @@ -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 @@ -299,6 +307,7 @@ func orderInitBlockers() []string { ethtypes.ModuleName, arbitrumtypes.ModuleName, optimismtypes.ModuleName, + layer2types.ModuleName, feemarkettypes.ModuleName, evmtypes.ModuleName, diff --git a/app/upgrades/v6/constants.go b/app/upgrades/v6/constants.go index e5f440987..20e361392 100644 --- a/app/upgrades/v6/constants.go +++ b/app/upgrades/v6/constants.go @@ -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}, + } }, } diff --git a/x/layer2/client/cli/query.go b/x/layer2/client/cli/query.go new file mode 100644 index 000000000..78a35977b --- /dev/null +++ b/x/layer2/client/cli/query.go @@ -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 +} diff --git a/x/layer2/client/cli/tx.go b/x/layer2/client/cli/tx.go new file mode 100644 index 000000000..06619c0a7 --- /dev/null +++ b/x/layer2/client/cli/tx.go @@ -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 +} diff --git a/x/layer2/module.go b/x/layer2/module.go new file mode 100644 index 000000000..d1a049cf1 --- /dev/null +++ b/x/layer2/module.go @@ -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{} +} diff --git a/x/layer2/types/genesis.go b/x/layer2/types/genesis.go new file mode 100644 index 000000000..a900c7dd3 --- /dev/null +++ b/x/layer2/types/genesis.go @@ -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, + } +} diff --git a/x/layer2/types/genesis_test.go b/x/layer2/types/genesis_test.go new file mode 100644 index 000000000..3cfab1d94 --- /dev/null +++ b/x/layer2/types/genesis_test.go @@ -0,0 +1,44 @@ +package types + +import ( + "reflect" + "testing" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + fxtypes "github.com/functionx/fx-core/v6/types" + crosschaintypes "github.com/functionx/fx-core/v6/x/crosschain/types" +) + +func TestDefaultGenesisState(t *testing.T) { + tests := []struct { + name string + want *crosschaintypes.GenesisState + }{ + { + name: "layer2 default genesis", + want: &crosschaintypes.GenesisState{ + Params: crosschaintypes.Params{ + GravityId: "fx-layer2-bridge", + AverageBlockTime: 7_000, + AverageExternalBlockTime: 2_000, + ExternalBatchTimeout: 12 * 3600 * 1000, + SignedWindow: 30_000, + SlashFraction: sdk.NewDec(8).Quo(sdk.NewDec(10)), + OracleSetUpdatePowerChangePercent: sdk.NewDec(1).Quo(sdk.NewDec(10)), + IbcTransferTimeoutHeight: 20_000, + DelegateThreshold: sdk.NewCoin(fxtypes.DefaultDenom, sdkmath.NewInt(10_000).MulRaw(1e18)), + DelegateMultiple: 10, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := DefaultGenesisState(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("DefaultGenesisState() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/x/layer2/types/key.go b/x/layer2/types/key.go new file mode 100644 index 000000000..2d32ea032 --- /dev/null +++ b/x/layer2/types/key.go @@ -0,0 +1,9 @@ +package types + +const ( + // ModuleName is the name of the module + ModuleName = "layer2" + + // StoreKey to be used when creating the KVStore + StoreKey = ModuleName +)