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

feat: expose InitChain tx responses #1941

Merged
merged 32 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7be8225
feat: expose InitChain response
n0izn0iz Apr 17, 2024
667f8bd
Merge branch 'master' into expose-genesis-response
n0izn0iz Apr 17, 2024
9107f45
tmp: start try to store results like in ApplyBlock
n0izn0iz Jun 10, 2024
8bcee48
chore: Merge remote-tracking branch 'origin/master' into expose-genes…
n0izn0iz Jun 10, 2024
8fa79be
feat: save InitChain's ResponseDeliverTxs and add test
n0izn0iz Jun 10, 2024
e4dd0f6
chore: clean
n0izn0iz Jun 10, 2024
d0da512
fix: preserve existing getHeight behavior
n0izn0iz Jun 10, 2024
15e974b
chore: improve comment
n0izn0iz Jun 10, 2024
6c41220
chore: self-contained tests
n0izn0iz Jun 11, 2024
13be10f
chore: remove artifact
n0izn0iz Jun 11, 2024
366d229
chore: use testing utils
n0izn0iz Jun 11, 2024
404fcd5
chore: move MockApplication into testing package
n0izn0iz Jun 12, 2024
926e226
chore: inline asserts
n0izn0iz Jun 12, 2024
d625a9a
Merge branch 'master' into expose-genesis-response
n0izn0iz Jun 12, 2024
f2923e8
Merge branch 'master' into expose-genesis-response
n0izn0iz Jun 12, 2024
a182a3a
chore: update proto
n0izn0iz Jun 12, 2024
0d1a4bd
Merge branch 'master' into expose-genesis-response
n0izn0iz Jun 17, 2024
9d309b7
Merge branch 'master' into expose-genesis-response
n0izn0iz Jun 19, 2024
eda735b
Merge branch 'master' into expose-genesis-response
n0izn0iz Jun 19, 2024
c5357f1
Merge branch 'master' into expose-genesis-response
n0izn0iz Jun 19, 2024
d684021
Merge branch 'master' into expose-genesis-response
n0izn0iz Jul 17, 2024
87fe7d8
chore: use t.Cleanup
n0izn0iz Jul 17, 2024
8b33ffc
chore: use cast instead of generic
n0izn0iz Jul 17, 2024
bad682a
chore: add getHeight test
n0izn0iz Jul 17, 2024
409cd9d
Merge branch 'master' into expose-genesis-response
n0izn0iz Jul 17, 2024
5cec713
Merge branch 'master' into expose-genesis-response
n0izn0iz Jul 19, 2024
ecdf0f2
Merge branch 'master' into expose-genesis-response
n0izn0iz Jul 19, 2024
973a73f
Merge branch 'master' into expose-genesis-response
n0izn0iz Jul 22, 2024
110da7d
chore: revert getHeight
n0izn0iz Jul 22, 2024
01dc6f8
chore: remove MockApplication
n0izn0iz Jul 22, 2024
e649de5
chore: SaveABCIResponses internal usage note
n0izn0iz Jul 22, 2024
83dd5a0
Merge branch 'master' into expose-genesis-response
n0izn0iz Jul 22, 2024
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
11 changes: 10 additions & 1 deletion gno.land/pkg/gnoland/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ func PanicOnFailingTxHandler(ctx sdk.Context, tx std.Tx, res sdk.Result) {
// InitChainer returns a function that can initialize the chain with genesis.
func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank.BankKeeperI, resHandler GenesisTxHandler) func(sdk.Context, abci.RequestInitChain) abci.ResponseInitChain {
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
txResponses := []abci.ResponseDeliverTx{}

if req.AppState != nil {
// Get genesis state
genState := req.AppState.(GnoGenesisState)
Expand All @@ -183,13 +185,20 @@ func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank
)
}

txResponses = append(txResponses, abci.ResponseDeliverTx{
ResponseBase: res.ResponseBase,
GasWanted: res.GasWanted,
GasUsed: res.GasUsed,
})

resHandler(ctx, tx, res)
}
}

