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: mocha block sync on v2.x #3843

Merged
merged 11 commits into from
Sep 16, 2024
Merged
56 changes: 41 additions & 15 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,17 +541,8 @@ func (app *App) Info(req abci.RequestInfo) abci.ResponseInfo {
//
// Side-effect: calls baseapp.Init()
func (app *App) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) {
// genesis must always contain the consensus params. The validator set however is derived from the
// initial genesis state. The genesis must always contain a non zero app version which is the initial
// version that the chain starts on
if req.ConsensusParams == nil || req.ConsensusParams.Version == nil {
panic("no consensus params set")
}
if req.ConsensusParams.Version.AppVersion == 0 {
panic("app version 0 is not accepted. Please set an app version in the genesis")
}
appVersion := req.ConsensusParams.Version.AppVersion

req = setMochaAppVersion(req)
appVersion := extractAppVersion(req)
// mount the stores for the provided app version if it has not already been mounted
if app.AppVersion() == 0 && !app.IsSealed() {
app.mountKeysAndInit(appVersion)
Expand All @@ -567,10 +558,45 @@ func (app *App) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain
return res
}

// setMochaAppVersion sets the app version to v1 if the chain ID is mocha-4.
// This is necessary because the mocha-4 genesis file doesn't populate an app
// version.
func setMochaAppVersion(req abci.RequestInitChain) abci.RequestInitChain {
if req.ChainId != "mocha-4" {
// if the chain id is not mocha-4, return the request as is
return req
}
if req.ConsensusParams == nil {
panic("no consensus params set")
}
if req.ConsensusParams.Version == nil {
panic("no version set in consensus params")
}
req.ConsensusParams.Version.AppVersion = v1
return req
}

// extractAppVersion extracts the app version from the provided init chain
// request. It panics if the app version is not present.
func extractAppVersion(req abci.RequestInitChain) uint64 {
if req.ConsensusParams == nil {
panic("no consensus params set")
}
if req.ConsensusParams.Version == nil {
panic("no version set in consensus params")
}
// The genesis must always contain a non zero app version which is the initial
// version that the chain starts on.
if req.ConsensusParams.Version.AppVersion == 0 {
panic("app version 0 is not accepted. Please set an app version in the genesis")
}
return req.ConsensusParams.Version.AppVersion
}

// mountKeysAndInit mounts the keys for the provided app version and then
// invokes baseapp.Init().
func (app *App) mountKeysAndInit(appVersion uint64) {
app.BaseApp.Logger().Debug(fmt.Sprintf("mounting KV stores for app version %v", appVersion))
app.BaseApp.Logger().Info(fmt.Sprintf("mounting KV stores for app version %v", appVersion))
app.MountKVStores(app.versionedKeys(appVersion))

// Invoke load latest version for it's side-effect of invoking baseapp.Init()
Expand All @@ -585,9 +611,9 @@ func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.Res
if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
}

app.UpgradeKeeper.SetModuleVersionMap(ctx, app.manager.GetVersionMap(req.ConsensusParams.Version.AppVersion))
return app.manager.InitGenesis(ctx, app.appCodec, genesisState, req.ConsensusParams.Version.AppVersion)
appVersion := extractAppVersion(req)
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.manager.GetVersionMap(appVersion))
return app.manager.InitGenesis(ctx, app.appCodec, genesisState, appVersion)
}

// LoadHeight loads a particular height
Expand Down
72 changes: 72 additions & 0 deletions app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmprototypes "github.com/tendermint/tendermint/proto/tendermint/types"
coretypes "github.com/tendermint/tendermint/types"
tmdb "github.com/tendermint/tm-db"
)

Expand Down Expand Up @@ -52,6 +54,76 @@ func TestNew(t *testing.T) {
})
}

func TestInitChain(t *testing.T) {
logger := log.NewNopLogger()
db := tmdb.NewMemDB()
traceStore := &NoopWriter{}
invCheckPeriod := uint(1)
encodingConfig := encoding.MakeConfig(app.ModuleEncodingRegisters...)
upgradeHeight := int64(0)
appOptions := NoopAppOptions{}

type testCase struct {
name string
request abci.RequestInitChain
wantPanic bool
}
testCases := []testCase{
{
name: "should panic if consensus params not set",
request: abci.RequestInitChain{},
wantPanic: true,
},
{
name: "should not panic on Mocha genesis.json",
request: getGenesis(t, "testdata/mocha-genesis.json"),
wantPanic: false,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
application := app.New(logger, db, traceStore, invCheckPeriod, encodingConfig, upgradeHeight, appOptions)
if tc.wantPanic {
assert.Panics(t, func() { application.InitChain(tc.request) })
} else {
assert.NotPanics(t, func() { application.InitChain(tc.request) })
}
})
}

}

func getGenesis(t *testing.T, filename string) abci.RequestInitChain {
doc, err := coretypes.GenesisDocFromFile(filename)
require.NoError(t, err)

return abci.RequestInitChain{
Time: doc.GenesisTime,
ChainId: doc.ChainID,
InitialHeight: doc.InitialHeight,
Validators: []abci.ValidatorUpdate{},
ConsensusParams: &abci.ConsensusParams{
Block: &abci.BlockParams{
MaxBytes: doc.ConsensusParams.Block.MaxBytes,
MaxGas: doc.ConsensusParams.Block.MaxGas,
},
Evidence: &tmprototypes.EvidenceParams{
MaxAgeNumBlocks: doc.ConsensusParams.Evidence.MaxAgeNumBlocks,
MaxAgeDuration: doc.ConsensusParams.Evidence.MaxAgeDuration,
MaxBytes: doc.ConsensusParams.Evidence.MaxBytes,
},
Validator: &tmprototypes.ValidatorParams{
PubKeyTypes: doc.ConsensusParams.Validator.PubKeyTypes,
},
Version: &tmprototypes.VersionParams{
AppVersion: doc.ConsensusParams.Version.AppVersion,
},
},
AppStateBytes: doc.AppState,
}
}

func TestOfferSnapshot(t *testing.T) {
logger := log.NewNopLogger()
db := tmdb.NewMemDB()
Expand Down
Loading
Loading