Skip to content

Commit

Permalink
feat(store): add rawlog in txstatus (#1458)
Browse files Browse the repository at this point in the history
## Description

Fixes #1454

---------

Co-authored-by: Rootul P <[email protected]>
  • Loading branch information
ninabarbakadze and rootulp authored Aug 15, 2024
1 parent 353761f commit 9563209
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 23 deletions.
2 changes: 1 addition & 1 deletion consensus/replay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,7 @@ func (bs *mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta {
func (bs *mockBlockStore) LoadBlockPart(height int64, index int) *types.Part { return nil }
func (bs *mockBlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) {
}
func (bs *mockBlockStore) SaveTxInfo(block *types.Block, txResponseCode []uint32) error {
func (bs *mockBlockStore) SaveTxInfo(block *types.Block, txResponseCodes []uint32, logs []string) error {
return nil
}
func (bs *mockBlockStore) LoadTxInfo(hash []byte) *cmtstore.TxInfo { return &cmtstore.TxInfo{} }
Expand Down
70 changes: 62 additions & 8 deletions proto/tendermint/store/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion proto/tendermint/store/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ message BlockStoreState {
}

// TxInfo describes the location of a tx inside a committed block
// as well as the result of executing the transaction.
// as well as the result of executing the transaction and the raw log output.
message TxInfo {
int64 height = 1;
uint32 index = 2;
// The response code of executing the tx. 0 means
// successfully executed, all others are error codes.
uint32 code = 3;
// The log output generated during the execution of a transaction.
// Note: this is empty if the transaction succeeded.
string log = 4;
}
2 changes: 1 addition & 1 deletion rpc/core/blocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ func (mockBlockStore) LoadSeenCommit(height int64) *types.Commit { retur
func (mockBlockStore) PruneBlocks(height int64) (uint64, error) { return 0, nil }
func (mockBlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) {
}
func (mockBlockStore) SaveTxInfo(block *types.Block, txResponseCode []uint32) error {
func (mockBlockStore) SaveTxInfo(block *types.Block, txResponseCodes []uint32, logs []string) error {
return nil
}

Expand Down
12 changes: 11 additions & 1 deletion state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ func (blockExec *BlockExecutor) ApplyBlock(
// for correct crash recovery
if blockExec.blockStore != nil {
respCodes := getResponseCodes(abciResponses.DeliverTxs)
if err := blockExec.blockStore.SaveTxInfo(block, respCodes); err != nil {
logs := getLogs(abciResponses.DeliverTxs)
if err := blockExec.blockStore.SaveTxInfo(block, respCodes, logs); err != nil {
return state, 0, err
}
}
Expand Down Expand Up @@ -684,3 +685,12 @@ func getResponseCodes(responses []*abci.ResponseDeliverTx) []uint32 {
}
return responseCodes
}

// getLogs gets logs from a list of ResponseDeliverTx.
func getLogs(responses []*abci.ResponseDeliverTx) []string {
logs := make([]string, len(responses))
for i, response := range responses {
logs[i] = response.Log
}
return logs
}
2 changes: 1 addition & 1 deletion state/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func TestApplyBlockWithBlockStore(t *testing.T) {
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}

// Check that SaveTxInfo is called with correct arguments
blockStore.On("SaveTxInfo", block, mock.AnythingOfType("[]uint32")).Return(nil)
blockStore.On("SaveTxInfo", block, mock.AnythingOfType("[]uint32"), mock.AnythingOfType("[]string")).Return(nil)

_, _, err = blockExec.ApplyBlock(state, blockID, block, nil)
require.Nil(t, err)
Expand Down
8 changes: 4 additions & 4 deletions state/mocks/block_store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion state/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type BlockStore interface {
LoadBlock(height int64) *types.Block

SaveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit)
SaveTxInfo(block *types.Block, txResponseCode []uint32) error
SaveTxInfo(block *types.Block, txResponseCodes []uint32, logs []string) error

PruneBlocks(height int64) (uint64, error)

Expand Down
13 changes: 11 additions & 2 deletions store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
dbm "github.com/cometbft/cometbft-db"
"github.com/gogo/protobuf/proto"

abci "github.com/tendermint/tendermint/abci/types"
cmtsync "github.com/tendermint/tendermint/libs/sync"
cmtstore "github.com/tendermint/tendermint/proto/tendermint/store"
cmtproto "github.com/tendermint/tendermint/proto/tendermint/types"
Expand Down Expand Up @@ -450,11 +451,15 @@ func (bs *BlockStore) SaveSeenCommit(height int64, seenCommit *types.Commit) err
return bs.db.Set(calcSeenCommitKey(height), seenCommitBytes)
}

// SaveTxInfo indexes the txs from the block with the given response codes from execution.
func (bs *BlockStore) SaveTxInfo(block *types.Block, txResponseCodes []uint32) error {
// SaveTxInfo indexes the txs from the block with the given response codes and logs from execution.
// The logs are only saved for failed transactions.
func (bs *BlockStore) SaveTxInfo(block *types.Block, txResponseCodes []uint32, logs []string) error {
if len(txResponseCodes) != len(block.Txs) {
return fmt.Errorf("txResponseCodes length mismatch with block txs length")
}
if len(logs) != len(block.Txs) {
return fmt.Errorf("logs length mismatch with block txs length")
}

// Create a new batch
batch := bs.db.NewBatch()
Expand All @@ -466,6 +471,10 @@ func (bs *BlockStore) SaveTxInfo(block *types.Block, txResponseCodes []uint32) e
Index: uint32(i),
Code: txResponseCodes[i],
}
// Only save Logs for failed transactions
if txResponseCodes[i] != abci.CodeTypeOK {
txInfo.Log = logs[i]
}
txInfoBytes, err := proto.Marshal(&txInfo)
if err != nil {
return fmt.Errorf("unable to marshal tx: %w", err)
Expand Down
16 changes: 13 additions & 3 deletions store/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,24 +384,27 @@ func TestSaveTxInfo(t *testing.T) {

// Create 1000 blocks
txResponseCodes := make([]uint32, len(block.Txs))
logs := make([]string, len(block.Txs))
for h := int64(1); h <= 1000; h++ {
block := makeBlock(h, state, new(types.Commit))
partSet := block.MakePartSet(2)
seenCommit := makeTestCommit(h, cmttime.Now())
blockStore.SaveBlock(block, partSet, seenCommit)

// Set the response codes for the transactions
// Set the response codes and logs for the transactions
for i := range block.Txs {
// If even set it to 0
if i%2 == 0 {
txResponseCodes[i] = 0
logs[i] = "success"
} else {
txResponseCodes[i] = 1
logs[i] = "failure"
}
}

// Save the tx info
err := blockStore.SaveTxInfo(block, txResponseCodes)
err := blockStore.SaveTxInfo(block, txResponseCodes, logs)
require.NoError(t, err)
}

Expand All @@ -414,6 +417,12 @@ func TestSaveTxInfo(t *testing.T) {
require.Equal(t, block.Height, txInfo.Height)
require.Equal(t, uint32(i), txInfo.Index)
require.Equal(t, txResponseCodes[i], txInfo.Code)
// We don't save the logs for successful transactions
if txResponseCodes[i] == 0 {
require.Equal(t, "", txInfo.Log)
} else {
require.Equal(t, logs[i], txInfo.Log)
}
}
}

Expand All @@ -426,6 +435,7 @@ func TestSaveTxInfo(t *testing.T) {
require.Equal(t, txInfo.Height, int64(777))
require.Equal(t, uint32(1), txInfo.Code)
require.Equal(t, uint32(5), txInfo.Index)
require.Equal(t, "failure", txInfo.Log)
}

func TestLoadBaseMeta(t *testing.T) {
Expand Down Expand Up @@ -597,7 +607,7 @@ func TestPruneBlocksPrunesTxs(t *testing.T) {
partSet := block.MakePartSet(2)
seenCommit := makeTestCommit(h, cmttime.Now())
blockStore.SaveBlock(block, partSet, seenCommit)
err := blockStore.SaveTxInfo(block, make([]uint32, len(block.Txs)))
err := blockStore.SaveTxInfo(block, make([]uint32, len(block.Txs)), make([]string, len(block.Txs)))
require.NoError(t, err)
for _, tx := range block.Txs {
indexedTxHashes = append(indexedTxHashes, tx.Hash())
Expand Down

0 comments on commit 9563209

Please sign in to comment.