// Done!
return abci.ResponseInitChain{
Validators: req.Validators,
Validators: req.Validators,
TxResponses: txResponses,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions tm2/pkg/bft/abci/types/abci.proto
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ message ResponseInitChain {
ResponseBase response_base = 1 [json_name = "ResponseBase"];
ConsensusParams consensus_params = 2 [json_name = "ConsensusParams"];
repeated ValidatorUpdate validators = 3 [json_name = "Validators"];
repeated ResponseDeliverTx tx_responses = 4 [json_name = "TxResponses"];
}

message ResponseQuery {
Expand Down
91 changes: 91 additions & 0 deletions tm2/pkg/bft/abci/types/testing/mock_application.go
thehowl marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package testing

import abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"

type MockApplication struct {
abci.BaseApplication
InfoFn func(abci.RequestInfo) abci.ResponseInfo
SetOptionFn func(abci.RequestSetOption) abci.ResponseSetOption
QueryFn func(abci.RequestQuery) abci.ResponseQuery
CheckTxFn func(abci.RequestCheckTx) abci.ResponseCheckTx
InitChainFn func(abci.RequestInitChain) abci.ResponseInitChain
BeginBlockFn func(abci.RequestBeginBlock) abci.ResponseBeginBlock
DeliverTxFn func(abci.RequestDeliverTx) abci.ResponseDeliverTx
EndBlockFn func(abci.RequestEndBlock) abci.ResponseEndBlock
CommitFn func() abci.ResponseCommit
CloseFn func() error
}

// Info/Query Connection
func (app *MockApplication) Info(req abci.RequestInfo) abci.ResponseInfo {
if app.InfoFn != nil {
return app.InfoFn(req)

Check warning on line 22 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L22

Added line #L22 was not covered by tests
}
return abci.ResponseInfo{}
}

func (app *MockApplication) SetOption(req abci.RequestSetOption) abci.ResponseSetOption {
if app.SetOptionFn != nil {
return app.SetOptionFn(req)

Check warning on line 29 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L27-L29

Added lines #L27 - L29 were not covered by tests
}
return abci.ResponseSetOption{}

Check warning on line 31 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L31

Added line #L31 was not covered by tests
}

func (app *MockApplication) Query(req abci.RequestQuery) abci.ResponseQuery {
if app.QueryFn != nil {
return app.QueryFn(req)

Check warning on line 36 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L34-L36

Added lines #L34 - L36 were not covered by tests
}
return abci.ResponseQuery{}

Check warning on line 38 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L38

Added line #L38 was not covered by tests
}

// Mempool Connection
func (app *MockApplication) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
if app.CheckTxFn != nil {
return app.CheckTxFn(req)

Check warning on line 44 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L42-L44

Added lines #L42 - L44 were not covered by tests
}
return abci.ResponseCheckTx{}

Check warning on line 46 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L46

Added line #L46 was not covered by tests
}

// Consensus Connection
func (app *MockApplication) InitChain(req abci.RequestInitChain) abci.ResponseInitChain {
if app.InitChainFn != nil {
return app.InitChainFn(req)
}
return abci.ResponseInitChain{}

Check warning on line 54 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L54

Added line #L54 was not covered by tests
}

func (app *MockApplication) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
if app.BeginBlockFn != nil {
return app.BeginBlockFn(req)

Check warning on line 59 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L57-L59

Added lines #L57 - L59 were not covered by tests
}
return abci.ResponseBeginBlock{}

Check warning on line 61 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L61

Added line #L61 was not covered by tests
}

func (app *MockApplication) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx {
if app.DeliverTxFn != nil {
return app.DeliverTxFn(req)

Check warning on line 66 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L64-L66

Added lines #L64 - L66 were not covered by tests
}
return abci.ResponseDeliverTx{}

Check warning on line 68 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L68

Added line #L68 was not covered by tests
}

func (app *MockApplication) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock {
if app.EndBlockFn != nil {
return app.EndBlockFn(req)

Check warning on line 73 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L71-L73

Added lines #L71 - L73 were not covered by tests
}
return abci.ResponseEndBlock{}

Check warning on line 75 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L75

Added line #L75 was not covered by tests
}

