Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com> Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
parent
5d70291fbb
commit
ffb27662e4
|
@ -73,6 +73,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (baseapp) [#14505](https://github.com/cosmos/cosmos-sdk/pull/14505) PrepareProposal and ProcessProposal now use deliverState for the first block in order to access changes made in InitChain.
|
||||||
* (x/group) [#14527](https://github.com/cosmos/cosmos-sdk/pull/14527) Fix wrong address set in `EventUpdateGroupPolicy`.
|
* (x/group) [#14527](https://github.com/cosmos/cosmos-sdk/pull/14527) Fix wrong address set in `EventUpdateGroupPolicy`.
|
||||||
* (cli) [#14509](https://github.com/cosmos/cosmos-sdk/pull/14509) Added missing options to keyring-backend flag usage.
|
* (cli) [#14509](https://github.com/cosmos/cosmos-sdk/pull/14509) Added missing options to keyring-backend flag usage.
|
||||||
* (server) [#14441](https://github.com/cosmos/cosmos-sdk/pull/14441) Fix `--log_format` flag not working.
|
* (server) [#14441](https://github.com/cosmos/cosmos-sdk/pull/14441) Fix `--log_format` flag not working.
|
||||||
|
|
|
@ -248,11 +248,24 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc
|
||||||
// Ref: https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-060-abci-1.0.md
|
// Ref: https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-060-abci-1.0.md
|
||||||
// Ref: https://github.com/tendermint/tendermint/blob/main/spec/abci/abci%2B%2B_basic_concepts.md
|
// Ref: https://github.com/tendermint/tendermint/blob/main/spec/abci/abci%2B%2B_basic_concepts.md
|
||||||
func (app *BaseApp) PrepareProposal(req abci.RequestPrepareProposal) (resp abci.ResponsePrepareProposal) {
|
func (app *BaseApp) PrepareProposal(req abci.RequestPrepareProposal) (resp abci.ResponsePrepareProposal) {
|
||||||
ctx := app.getContextForTx(runTxPrepareProposal, []byte{})
|
|
||||||
if app.prepareProposal == nil {
|
if app.prepareProposal == nil {
|
||||||
panic("PrepareProposal method not set")
|
panic("PrepareProposal method not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tendermint must never call PrepareProposal with a height of 0.
|
||||||
|
// Ref: https://github.com/tendermint/tendermint/blob/059798a4f5b0c9f52aa8655fa619054a0154088c/spec/core/state.md?plain=1#L37-L38
|
||||||
|
if req.Height < 1 {
|
||||||
|
panic("PrepareProposal called with invalid height")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := app.getContextForProposal(app.prepareProposalState.ctx, req.Height)
|
||||||
|
|
||||||
|
ctx = ctx.WithVoteInfos(app.voteInfos).
|
||||||
|
WithBlockHeight(req.Height).
|
||||||
|
WithBlockTime(req.Time).
|
||||||
|
WithProposer(req.ProposerAddress).
|
||||||
|
WithConsensusParams(app.GetConsensusParams(ctx))
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
app.logger.Error(
|
app.logger.Error(
|
||||||
|
@ -289,13 +302,15 @@ func (app *BaseApp) ProcessProposal(req abci.RequestProcessProposal) (resp abci.
|
||||||
panic("app.ProcessProposal is not set")
|
panic("app.ProcessProposal is not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := app.processProposalState.ctx.
|
ctx := app.getContextForProposal(app.processProposalState.ctx, req.Height)
|
||||||
|
|
||||||
|
ctx = ctx.
|
||||||
WithVoteInfos(app.voteInfos).
|
WithVoteInfos(app.voteInfos).
|
||||||
WithBlockHeight(req.Height).
|
WithBlockHeight(req.Height).
|
||||||
WithBlockTime(req.Time).
|
WithBlockTime(req.Time).
|
||||||
WithHeaderHash(req.Hash).
|
WithHeaderHash(req.Hash).
|
||||||
WithProposer(req.ProposerAddress).
|
WithProposer(req.ProposerAddress).
|
||||||
WithConsensusParams(app.GetConsensusParams(app.processProposalState.ctx))
|
WithConsensusParams(app.GetConsensusParams(ctx))
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
|
@ -928,3 +943,14 @@ func SplitABCIQueryPath(requestPath string) (path []string) {
|
||||||
|
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getContextForProposal returns the right context for PrepareProposal and
|
||||||
|
// ProcessProposal. We use deliverState on the first block to be able to access
|
||||||
|
// any state changes made in InitChain.
|
||||||
|
func (app *BaseApp) getContextForProposal(ctx sdk.Context, height int64) sdk.Context {
|
||||||
|
if height == 1 {
|
||||||
|
ctx, _ = app.deliverState.ctx.CacheContext()
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
|
@ -1323,10 +1323,6 @@ func TestABCI_Proposal_HappyPath(t *testing.T) {
|
||||||
ConsensusParams: &tmproto.ConsensusParams{},
|
ConsensusParams: &tmproto.ConsensusParams{},
|
||||||
})
|
})
|
||||||
|
|
||||||
suite.baseApp.BeginBlock(abci.RequestBeginBlock{
|
|
||||||
Header: tmproto.Header{Height: suite.baseApp.LastBlockHeight() + 1},
|
|
||||||
})
|
|
||||||
|
|
||||||
tx := newTxCounter(t, suite.txConfig, 0, 1)
|
tx := newTxCounter(t, suite.txConfig, 0, 1)
|
||||||
txBytes, err := suite.txConfig.TxEncoder()(tx)
|
txBytes, err := suite.txConfig.TxEncoder()(tx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -1347,6 +1343,7 @@ func TestABCI_Proposal_HappyPath(t *testing.T) {
|
||||||
|
|
||||||
reqPrepareProposal := abci.RequestPrepareProposal{
|
reqPrepareProposal := abci.RequestPrepareProposal{
|
||||||
MaxTxBytes: 1000,
|
MaxTxBytes: 1000,
|
||||||
|
Height: 1,
|
||||||
}
|
}
|
||||||
resPrepareProposal := suite.baseApp.PrepareProposal(reqPrepareProposal)
|
resPrepareProposal := suite.baseApp.PrepareProposal(reqPrepareProposal)
|
||||||
require.Equal(t, 2, len(resPrepareProposal.Txs))
|
require.Equal(t, 2, len(resPrepareProposal.Txs))
|
||||||
|
@ -1362,6 +1359,10 @@ func TestABCI_Proposal_HappyPath(t *testing.T) {
|
||||||
resProcessProposal := suite.baseApp.ProcessProposal(reqProcessProposal)
|
resProcessProposal := suite.baseApp.ProcessProposal(reqProcessProposal)
|
||||||
require.Equal(t, abci.ResponseProcessProposal_ACCEPT, resProcessProposal.Status)
|
require.Equal(t, abci.ResponseProcessProposal_ACCEPT, resProcessProposal.Status)
|
||||||
|
|
||||||
|
suite.baseApp.BeginBlock(abci.RequestBeginBlock{
|
||||||
|
Header: tmproto.Header{Height: suite.baseApp.LastBlockHeight() + 1},
|
||||||
|
})
|
||||||
|
|
||||||
res := suite.baseApp.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
res := suite.baseApp.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||||
require.Equal(t, 1, pool.CountTx())
|
require.Equal(t, 1, pool.CountTx())
|
||||||
|
|
||||||
|
@ -1369,6 +1370,51 @@ func TestABCI_Proposal_HappyPath(t *testing.T) {
|
||||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestABCI_Proposal_Read_State_PrepareProposal(t *testing.T) {
|
||||||
|
someKey := []byte("some-key")
|
||||||
|
|
||||||
|
setInitChainerOpt := func(bapp *baseapp.BaseApp) {
|
||||||
|
bapp.SetInitChainer(func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||||
|
ctx.KVStore(capKey1).Set(someKey, []byte("foo"))
|
||||||
|
return abci.ResponseInitChain{}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareOpt := func(bapp *baseapp.BaseApp) {
|
||||||
|
bapp.SetPrepareProposal(func(ctx sdk.Context, req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
|
||||||
|
value := ctx.KVStore(capKey1).Get(someKey)
|
||||||
|
// We should be able to access any state written in InitChain
|
||||||
|
require.Equal(t, "foo", string(value))
|
||||||
|
return abci.ResponsePrepareProposal{Txs: req.Txs}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
suite := NewBaseAppSuite(t, setInitChainerOpt, prepareOpt)
|
||||||
|
|
||||||
|
suite.baseApp.InitChain(abci.RequestInitChain{
|
||||||
|
ConsensusParams: &tmproto.ConsensusParams{},
|
||||||
|
})
|
||||||
|
|
||||||
|
reqPrepareProposal := abci.RequestPrepareProposal{
|
||||||
|
MaxTxBytes: 1000,
|
||||||
|
Height: 1, // this value can't be 0
|
||||||
|
}
|
||||||
|
resPrepareProposal := suite.baseApp.PrepareProposal(reqPrepareProposal)
|
||||||
|
require.Equal(t, 0, len(resPrepareProposal.Txs))
|
||||||
|
|
||||||
|
reqProposalTxBytes := [][]byte{}
|
||||||
|
reqProcessProposal := abci.RequestProcessProposal{
|
||||||
|
Txs: reqProposalTxBytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
resProcessProposal := suite.baseApp.ProcessProposal(reqProcessProposal)
|
||||||
|
require.Equal(t, abci.ResponseProcessProposal_ACCEPT, resProcessProposal.Status)
|
||||||
|
|
||||||
|
suite.baseApp.BeginBlock(abci.RequestBeginBlock{
|
||||||
|
Header: tmproto.Header{Height: suite.baseApp.LastBlockHeight() + 1},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestABCI_PrepareProposal_ReachedMaxBytes(t *testing.T) {
|
func TestABCI_PrepareProposal_ReachedMaxBytes(t *testing.T) {
|
||||||
anteKey := []byte("ante-key")
|
anteKey := []byte("ante-key")
|
||||||
pool := mempool.NewSenderNonceMempool()
|
pool := mempool.NewSenderNonceMempool()
|
||||||
|
@ -1389,6 +1435,7 @@ func TestABCI_PrepareProposal_ReachedMaxBytes(t *testing.T) {
|
||||||
|
|
||||||
reqPrepareProposal := abci.RequestPrepareProposal{
|
reqPrepareProposal := abci.RequestPrepareProposal{
|
||||||
MaxTxBytes: 1500,
|
MaxTxBytes: 1500,
|
||||||
|
Height: 1,
|
||||||
}
|
}
|
||||||
resPrepareProposal := suite.baseApp.PrepareProposal(reqPrepareProposal)
|
resPrepareProposal := suite.baseApp.PrepareProposal(reqPrepareProposal)
|
||||||
require.Equal(t, 10, len(resPrepareProposal.Txs))
|
require.Equal(t, 10, len(resPrepareProposal.Txs))
|
||||||
|
@ -1412,6 +1459,7 @@ func TestABCI_PrepareProposal_BadEncoding(t *testing.T) {
|
||||||
|
|
||||||
reqPrepareProposal := abci.RequestPrepareProposal{
|
reqPrepareProposal := abci.RequestPrepareProposal{
|
||||||
MaxTxBytes: 1000,
|
MaxTxBytes: 1000,
|
||||||
|
Height: 1,
|
||||||
}
|
}
|
||||||
resPrepareProposal := suite.baseApp.PrepareProposal(reqPrepareProposal)
|
resPrepareProposal := suite.baseApp.PrepareProposal(reqPrepareProposal)
|
||||||
require.Equal(t, 1, len(resPrepareProposal.Txs))
|
require.Equal(t, 1, len(resPrepareProposal.Txs))
|
||||||
|
@ -1449,6 +1497,7 @@ func TestABCI_PrepareProposal_Failures(t *testing.T) {
|
||||||
|
|
||||||
req := abci.RequestPrepareProposal{
|
req := abci.RequestPrepareProposal{
|
||||||
MaxTxBytes: 1000,
|
MaxTxBytes: 1000,
|
||||||
|
Height: 1,
|
||||||
}
|
}
|
||||||
res := suite.baseApp.PrepareProposal(req)
|
res := suite.baseApp.PrepareProposal(req)
|
||||||
require.Equal(t, 1, len(res.Txs))
|
require.Equal(t, 1, len(res.Txs))
|
||||||
|
@ -1468,6 +1517,7 @@ func TestABCI_PrepareProposal_PanicRecovery(t *testing.T) {
|
||||||
|
|
||||||
req := abci.RequestPrepareProposal{
|
req := abci.RequestPrepareProposal{
|
||||||
MaxTxBytes: 1000,
|
MaxTxBytes: 1000,
|
||||||
|
Height: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NotPanics(t, func() {
|
require.NotPanics(t, func() {
|
||||||
|
|
Loading…
Reference in New Issue