@@ -21,9 +21,9 @@ import (
2121 "github.com/cometbft/cometbft/node"
2222 "github.com/cometbft/cometbft/p2p"
2323 pvm "github.com/cometbft/cometbft/privval"
24+ cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
2425 "github.com/cometbft/cometbft/proxy"
2526 "github.com/cometbft/cometbft/rpc/client/local"
26- cmttypes "github.com/cometbft/cometbft/types"
2727 db "github.com/cosmos/cosmos-db"
2828 "github.com/cosmos/cosmos-sdk/client"
2929 "github.com/cosmos/cosmos-sdk/codec"
@@ -75,14 +75,14 @@ type Multiplexer struct {
7575 chainHandlers map [string ]* ChainHandler
7676 // rejectedConsumerChains tracks consumer chains that rejected the current proposal
7777 rejectedConsumerChains map [string ]bool
78- // initializedChains tracks which chains have had InitChain called
79- initializedChains map [string ]bool
78+ // initializedConsumerChains tracks which consumer chains have had InitChain called
79+ initializedConsumerChains map [string ]bool
8080 // activeChains tracks the list of active chains from the provider module
8181 activeChains map [string ]bool
82- // genesisValidators stores the initial validators from InitChain for use with dynamic consumer chains
83- genesisValidators []abci.ValidatorUpdate
84- // genesisConsensusParams stores the initial consensus params from InitChain for use with dynamic consumer chains
85- genesisConsensusParams * cmttypes .ConsensusParams
82+ // providerValidators stores the validators from the provider's InitChain response for use with consumer chains
83+ providerValidators []abci.ValidatorUpdate
84+ // providerConsensusParams stores the initial consensus params from the provider's InitChain for use with consumer chains
85+ providerConsensusParams * cmtproto .ConsensusParams
8686 // cmNode is the comet node which has been created (of the provider chain).
8787 cmNode * node.Node
8888 // ctx is the context which is passed to the comet, grpc and api server starting functions.
@@ -112,16 +112,16 @@ func NewMultiplexer(
112112 }
113113
114114 mp := & Multiplexer {
115- svrCtx : svrCtx ,
116- svrCfg : svrCfg ,
117- clientContext : clientCtx ,
118- providerCreator : providerCreator ,
119- logger : logger ,
120- chainHandlers : make (map [string ]* ChainHandler , len (chainConfig .Chains )),
121- rejectedConsumerChains : make (map [string ]bool ),
122- initializedChains : make (map [string ]bool ),
123- activeChains : make (map [string ]bool ),
124- chainConfig : chainConfig ,
115+ svrCtx : svrCtx ,
116+ svrCfg : svrCfg ,
117+ clientContext : clientCtx ,
118+ providerCreator : providerCreator ,
119+ logger : logger ,
120+ chainHandlers : make (map [string ]* ChainHandler , len (chainConfig .Chains )),
121+ rejectedConsumerChains : make (map [string ]bool ),
122+ initializedConsumerChains : make (map [string ]bool ),
123+ activeChains : make (map [string ]bool ),
124+ chainConfig : chainConfig ,
125125 }
126126
127127 return mp , nil
@@ -191,26 +191,34 @@ func (m *Multiplexer) startNativeProvider() error {
191191
192192// loadGenesisValues loads validators and consensus params from the genesis document.
193193func (m * Multiplexer ) loadGenesisValues () error {
194+ // skip fetching if we have data
195+ if len (m .providerValidators ) != 0 && m .providerConsensusParams != nil {
196+ return nil
197+ }
198+
194199 genDocProvider := GetGenDocProvider (m .svrCtx .Config )
195200 genDoc , err := genDocProvider ()
196201 if err != nil {
197202 return fmt .Errorf ("failed to load genesis doc: %w" , err )
198203 }
199204
200- // Convert genesis validators to ABCI validator updates
201- m .genesisValidators = make ([]abci.ValidatorUpdate , 0 , len (genDoc .Validators ))
205+ // Convert genesis validators to ABCI validator updates as fallback
206+ // These will be overwritten by the provider's InitChain response validators
207+ m .providerValidators = make ([]abci.ValidatorUpdate , 0 , len (genDoc .Validators ))
202208 for _ , val := range genDoc .Validators {
203209 pubKey , err := encoding .PubKeyToProto (val .PubKey )
204210 if err != nil {
205211 return fmt .Errorf ("failed to convert validator pubkey: %w" , err )
206212 }
207- m .genesisValidators = append (m .genesisValidators , abci.ValidatorUpdate {
213+ m .providerValidators = append (m .providerValidators , abci.ValidatorUpdate {
208214 PubKey : pubKey ,
209215 Power : val .Power ,
210216 })
211217 }
212218
213- m .genesisConsensusParams = genDoc .ConsensusParams
219+ consensusParams := genDoc .ConsensusParams .ToProto ()
220+ m .providerConsensusParams = & consensusParams
221+
214222 return nil
215223}
216224
@@ -531,57 +539,48 @@ func (m *Multiplexer) validateActiveChains() {
531539
532540// initChainIfNeeded initializes a chain if it hasn't been initialized yet.
533541// Checks chain state via Info to detect already-initialized chains after restart.
534- func (m * Multiplexer ) initChainIfNeeded (chainID string , height int64 , blockTime time.Time ) error {
535- if m .initializedChains [chainID ] {
536- return nil
542+ func (m * Multiplexer ) initChainIfNeeded (chainID string , height int64 , blockTime time.Time ) ([] byte , error ) {
543+ if m .initializedConsumerChains [chainID ] {
544+ return nil , nil
537545 }
538546
539547 handler , exists := m .chainHandlers [chainID ]
540548 if ! exists {
541- return fmt .Errorf ("chain handler not found for chain_id: %s" , chainID )
549+ return nil , fmt .Errorf ("chain handler not found for chain_id: %s" , chainID )
542550 }
543551
544552 // Check if chain has state (already initialized)
545553 infoResp , err := handler .app .Info (& abci.RequestInfo {})
546554 if err == nil && (infoResp .LastBlockHeight > 0 || len (infoResp .LastBlockAppHash ) > 0 ) {
547555 m .logger .Info ("Chain already initialized" , "chain_id" , chainID , "height" , infoResp .LastBlockHeight )
548- m .initializedChains [chainID ] = true
549- return nil
556+ m .initializedConsumerChains [chainID ] = true
557+ return nil , nil
550558 }
551559
552560 m .logger .Info ("Initializing new consumer chain" , "chain_id" , chainID , "height" , height )
553561
554- // Use stored genesis values, falling back to defaults if not available
555- consensusParams := m .genesisConsensusParams
556- if consensusParams == nil {
557- consensusParams = cmttypes .DefaultConsensusParams ()
558- }
559-
560562 // Load consumer chain's own genesis state from its home directory
561563 appState , err := handler .config .LoadGenesisAppState ()
562564 if err != nil {
563- return fmt .Errorf ("failed to load genesis for chain %s: %w" , chainID , err )
565+ return nil , fmt .Errorf ("failed to load genesis for chain %s: %w" , chainID , err )
564566 }
565567
566- protoConsensusParams := consensusParams .ToProto ()
567568 initReq := & abci.RequestInitChain {
568569 Time : blockTime ,
569570 ChainId : chainID ,
570- ConsensusParams : & protoConsensusParams ,
571- Validators : m .genesisValidators ,
571+ ConsensusParams : m . providerConsensusParams ,
572+ Validators : m .providerValidators ,
572573 AppStateBytes : appState ,
573574 InitialHeight : height ,
574575 }
575576
576- _ , err = handler .app .InitChain (initReq )
577+ resp , err : = handler .app .InitChain (initReq )
577578 if err != nil {
578- return fmt .Errorf ("failed to initialize chain %s: %w" , chainID , err )
579+ return nil , fmt .Errorf ("failed to initialize chain %s: %w" , chainID , err )
579580 }
581+ m .initializedConsumerChains [chainID ] = true
580582
581- m .initializedChains [chainID ] = true
582- m .logger .Info ("Successfully initialized consumer chain" , "chain_id" , chainID )
583-
584- return nil
583+ return resp .AppHash , nil
585584}
586585
587586// updateActiveChains updates the list of active chains from the provider module
0 commit comments