Skip to content

Commit 2428040

Browse files
committed
inherit proposer valset
1 parent b799cb4 commit 2428040

2 files changed

Lines changed: 67 additions & 73 deletions

File tree

abci/abci.go

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func (m *Multiplexer) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*a
5151
return &abci.ResponseCheckTx{Code: 1, Log: fmt.Sprintf("unknown chain: %s", chainID)}, nil
5252
}
5353

54-
if !m.initializedChains[chainID] {
54+
if !m.initializedConsumerChains[chainID] {
5555
return &abci.ResponseCheckTx{Code: 1, Log: fmt.Sprintf("chain not initialized: %s", chainID)}, nil
5656
}
5757

@@ -61,28 +61,37 @@ func (m *Multiplexer) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*a
6161
func (m *Multiplexer) InitChain(ctx context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
6262
m.logger.Debug("InitChain", "chain_id", req.ChainId)
6363

64+
providerResp, err := m.providerChain.InitChain(req)
65+
if err != nil {
66+
return nil, err
67+
}
68+
69+
m.providerValidators = providerResp.Validators
70+
m.providerConsensusParams = providerResp.ConsensusParams
71+
72+
response := &abci.ResponseInitChain{
73+
ConsensusParams: providerResp.ConsensusParams,
74+
Validators: providerResp.Validators,
75+
}
76+
77+
chainHashes := make(map[string][]byte)
78+
chainHashes[m.providerChainID] = providerResp.AppHash
79+
6480
type result struct {
6581
chainID string
6682
response *abci.ResponseInitChain
6783
err error
6884
}
6985

70-
// Include provider chain in the count
71-
numChains := len(m.chainHandlers) + 1
72-
results := make(chan result, numChains)
86+
results := make(chan result, len(m.chainHandlers))
7387
var wg sync.WaitGroup
7488

75-
// Call provider chain first
76-
wg.Go(func() {
77-
resp, err := m.providerChain.InitChain(req)
78-
results <- result{chainID: req.ChainId, response: resp, err: err}
79-
})
80-
81-
// Then call consumer chains
8289
for chainID, handler := range m.chainHandlers {
8390
wg.Go(func() {
8491
consumerReq := *req
8592
consumerReq.ChainId = chainID
93+
consumerReq.Validators = m.providerValidators
94+
consumerReq.ConsensusParams = m.providerConsensusParams
8695

8796
// Load consumer chain's own genesis state from its home directory
8897
appState, err := handler.config.LoadGenesisAppState()
@@ -103,28 +112,14 @@ func (m *Multiplexer) InitChain(ctx context.Context, req *abci.RequestInitChain)
103112
close(results)
104113
}()
105114

106-
response := &abci.ResponseInitChain{}
107-
chainHashes := make(map[string][]byte)
108-
109115
for res := range results {
110116
if res.err != nil {
111-
if res.chainID == m.providerChainID {
112-
return nil, res.err
113-
}
114-
m.logger.Error("InitChain failed for consumer chain, skipping",
115-
"chain_id", res.chainID, "error", res.err)
117+
m.logger.Error("InitChain failed for consumer chain, skipping", "chain_id", res.chainID, "error", res.err)
116118
continue
117119
}
118120

119121
chainHashes[res.chainID] = res.response.AppHash
120-
121-
m.initializedChains[res.chainID] = true
122-
123-
// Only use ConsensusParams and Validators from provider chain
124-
if res.chainID == m.providerChainID {
125-
response.ConsensusParams = res.response.ConsensusParams
126-
response.Validators = append(response.Validators, res.response.Validators...)
127-
}
122+
m.initializedConsumerChains[res.chainID] = true
128123
}
129124

130125
// Combine app hashes in sorted order by chain ID
@@ -163,7 +158,7 @@ func (m *Multiplexer) ProcessProposal(ctx context.Context, req *abci.RequestProc
163158
m.logger.Debug("Transaction for unexisting chain in proposal, skipping...", "chain_id", chainID)
164159
continue
165160
}
166-
if !m.initializedChains[chainID] {
161+
if !m.initializedConsumerChains[chainID] {
167162
m.logger.Debug("Transaction for uninitialized chain in proposal, skipping...", "chain_id", chainID)
168163
continue
169164
}
@@ -323,7 +318,7 @@ func (m *Multiplexer) FinalizeBlock(ctx context.Context, req *abci.RequestFinali
323318

324319
// Initialize any new active chains
325320
for chainID := range m.activeChains {
326-
if err := m.initChainIfNeeded(chainID, req.Height, req.Time); err != nil {
321+
if _, err := m.initChainIfNeeded(chainID, req.Height, req.Time); err != nil {
327322
m.logger.Error("Failed to initialize chain", "chain_id", chainID, "error", err)
328323
}
329324
}
@@ -421,7 +416,7 @@ func (m *Multiplexer) Commit(ctx context.Context, req *abci.RequestCommit) (*abc
421416

422417
for chainID, handler := range m.chainHandlers {
423418
// Only commit if the chain has been initialized
424-
if !m.initializedChains[chainID] {
419+
if !m.initializedConsumerChains[chainID] {
425420
m.logger.Debug("Skipping Commit for uninitialized chain", "chain_id", chainID)
426421
continue
427422
}

abci/multiplexer.go

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
193193
func (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

Comments
 (0)