Skip to content

Commit

Permalink
feat: expose InitChain response
Browse files Browse the repository at this point in the history
Signed-off-by: Norman Meier <[email protected]>
  • Loading branch information
n0izn0iz committed Apr 17, 2024
1 parent 3297d0c commit b190ec1
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 5 deletions.
9 changes: 8 additions & 1 deletion gno.land/pkg/gnoland/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank
}

// Run genesis txs.
txResponses := make([]abci.ResponseDeliverTx, 0, len(genState.Txs))
for _, tx := range genState.Txs {
res := baseApp.Deliver(tx)
if res.IsErr() {
Expand All @@ -180,11 +181,17 @@ func InitChainer(baseApp *sdk.BaseApp, acctKpr auth.AccountKeeperI, bankKpr bank
}

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

// 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/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ type ResponseInitChain struct {
ResponseBase
ConsensusParams *ConsensusParams
Validators []ValidatorUpdate
TxResponses []ResponseDeliverTx
}

type ResponseQuery struct {
Expand Down
12 changes: 12 additions & 0 deletions tm2/pkg/bft/consensus/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"reflect"
"time"

"github.com/gnolang/gno/tm2/pkg/amino"
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
"github.com/gnolang/gno/tm2/pkg/bft/appconn"
cstypes "github.com/gnolang/gno/tm2/pkg/bft/consensus/types"
Expand Down Expand Up @@ -273,6 +274,16 @@ func (h *Handshaker) Handshake(proxyApp appconn.AppConns) error {
return nil
}

// panics if failed to marshal the given genesis response
func saveGenesisRes(logger *slog.Logger, db dbm.DB, res *abci.ResponseInitChain) {
b, err := amino.MarshalJSON(res)
if err != nil {
panic(fmt.Sprintf("Failed to save genesis response due to marshaling error: %v", err))
}
db.SetSync([]byte("genesisRes"), b)
logger.Info("saved genesis response", "response", string(b))
}

// ReplayBlocks replays all blocks since appBlockHeight and ensures the result
// matches the current state.
// Returns the final AppHash or an error.
Expand Down Expand Up @@ -306,6 +317,7 @@ func (h *Handshaker) ReplayBlocks(
if err != nil {
return nil, err
}
saveGenesisRes(h.logger, h.stateDB, &res)

if stateBlockHeight == 0 { // we only update state when we are in initial state
// If the app returned validators or consensus params, update the state.
Expand Down
6 changes: 6 additions & 0 deletions tm2/pkg/bft/consensus/replay_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/bft/proxy"
sm "github.com/gnolang/gno/tm2/pkg/bft/state"
"github.com/gnolang/gno/tm2/pkg/bft/store"
"github.com/gnolang/gno/tm2/pkg/bft/types"
walm "github.com/gnolang/gno/tm2/pkg/bft/wal"
dbm "github.com/gnolang/gno/tm2/pkg/db"
"github.com/gnolang/gno/tm2/pkg/errors"
Expand Down Expand Up @@ -294,6 +295,11 @@ func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cnscfg.Consensu
if err != nil {
osm.Exit(err.Error())
}
blockStore.SaveBlock(&types.Block{
Header: types.Header{
AppVersion: state.AppVersion,
},
}, nil, nil)

// Create proxyAppConn connection (consensus, mempool, query)
clientCreator := proxy.DefaultClientCreator(
Expand Down
6 changes: 6 additions & 0 deletions tm2/pkg/bft/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,12 @@ func NewNode(config *cfg.Config,
if err != nil {
return nil, err
}
/*
// doesn't work
block0 := types.MakeBlock(0, nil, nil)
block0.AppVersion = state.AppVersion
blockStore.SaveBlock(block0, nil, nil)
*/

// Create the proxyApp and establish connections to the ABCI app (consensus, mempool, query).
proxyApp, err := createAndStartProxyAppConns(clientCreator, logger)
Expand Down
4 changes: 2 additions & 2 deletions tm2/pkg/bft/rpc/core/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,8 @@ func BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockR
func getHeight(currentHeight int64, heightPtr *int64) (int64, error) {
if heightPtr != nil {
height := *heightPtr
if height <= 0 {
return 0, fmt.Errorf("height must be greater than 0")
if height < 0 {
return 0, fmt.Errorf("height must be greater than or equal to 0")
}
if height > currentHeight {
return 0, fmt.Errorf("height must be less than or equal to the current blockchain height")
Expand Down
24 changes: 23 additions & 1 deletion tm2/pkg/bft/rpc/core/net.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package core

import (
"fmt"

"github.com/gnolang/gno/tm2/pkg/amino"
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
ctypes "github.com/gnolang/gno/tm2/pkg/bft/rpc/core/types"
rpctypes "github.com/gnolang/gno/tm2/pkg/bft/rpc/lib/types"
dbm "github.com/gnolang/gno/tm2/pkg/db"
"github.com/gnolang/gno/tm2/pkg/errors"
)

Expand Down Expand Up @@ -251,5 +256,22 @@ func UnsafeDialPeers(ctx *rpctypes.Context, peers []string, persistent bool) (*c
//
// ```
func Genesis(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) {
return &ctypes.ResultGenesis{Genesis: genDoc}, nil
res, err := loadGenesisRes(stateDB)
if err != nil {
return nil, err
}
return &ctypes.ResultGenesis{Genesis: genDoc, Response: res}, nil
}

func loadGenesisRes(db dbm.DB) (*abci.ResponseInitChain, error) {
b := db.Get([]byte("genesisRes"))
if len(b) == 0 {
return nil, errors.New("Genesis res not found")
}
var genRes *abci.ResponseInitChain
err := amino.UnmarshalJSON(b, &genRes)
if err != nil {
panic(fmt.Sprintf("Failed to load genesis res due to unmarshaling error: %v (bytes: %X)", err, b))
}
return genRes, nil
}
3 changes: 2 additions & 1 deletion tm2/pkg/bft/rpc/core/types/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ type ResultBlockchainInfo struct {

// Genesis file
type ResultGenesis struct {
Genesis *types.GenesisDoc `json:"genesis"`
Genesis *types.GenesisDoc `json:"genesis"`
Response *abci.ResponseInitChain `json:"response"`
}

// Single block (with meta)
Expand Down
4 changes: 4 additions & 0 deletions tm2/pkg/bft/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ func (bs *BlockStore) Height() int64 {
// LoadBlock returns the block with the given height.
// If no block is found for that height, it returns nil.
func (bs *BlockStore) LoadBlock(height int64) *types.Block {
if height == 0 {
return &types.Block{Header: types.Header{Height: 0, ChainID: "wololo"}}
}

blockMeta := bs.LoadBlockMeta(height)
if blockMeta == nil {
return nil
Expand Down
10 changes: 10 additions & 0 deletions tm2/pkg/sdk/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,16 @@ func (app *BaseApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOp
return
}

// panics if failed to marshal the given genesis response
func saveGenesisRes(logger *slog.Logger, db dbm.DB, res *abci.ResponseInitChain) {
b, err := amino.MarshalJSON(res)
if err != nil {
panic(fmt.Sprintf("Failed to save genesis response due to marshaling error: %v", err))
}
db.SetSync([]byte("genesisRes"), b)
logger.Info("saved genesis response", "response", string(b))
}

// InitChain implements the ABCI interface. It runs the initialization logic
// directly on the CommitMultiStore.
func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) {
Expand Down

0 comments on commit b190ec1

Please sign in to comment.