11package app
22
33import (
4+ "encoding/json"
45 "os"
56
6- "github.com/cosmos/ethermint/x/evm"
7-
87 bam "github.com/cosmos/cosmos-sdk/baseapp"
98 "github.com/cosmos/cosmos-sdk/codec"
109 sdk "github.com/cosmos/cosmos-sdk/types"
1110 "github.com/cosmos/cosmos-sdk/types/module"
11+ "github.com/cosmos/cosmos-sdk/version"
1212 "github.com/cosmos/cosmos-sdk/x/auth"
1313 "github.com/cosmos/cosmos-sdk/x/bank"
14+ "github.com/cosmos/cosmos-sdk/x/crisis"
1415 distr "github.com/cosmos/cosmos-sdk/x/distribution"
16+ distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client"
1517 "github.com/cosmos/cosmos-sdk/x/genaccounts"
1618 "github.com/cosmos/cosmos-sdk/x/genutil"
1719 "github.com/cosmos/cosmos-sdk/x/gov"
1820 "github.com/cosmos/cosmos-sdk/x/mint"
1921 "github.com/cosmos/cosmos-sdk/x/params"
22+ paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
2023 "github.com/cosmos/cosmos-sdk/x/slashing"
2124 "github.com/cosmos/cosmos-sdk/x/staking"
2225 "github.com/cosmos/cosmos-sdk/x/supply"
2326
2427 "github.com/cosmos/ethermint/crypto"
2528 evmtypes "github.com/cosmos/ethermint/x/evm/types"
2629
27- "github.com/pkg/errors"
28-
2930 abci "github.com/tendermint/tendermint/abci/types"
30- tmcmn "github.com/tendermint/tendermint/libs/common"
3131 dbm "github.com/tendermint/tendermint/libs/db"
3232 tmlog "github.com/tendermint/tendermint/libs/log"
33+ tmtypes "github.com/tendermint/tendermint/types"
3334)
3435
3536const appName = "Ethermint"
3637
37- // application multi-store keys
3838var (
3939 // default home directories for the application CLI
4040 DefaultCLIHome = os .ExpandEnv ("$HOME/.emintcli" )
4141
4242 // DefaultNodeHome sets the folder where the applcation data and configuration will be stored
4343 DefaultNodeHome = os .ExpandEnv ("$HOME/.emintd" )
4444
45- // ModuleBasics is in charge of setting up basic module elements
45+ // The module BasicManager is in charge of setting up basic,
46+ // non-dependant module elements, such as codec registration
47+ // and genesis verification.
4648 ModuleBasics = module .NewBasicManager (
4749 genaccounts.AppModuleBasic {},
4850 genutil.AppModuleBasic {},
4951 auth.AppModuleBasic {},
5052 bank.AppModuleBasic {},
51- params.AppModuleBasic {},
52- evm.AppModuleBasic {},
5353 staking.AppModuleBasic {},
54+ mint.AppModuleBasic {},
5455 distr.AppModuleBasic {},
56+ gov .NewAppModuleBasic (paramsclient .ProposalHandler , distrclient .ProposalHandler ),
57+ params.AppModuleBasic {},
58+ crisis.AppModuleBasic {},
5559 slashing.AppModuleBasic {},
60+ supply.AppModuleBasic {},
5661 )
57-
58- storeKeyAccount = sdk .NewKVStoreKey ("acc" )
59- storeKeyStorage = sdk .NewKVStoreKey ("contract_storage" )
60- storeKeyMain = sdk .NewKVStoreKey ("main" )
61- storeKeyStake = sdk .NewKVStoreKey ("stake" )
62- storeKeySlashing = sdk .NewKVStoreKey ("slashing" )
63- storeKeyGov = sdk .NewKVStoreKey ("gov" )
64- storeKeySupply = sdk .NewKVStoreKey ("supply" )
65- storeKeyParams = sdk .NewKVStoreKey ("params" )
66- storeKeyTransParams = sdk .NewTransientStoreKey ("transient_params" )
6762)
6863
6964// MakeCodec generates the necessary codecs for Amino
7065func MakeCodec () * codec.Codec {
7166 var cdc = codec .New ()
67+
68+ // TODO: Move this codec to module (Issue #12 https://github.com/ChainSafe/ethermint/issues/12)
69+ crypto .RegisterCodec (cdc )
70+
7271 ModuleBasics .RegisterCodec (cdc )
7372 sdk .RegisterCodec (cdc )
7473 codec .RegisterCrypto (cdc )
@@ -80,26 +79,40 @@ func MakeCodec() *codec.Codec {
8079// Tendermint consensus.
8180type EthermintApp struct {
8281 * bam.BaseApp
83-
8482 cdc * codec.Codec
8583
86- accountKey * sdk.KVStoreKey
87- storageKey * sdk.KVStoreKey
88- mainKey * sdk.KVStoreKey
89- stakeKey * sdk.KVStoreKey
90- slashingKey * sdk.KVStoreKey
91- govKey * sdk.KVStoreKey
92- supplyKey * sdk.KVStoreKey
93- paramsKey * sdk.KVStoreKey
94- tParamsKey * sdk.TransientStoreKey
95-
84+ invCheckPeriod uint
85+
86+ // keys to access the substores
87+ keyMain * sdk.KVStoreKey
88+ keyAccount * sdk.KVStoreKey
89+ keySupply * sdk.KVStoreKey
90+ keyStaking * sdk.KVStoreKey
91+ tkeyStaking * sdk.TransientStoreKey
92+ keySlashing * sdk.KVStoreKey
93+ keyMint * sdk.KVStoreKey
94+ keyDistr * sdk.KVStoreKey
95+ tkeyDistr * sdk.TransientStoreKey
96+ keyGov * sdk.KVStoreKey
97+ keyParams * sdk.KVStoreKey
98+ tkeyParams * sdk.TransientStoreKey
99+ // TODO: Add evm module key
100+
101+ // keepers
96102 accountKeeper auth.AccountKeeper
97- supplyKeeper supply.Keeper
98103 bankKeeper bank.Keeper
99- stakeKeeper staking.Keeper
104+ supplyKeeper supply.Keeper
105+ stakingKeeper staking.Keeper
100106 slashingKeeper slashing.Keeper
107+ mintKeeper mint.Keeper
108+ distrKeeper distr.Keeper
101109 govKeeper gov.Keeper
110+ crisisKeeper crisis.Keeper
102111 paramsKeeper params.Keeper
112+ // TODO: Include evm Keeper
113+
114+ // the module manager
115+ mm * module.Manager
103116}
104117
105118// NewEthermintApp returns a reference to a new initialized Ethermint
@@ -108,28 +121,42 @@ type EthermintApp struct {
108121// TODO: Ethermint needs to support being bootstrapped as an application running
109122// in a sovereign zone and as an application running with a shared security model.
110123// For now, it will support only running as a sovereign application.
111- func NewEthermintApp (logger tmlog.Logger , db dbm.DB , baseAppOpts ... func (* bam.BaseApp )) * EthermintApp {
112- cdc := CreateCodec ()
113-
114- baseApp := bam .NewBaseApp (appName , logger , db , evmtypes .TxDecoder (cdc ), baseAppOpts ... )
115- app := & EthermintApp {
116- BaseApp : baseApp ,
117- cdc : cdc ,
118- accountKey : storeKeyAccount ,
119- storageKey : storeKeyStorage ,
120- mainKey : storeKeyMain ,
121- stakeKey : storeKeyStake ,
122- slashingKey : storeKeySlashing ,
123- govKey : storeKeyGov ,
124- supplyKey : storeKeySupply ,
125- paramsKey : storeKeyParams ,
126- tParamsKey : storeKeyTransParams ,
124+ func NewEthermintApp (logger tmlog.Logger , db dbm.DB , loadLatest bool ,
125+ invCheckPeriod uint , baseAppOptions ... func (* bam.BaseApp )) * EthermintApp {
126+ cdc := MakeCodec ()
127+
128+ baseApp := bam .NewBaseApp (appName , logger , db , evmtypes .TxDecoder (cdc ), baseAppOptions ... )
129+ baseApp .SetAppVersion (version .Version )
130+
131+ var app = & EthermintApp {
132+ BaseApp : baseApp ,
133+ cdc : cdc ,
134+ invCheckPeriod : invCheckPeriod ,
135+ keyMain : sdk .NewKVStoreKey (bam .MainStoreKey ),
136+ keyAccount : sdk .NewKVStoreKey (auth .StoreKey ),
137+ keyStaking : sdk .NewKVStoreKey (staking .StoreKey ),
138+ keySupply : sdk .NewKVStoreKey (supply .StoreKey ),
139+ tkeyStaking : sdk .NewTransientStoreKey (staking .TStoreKey ),
140+ keyMint : sdk .NewKVStoreKey (mint .StoreKey ),
141+ keyDistr : sdk .NewKVStoreKey (distr .StoreKey ),
142+ tkeyDistr : sdk .NewTransientStoreKey (distr .TStoreKey ),
143+ keySlashing : sdk .NewKVStoreKey (slashing .StoreKey ),
144+ keyGov : sdk .NewKVStoreKey (gov .StoreKey ),
145+ keyParams : sdk .NewKVStoreKey (params .StoreKey ),
146+ tkeyParams : sdk .NewTransientStoreKey (params .TStoreKey ),
147+ // TODO: Initialize evm module key
127148 }
128149
129- // Set params keeper and subspaces
130- app .paramsKeeper = params .NewKeeper (app .cdc , app .paramsKey , app .tParamsKey , params .DefaultCodespace )
150+ // init params keeper and subspaces
151+ app .paramsKeeper = params .NewKeeper (app .cdc , app .keyParams , app .tkeyParams , params .DefaultCodespace )
131152 authSubspace := app .paramsKeeper .Subspace (auth .DefaultParamspace )
132153 bankSubspace := app .paramsKeeper .Subspace (bank .DefaultParamspace )
154+ stakingSubspace := app .paramsKeeper .Subspace (staking .DefaultParamspace )
155+ mintSubspace := app .paramsKeeper .Subspace (mint .DefaultParamspace )
156+ distrSubspace := app .paramsKeeper .Subspace (distr .DefaultParamspace )
157+ slashingSubspace := app .paramsKeeper .Subspace (slashing .DefaultParamspace )
158+ govSubspace := app .paramsKeeper .Subspace (gov .DefaultParamspace )
159+ crisisSubspace := app .paramsKeeper .Subspace (crisis .DefaultParamspace )
133160
134161 // account permissions
135162 maccPerms := map [string ][]string {
@@ -141,88 +168,125 @@ func NewEthermintApp(logger tmlog.Logger, db dbm.DB, baseAppOpts ...func(*bam.Ba
141168 gov .ModuleName : []string {supply .Burner },
142169 }
143170
144- // Add keepers
145- app .accountKeeper = auth .NewAccountKeeper (app .cdc , app .accountKey , authSubspace , auth .ProtoBaseAccount )
171+ // add keepers
172+ app .accountKeeper = auth .NewAccountKeeper (app .cdc , app .keyAccount , authSubspace , auth .ProtoBaseAccount )
146173 app .bankKeeper = bank .NewBaseKeeper (app .accountKeeper , bankSubspace , bank .DefaultCodespace )
147- app .supplyKeeper = supply .NewKeeper (cdc , app .supplyKey , app .accountKeeper , app .bankKeeper , supply .DefaultCodespace , maccPerms )
174+ app .supplyKeeper = supply .NewKeeper (app .cdc , app .keySupply , app .accountKeeper , app .bankKeeper , supply .DefaultCodespace , maccPerms )
175+ stakingKeeper := staking .NewKeeper (app .cdc , app .keyStaking , app .tkeyStaking ,
176+ app .supplyKeeper , stakingSubspace , staking .DefaultCodespace )
177+ app .mintKeeper = mint .NewKeeper (app .cdc , app .keyMint , mintSubspace , & stakingKeeper , app .supplyKeeper , auth .FeeCollectorName )
178+ app .distrKeeper = distr .NewKeeper (app .cdc , app .keyDistr , distrSubspace , & stakingKeeper ,
179+ app .supplyKeeper , distr .DefaultCodespace , auth .FeeCollectorName )
180+ app .slashingKeeper = slashing .NewKeeper (app .cdc , app .keySlashing , & stakingKeeper ,
181+ slashingSubspace , slashing .DefaultCodespace )
182+ app .crisisKeeper = crisis .NewKeeper (crisisSubspace , invCheckPeriod , app .supplyKeeper , auth .FeeCollectorName )
183+ // TODO: Instantiate evm Keeper
184+
185+ // register the proposal types
186+ govRouter := gov .NewRouter ()
187+ govRouter .AddRoute (gov .RouterKey , gov .ProposalHandler ).
188+ AddRoute (params .RouterKey , params .NewParamChangeProposalHandler (app .paramsKeeper )).
189+ AddRoute (distr .RouterKey , distr .NewCommunityPoolSpendProposalHandler (app .distrKeeper ))
190+ app .govKeeper = gov .NewKeeper (app .cdc , app .keyGov , app .paramsKeeper , govSubspace ,
191+ app .supplyKeeper , & stakingKeeper , gov .DefaultCodespace , govRouter )
192+
193+ // register the staking hooks
194+ // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
195+ app .stakingKeeper = * stakingKeeper .SetHooks (
196+ staking .NewMultiStakingHooks (app .distrKeeper .Hooks (), app .slashingKeeper .Hooks ()))
197+
198+ app .mm = module .NewManager (
199+ genaccounts .NewAppModule (app .accountKeeper ),
200+ genutil .NewAppModule (app .accountKeeper , app .stakingKeeper , app .BaseApp .DeliverTx ),
201+ auth .NewAppModule (app .accountKeeper ),
202+ bank .NewAppModule (app .bankKeeper , app .accountKeeper ),
203+ crisis .NewAppModule (app .crisisKeeper ),
204+ supply .NewAppModule (app .supplyKeeper , app .accountKeeper ),
205+ distr .NewAppModule (app .distrKeeper , app .supplyKeeper ),
206+ gov .NewAppModule (app .govKeeper , app .supplyKeeper ),
207+ mint .NewAppModule (app .mintKeeper ),
208+ slashing .NewAppModule (app .slashingKeeper , app .stakingKeeper ),
209+ staking .NewAppModule (app .stakingKeeper , app .distrKeeper , app .accountKeeper , app .supplyKeeper ),
210+ )
211+
212+ // During begin block slashing happens after distr.BeginBlocker so that
213+ // there is nothing left over in the validator fee pool, so as to keep the
214+ // CanWithdrawInvariant invariant.
215+ app .mm .SetOrderBeginBlockers (mint .ModuleName , distr .ModuleName , slashing .ModuleName )
216+
217+ app .mm .SetOrderEndBlockers (gov .ModuleName , staking .ModuleName )
218+
219+ // genutils must occur after staking so that pools are properly
220+ // initialized with tokens from genesis accounts.
221+ app .mm .SetOrderInitGenesis (genaccounts .ModuleName , supply .ModuleName , distr .ModuleName ,
222+ staking .ModuleName , auth .ModuleName , bank .ModuleName , slashing .ModuleName ,
223+ gov .ModuleName , mint .ModuleName , crisis .ModuleName , genutil .ModuleName )
148224
149- // register message handlers
150- app .Router ().
151- // TODO: add remaining routes
152- AddRoute ("stake" , staking .NewHandler (app .stakeKeeper )).
153- AddRoute ("slashing" , slashing .NewHandler (app .slashingKeeper )).
154- AddRoute ("gov" , gov .NewHandler (app .govKeeper ))
225+ app .mm .RegisterInvariants (& app .crisisKeeper )
226+ app .mm .RegisterRoutes (app .Router (), app .QueryRouter ())
155227
156- // initialize the underlying ABCI BaseApp
157- app .SetInitChainer (app .initChainer )
228+ // initialize stores
229+ app .MountStores (app .keyMain , app .keyAccount , app .keySupply , app .keyStaking ,
230+ app .keyMint , app .keyDistr , app .keySlashing , app .keyGov , app .keyParams ,
231+ app .tkeyParams , app .tkeyStaking , app .tkeyDistr )
232+
233+ // initialize BaseApp
234+ app .SetInitChainer (app .InitChainer )
158235 app .SetBeginBlocker (app .BeginBlocker )
236+ app .SetAnteHandler (auth .NewAnteHandler (app .accountKeeper , app .supplyKeeper , auth .DefaultSigVerificationGasConsumer ))
159237 app .SetEndBlocker (app .EndBlocker )
160- app .SetAnteHandler (NewAnteHandler (app .accountKeeper , app .supplyKeeper ))
161-
162- app .MountStores (
163- app .mainKey , app .accountKey , app .stakeKey , app .slashingKey ,
164- app .govKey , app .supplyKey , app .paramsKey , app .storageKey ,
165- )
166- app .MountStore (app .tParamsKey , sdk .StoreTypeTransient )
167238
168- if err := app .LoadLatestVersion (app .accountKey ); err != nil {
169- tmcmn .Exit (err .Error ())
239+ if loadLatest {
240+ err := app .LoadLatestVersion (app .keyMain )
241+ if err != nil {
242+ panic (err )
243+ }
170244 }
171-
172- app .BaseApp .Seal ()
173245 return app
246+
174247}
175248
176- // BeginBlocker signals the beginning of a block. It performs application
177- // updates on the start of every block.
178- func (app * EthermintApp ) BeginBlocker (
179- _ sdk.Context , _ abci.RequestBeginBlock ,
180- ) abci.ResponseBeginBlock {
249+ // The genesis state of the blockchain is represented here as a map of raw json
250+ // messages key'd by a identifier string.
251+ type GenesisState map [string ]json.RawMessage
181252
182- return abci.ResponseBeginBlock {}
253+ // application updates every begin block
254+ func (app * EthermintApp ) BeginBlocker (ctx sdk.Context , req abci.RequestBeginBlock ) abci.ResponseBeginBlock {
255+ return app .mm .BeginBlock (ctx , req )
183256}
184257
185- // EndBlocker signals the end of a block. It performs application updates on
186- // the end of every block.
187- func (app * EthermintApp ) EndBlocker (
188- _ sdk.Context , _ abci.RequestEndBlock ,
189- ) abci.ResponseEndBlock {
258+ // application updates every end block
259+ func (app * EthermintApp ) EndBlocker (ctx sdk.Context , req abci.RequestEndBlock ) abci.ResponseEndBlock {
260+ return app .mm .EndBlock (ctx , req )
261+ }
262+
263+ // application update at chain initialization
264+ func (app * EthermintApp ) InitChainer (ctx sdk.Context , req abci.RequestInitChain ) abci.ResponseInitChain {
265+ var genesisState GenesisState
266+ app .cdc .MustUnmarshalJSON (req .AppStateBytes , & genesisState )
267+ return app .mm .InitGenesis (ctx , genesisState )
268+ }
190269
191- return abci.ResponseEndBlock {}
270+ // load a particular height
271+ func (app * EthermintApp ) LoadHeight (height int64 ) error {
272+ return app .LoadVersion (height , app .keyMain )
192273}
193274
194- // initChainer initializes the application blockchain with validators and other
195- // state data from TendermintCore.
196- func (app * EthermintApp ) initChainer (
197- _ sdk.Context , req abci.RequestInitChain ,
198- ) abci.ResponseInitChain {
275+ // ExportAppStateAndValidators exports the state of the application for a genesis
276+ // file.
277+ func (app * EthermintApp ) ExportAppStateAndValidators (forZeroHeight bool , jailWhiteList []string ,
278+ ) (appState json.RawMessage , validators []tmtypes.GenesisValidator , err error ) {
199279
200- var genesisState evm. GenesisState
201- stateJSON := req . AppStateBytes
280+ // as if they could withdraw from the start of the next block
281+ ctx := app . NewContext ( true , abci. Header { Height : app . LastBlockHeight ()})
202282
203- err := app .cdc .UnmarshalJSON (stateJSON , & genesisState )
283+ genState := app .mm .ExportGenesis (ctx )
284+ appState , err = codec .MarshalJSONIndent (app .cdc , genState )
204285 if err != nil {
205- panic ( errors . Wrap ( err , "failed to parse application genesis state" ))
286+ return nil , nil , err
206287 }
207288
208- // TODO: load the genesis accounts
289+ validators = staking . WriteValidators ( ctx , app . stakingKeeper )
209290
210- return abci.ResponseInitChain {}
211- }
212-
213- // CreateCodec creates a new amino wire codec and registers all the necessary
214- // concrete types and interfaces needed for the application.
215- func CreateCodec () * codec.Codec {
216- cdc := codec .New ()
217-
218- // TODO: Add remaining codec registrations:
219- // bank, staking, distribution, slashing, and gov
220-
221- crypto .RegisterCodec (cdc )
222- evmtypes .RegisterCodec (cdc )
223- auth .RegisterCodec (cdc )
224- sdk .RegisterCodec (cdc )
225- codec .RegisterCrypto (cdc )
226-
227- return cdc
291+ return appState , validators , nil
228292}
0 commit comments