Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: testnetify halt height edge case (backport #521) #522

Merged
merged 1 commit into from
Feb 9, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 39 additions & 12 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -734,18 +734,51 @@ func testnetify(ctx *Context, home string, testnetAppCreator types.AppCreator, d
return nil, err
}

// There are times when a user stops their node between commits, resulting in a mismatch between the
// blockStore and state. For convenience, we just discard the uncommitted blockStore block and operate on
// the lastBlockHeight in state.
if blockStore.Height() != state.LastBlockHeight {
ctx.Viper.Set(KeyNewValAddr, validatorAddress)
ctx.Viper.Set(KeyUserPubKey, userPubKey)
testnetApp := testnetAppCreator(ctx.Logger, db, traceWriter, ctx.Viper)

// We need to create a temporary proxyApp to get the initial state of the application.
// Depending on how the node was stopped, the application height can differ from the blockStore height.
// This height difference changes how we go about modifying the state.
clientCreator := proxy.NewLocalClientCreator(testnetApp)
metrics := node.DefaultMetricsProvider(config.Instrumentation)
_, _, _, _, proxyMetrics := metrics(genDoc.ChainID) //nolint:dogsled
proxyApp := proxy.NewAppConns(clientCreator, proxyMetrics)
if err := proxyApp.Start(); err != nil {
return nil, fmt.Errorf("error starting proxy app connections: %v", err)
}
res, err := proxyApp.Query().InfoSync(proxy.RequestInfo)
if err != nil {
return nil, fmt.Errorf("error calling Info: %v", err)
}
err = proxyApp.Stop()
if err != nil {
return nil, err
}
appHash := res.LastBlockAppHash
appHeight := res.LastBlockHeight

var block *cmttypes.Block
switch {
case appHeight == blockStore.Height():
// This state occurs when we stop the node with the halt height flag, and need to handle differently
state.LastBlockHeight++
block = blockStore.LoadBlock(blockStore.Height())
block.AppHash = appHash
state.AppHash = appHash
case blockStore.Height() > state.LastBlockHeight:
// This state occurs when we kill the node
err = blockStore.DeleteLatestBlock()
if err != nil {
return nil, err
}
block = blockStore.LoadBlock(blockStore.Height())
default:
// If there is any other state, we just load the block
block = blockStore.LoadBlock(blockStore.Height())
}

block := blockStore.LoadBlock(blockStore.Height())

block.ChainID = newChainID
state.ChainID = newChainID

Expand Down Expand Up @@ -853,12 +886,6 @@ func testnetify(ctx *Context, home string, testnetAppCreator types.AppCreator, d
return nil, err
}

// testnetAppCreator makes any application side changes that must be made due to the above modifications.
// Also, it makes any optional application side changes to make running the testnet easier (voting times, fund accounts, etc).
ctx.Viper.Set(KeyNewValAddr, validatorAddress)
ctx.Viper.Set(KeyUserPubKey, userPubKey)
testnetApp := testnetAppCreator(ctx.Logger, db, traceWriter, ctx.Viper)

return testnetApp, err
}

Expand Down
Loading