func (app *MockApplication) Commit() abci.ResponseCommit {
if app.CommitFn != nil {
return app.CommitFn()

Check warning on line 80 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L78-L80

Added lines #L78 - L80 were not covered by tests
}
return abci.ResponseCommit{}

Check warning on line 82 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L82

Added line #L82 was not covered by tests
}

// Cleanup
func (app *MockApplication) Close() error {
if app.CloseFn != nil {
return app.CloseFn()

Check warning on line 88 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L86-L88

Added lines #L86 - L88 were not covered by tests
}
return nil

Check warning on line 90 in tm2/pkg/bft/abci/types/testing/mock_application.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/abci/types/testing/mock_application.go#L90

Added line #L90 was not covered by tests
}
1 change: 1 addition & 0 deletions tm2/pkg/bft/abci/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ type ResponseInitChain struct {
ResponseBase
ConsensusParams *ConsensusParams
Validators []ValidatorUpdate
TxResponses []ResponseDeliverTx
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
}

type ResponseQuery struct {
Expand Down
7 changes: 7 additions & 0 deletions tm2/pkg/bft/consensus/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ func (h *Handshaker) ReplayBlocks(
return nil, err
}

// Save the results by height
abciResponse := sm.NewABCIResponsesFromNum(len(res.TxResponses))
copy(abciResponse.DeliverTxs, res.TxResponses)
sm.SaveABCIResponses(h.stateDB, 0, abciResponse)

// NOTE: we don't save results by tx hash since the transactions are in the AppState opaque type
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved

if stateBlockHeight == 0 { // we only update state when we are in initial state
// If the app returned validators or consensus params, update the state.
if len(res.Validators) > 0 {
Expand Down
57 changes: 41 additions & 16 deletions tm2/pkg/bft/consensus/replay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/amino"
"github.com/gnolang/gno/tm2/pkg/bft/abci/example/kvstore"
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
abci_testing "github.com/gnolang/gno/tm2/pkg/bft/abci/types/testing"
"github.com/gnolang/gno/tm2/pkg/bft/appconn"
cfg "github.com/gnolang/gno/tm2/pkg/bft/config"
cstypes "github.com/gnolang/gno/tm2/pkg/bft/consensus/types"
Expand Down Expand Up @@ -1131,7 +1132,15 @@ func TestHandshakeUpdatesValidators(t *testing.T) {

val, _ := types.RandValidator(true, 10)
vals := types.NewValidatorSet([]*types.Validator{val})
app := &initChainApp{vals: vals.ABCIValidatorUpdates()}
appVals := vals.ABCIValidatorUpdates()
// returns the vals on InitChain
app := &abci_testing.MockApplication{
InitChainFn: func(req abci.RequestInitChain) abci.ResponseInitChain {
return abci.ResponseInitChain{
Validators: appVals,
}
},
}
clientCreator := proxy.NewLocalClientCreator(app)

config, genesisFile := ResetConfig("handshake_test_")
Expand All @@ -1144,13 +1153,9 @@ func TestHandshakeUpdatesValidators(t *testing.T) {
genDoc, _ := sm.MakeGenesisDocFromFile(genesisFile)
handshaker := NewHandshaker(stateDB, state, store, genDoc)
proxyApp := appconn.NewAppConns(clientCreator)
if err := proxyApp.Start(); err != nil {
t.Fatalf("Error starting proxy app connections: %v", err)
}
defer proxyApp.Stop()
if err := handshaker.Handshake(proxyApp); err != nil {
t.Fatalf("Error on abci handshake: %v", err)
}
require.NoError(t, proxyApp.Start(), "Error starting proxy app connections")
defer func() { require.NoError(t, proxyApp.Stop()) }()
thehowl marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(t, handshaker.Handshake(proxyApp), "Error on abci handshake")

// reload the state, check the validator set was updated
state = sm.LoadState(stateDB)
Expand All @@ -1161,14 +1166,34 @@ func TestHandshakeUpdatesValidators(t *testing.T) {
assert.Equal(t, newValAddr, expectValAddr)
}

// returns the vals on InitChain
type initChainApp struct {
abci.BaseApplication
vals []abci.ValidatorUpdate
}
func TestHandshakeGenesisResponseDeliverTx(t *testing.T) {
t.Parallel()

func (ica *initChainApp) InitChain(req abci.RequestInitChain) abci.ResponseInitChain {
return abci.ResponseInitChain{
Validators: ica.vals,
const numInitResponses = 42

app := &abci_testing.MockApplication{
InitChainFn: func(req abci.RequestInitChain) abci.ResponseInitChain {
return abci.ResponseInitChain{
TxResponses: make([]abci.ResponseDeliverTx, numInitResponses),
}
},
}
clientCreator := proxy.NewLocalClientCreator(app)

config, genesisFile := ResetConfig("handshake_test_")
defer os.RemoveAll(config.RootDir)
thehowl marked this conversation as resolved.
Show resolved Hide resolved
stateDB, state, store := makeStateAndStore(config, genesisFile, "v0.0.0-test")

// now start the app using the handshake - it should sync
genDoc, _ := sm.MakeGenesisDocFromFile(genesisFile)
handshaker := NewHandshaker(stateDB, state, store, genDoc)
proxyApp := appconn.NewAppConns(clientCreator)
require.NoError(t, proxyApp.Start(), "Error starting proxy app connections")
defer func() { require.NoError(t, proxyApp.Stop()) }()
thehowl marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(t, handshaker.Handshake(proxyApp), "Error on abci handshake")

// check that the genesis transaction results are saved
res, err := sm.LoadABCIResponses(stateDB, 0)
require.NoError(t, err, "Failed to load genesis ABCI responses")
assert.Len(t, res.DeliverTxs, numInitResponses)
}
12 changes: 6 additions & 6 deletions tm2/pkg/bft/rpc/core/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@
// ```
func Block(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlock, error) {
storeHeight := blockStore.Height()
height, err := getHeight(storeHeight, heightPtr)
height, err := getHeight(storeHeight, heightPtr, 1)

Check warning on line 239 in tm2/pkg/bft/rpc/core/blocks.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/rpc/core/blocks.go#L239

Added line #L239 was not covered by tests
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -327,7 +327,7 @@
// ```
func Commit(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultCommit, error) {
storeHeight := blockStore.Height()
height, err := getHeight(storeHeight, heightPtr)
height, err := getHeight(storeHeight, heightPtr, 1)

Check warning on line 330 in tm2/pkg/bft/rpc/core/blocks.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/rpc/core/blocks.go#L330

Added line #L330 was not covered by tests
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -400,7 +400,7 @@
// ```
func BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockResults, error) {
storeHeight := blockStore.Height()
height, err := getHeight(storeHeight, heightPtr)
height, err := getHeight(storeHeight, heightPtr, 0)

Check warning on line 403 in tm2/pkg/bft/rpc/core/blocks.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/rpc/core/blocks.go#L403

Added line #L403 was not covered by tests
thehowl marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
Expand All @@ -417,11 +417,11 @@
return res, nil
}

func getHeight(currentHeight int64, heightPtr *int64) (int64, error) {
func getHeight(currentHeight int64, heightPtr *int64, min int64) (int64, error) {
if heightPtr != nil {
height := *heightPtr
if height <= 0 {
return 0, fmt.Errorf("height must be greater than 0")
if height < min {
return 0, fmt.Errorf("height must be greater than or equal to %d", min)

Check warning on line 424 in tm2/pkg/bft/rpc/core/blocks.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/rpc/core/blocks.go#L424

Added line #L424 was not covered by tests
ajnavarro marked this conversation as resolved.
Show resolved Hide resolved
}
if height > currentHeight {
ajnavarro marked this conversation as resolved.
Show resolved Hide resolved
return 0, fmt.Errorf("height must be less than or equal to the current blockchain height")
Expand Down
4 changes: 2 additions & 2 deletions tm2/pkg/bft/rpc/core/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
// The latest validator that we know is the
// NextValidator of the last block.
height := consensusState.GetState().LastBlockHeight + 1
height, err := getHeight(height, heightPtr)
height, err := getHeight(height, heightPtr, 1)

Check warning on line 61 in tm2/pkg/bft/rpc/core/consensus.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/rpc/core/consensus.go#L61

Added line #L61 was not covered by tests
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -344,7 +344,7 @@
// ```
func ConsensusParams(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultConsensusParams, error) {
height := consensusState.GetState().LastBlockHeight + 1
height, err := getHeight(height, heightPtr)
height, err := getHeight(height, heightPtr, 1)

Check warning on line 347 in tm2/pkg/bft/rpc/core/consensus.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/rpc/core/consensus.go#L347

Added line #L347 was not covered by tests
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion tm2/pkg/bft/rpc/core/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func Tx(_ *rpctypes.Context, hash []byte) (*ctypes.ResultTx, error) {
}

// Sanity check the block height
height, err := getHeight(blockStore.Height(), &resultIndex.BlockNum)
height, err := getHeight(blockStore.Height(), &resultIndex.BlockNum, 1)
if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions tm2/pkg/bft/state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ func (blockExec *BlockExecutor) ApplyBlock(state State, blockID types.BlockID, b

fail.Fail() // XXX

// Save the results before we commit.
saveABCIResponses(blockExec.db, block.Height, abciResponses)
// Save the results by height
SaveABCIResponses(blockExec.db, block.Height, abciResponses)

// Save the transaction results
// Save the results by tx hash
for index, tx := range block.Txs {
saveTxResultIndex(
blockExec.db,
Expand Down
6 changes: 0 additions & 6 deletions tm2/pkg/bft/state/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ func CalcValidatorsKey(height int64) []byte {
return calcValidatorsKey(height)
}

// SaveABCIResponses is an alias for the private saveABCIResponses method in
// store.go, exported exclusively and explicitly for testing.
func SaveABCIResponses(db dbm.DB, height int64, abciResponses *ABCIResponses) {
saveABCIResponses(db, height, abciResponses)
}

// SaveConsensusParamsInfo is an alias for the private saveConsensusParamsInfo
// method in store.go, exported exclusively and explicitly for testing.
func SaveConsensusParamsInfo(db dbm.DB, nextHeight, changeHeight int64, params abci.ConsensusParams) {
Expand Down
12 changes: 9 additions & 3 deletions tm2/pkg/bft/state/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/bft/types"
dbm "github.com/gnolang/gno/tm2/pkg/db"
osm "github.com/gnolang/gno/tm2/pkg/os"
"golang.org/x/exp/constraints"
)

const (
Expand Down Expand Up @@ -131,8 +132,13 @@ type ABCIResponses struct {

// NewABCIResponses returns a new ABCIResponses
func NewABCIResponses(block *types.Block) *ABCIResponses {
resDeliverTxs := make([]abci.ResponseDeliverTx, block.NumTxs)
if block.NumTxs == 0 {
return NewABCIResponsesFromNum(block.NumTxs)
}

// NewABCIResponsesFromNum returns a new ABCIResponses with a set number of txs
func NewABCIResponsesFromNum[N constraints.Integer](numTxs N) *ABCIResponses {
thehowl marked this conversation as resolved.
Show resolved Hide resolved
resDeliverTxs := make([]abci.ResponseDeliverTx, numTxs)
if numTxs == 0 {
// This makes Amino encoding/decoding consistent.
resDeliverTxs = nil
}
Expand Down Expand Up @@ -175,7 +181,7 @@ func LoadABCIResponses(db dbm.DB, height int64) (*ABCIResponses, error) {
// SaveABCIResponses persists the ABCIResponses to the database.
// This is useful in case we crash after app.Commit and before s.Save().
// Responses are indexed by height so they can also be loaded later to produce Merkle proofs.
func saveABCIResponses(db dbm.DB, height int64, abciResponses *ABCIResponses) {
func SaveABCIResponses(db dbm.DB, height int64, abciResponses *ABCIResponses) {
thehowl marked this conversation as resolved.
Show resolved Hide resolved
db.Set(CalcABCIResponsesKey(height), abciResponses.Bytes())
}

Expand Down
Loading