Skip to content

Commit

Permalink
fix: update blockTxs to correctly parse finalizeblock events (#123)
Browse files Browse the repository at this point in the history
* fix: FinalizeBlock

* fix

* CHANGELOG

* fix
  • Loading branch information
JulianToledano authored May 7, 2024
1 parent 92c741d commit 3eed528
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 73 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

### Bug Fixes

* [123](https://github.com/cosmos/rosetta/pull/123) Correctly parse cometBFT finalize block.

## [v0.50.6](https://github.com/cosmos/rosetta/releases/tag/v0.50.6) 2024-04-23

### Improvements
Expand Down
37 changes: 7 additions & 30 deletions client_online.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,20 +306,6 @@ func (c *Client) GetTx(ctx context.Context, hash string) (*rosettatypes.Transact
// construct rosetta tx
switch txType {
// handle begin block hash
case BeginBlockTx:
// get block height by hash
block, err := c.tmRPC.BlockByHash(ctx, hashBytes)
if err != nil {
return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block by hash %s", err.Error()))
}

// get block txs
fullBlock, err := c.blockTxs(ctx, &block.Block.Height)
if err != nil {
return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block tx %s", err.Error()))
}

return fullBlock.Transactions[0], nil
// handle deliver tx hash
case DeliverTxTx:
rawTx, err := c.tmRPC.Tx(ctx, hashBytes, true)
Expand All @@ -328,7 +314,7 @@ func (c *Client) GetTx(ctx context.Context, hash string) (*rosettatypes.Transact
}
return c.converter.ToRosetta().Tx(rawTx.Tx, &rawTx.TxResult)
// handle end block hash
case EndBlockTx:
case FinalizeBlockTx:
// get block height by hash
block, err := c.tmRPC.BlockByHash(ctx, hashBytes)
if err != nil {
Expand Down Expand Up @@ -365,8 +351,8 @@ func (c *Client) GetUnconfirmedTx(ctx context.Context, hash string) (*rosettatyp
switch len(hashAsBytes) {
default:
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, fmt.Sprintf("unrecognized tx size: %d", len(hashAsBytes)))
case BeginEndBlockTxSize:
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "endblock and begin block txs cannot be unconfirmed")
case FinalizeBlockTxSize:
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "finalize block txs cannot be unconfirmed")
case DeliverTxSize:
break
}
Expand Down Expand Up @@ -510,16 +496,8 @@ func (c *Client) blockTxs(ctx context.Context, height *int64) (crgtypes.BlockTra
return crgtypes.BlockTransactionsResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, "block results transactions do now match block transactions")
}
// process begin and end block txs
beginBlockTx := &rosettatypes.Transaction{
TransactionIdentifier: &rosettatypes.TransactionIdentifier{Hash: c.converter.ToRosetta().BeginBlockTxHash(blockInfo.BlockID.Hash)},
Operations: AddOperationIndexes(
nil,
c.converter.ToRosetta().BalanceOps(StatusTxSuccess, blockResults.FinalizeBlockEvents),
),
}

endBlockTx := &rosettatypes.Transaction{
TransactionIdentifier: &rosettatypes.TransactionIdentifier{Hash: c.converter.ToRosetta().EndBlockTxHash(blockInfo.BlockID.Hash)},
finalizeBlockTx := &rosettatypes.Transaction{
TransactionIdentifier: &rosettatypes.TransactionIdentifier{Hash: c.converter.ToRosetta().FinalizeBlockTxHash(blockInfo.BlockID.Hash)},
Operations: AddOperationIndexes(
nil,
c.converter.ToRosetta().BalanceOps(StatusTxSuccess, blockResults.FinalizeBlockEvents),
Expand All @@ -536,10 +514,9 @@ func (c *Client) blockTxs(ctx context.Context, height *int64) (crgtypes.BlockTra
deliverTx[i] = rosTx
}

finalTxs := make([]*rosettatypes.Transaction, 0, 2+len(deliverTx))
finalTxs = append(finalTxs, beginBlockTx)
finalTxs := make([]*rosettatypes.Transaction, 0, 1+len(deliverTx))
finalTxs = append(finalTxs, deliverTx...)
finalTxs = append(finalTxs, endBlockTx)
finalTxs = append(finalTxs, finalizeBlockTx)

return crgtypes.BlockTransactionsResponse{
BlockResponse: c.converter.ToRosetta().BlockResponse(blockInfo),
Expand Down
32 changes: 10 additions & 22 deletions converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ type ToRosettaConverter interface {
// BlockResponse returns a block response given a result block
BlockResponse(block *tmcoretypes.ResultBlock) crgtypes.BlockResponse
// BeginBlockToTx converts the given begin block hash to rosetta transaction hash
BeginBlockTxHash(blockHash []byte) string
// EndBlockTxHash converts the given endblock hash to rosetta transaction hash
EndBlockTxHash(blockHash []byte) string
FinalizeBlockTxHash(blockHash []byte) string
// Amounts converts sdk.Coins to rosetta.Amounts
Amounts(ownedCoins []sdk.Coin, availableCoins sdk.Coins) []*rosettatypes.Amount
// Ops converts an sdk.Msg to rosetta operations
Expand Down Expand Up @@ -474,35 +472,25 @@ func AddOperationIndexes(msgOps, balanceOps []*rosettatypes.Operation) (finalOps
return finalOps
}

// EndBlockTxHash produces a mock endblock hash that rosetta can query
// for endblock operations, it also serves the purpose of representing
// part of the state changes happening at endblock level (balance ones)
func (c converter) EndBlockTxHash(hash []byte) string {
final := append([]byte{EndBlockHashStart}, hash...)
return fmt.Sprintf("%X", final)
}

// BeginBlockTxHash produces a mock beginblock hash that rosetta can query
// for beginblock operations, it also serves the purpose of representing
// part of the state changes happening at beginblock level (balance ones)
func (c converter) BeginBlockTxHash(hash []byte) string {
final := append([]byte{BeginBlockHashStart}, hash...)
// FinalizeBlockTxHash produces a mock beginblock hash that rosetta can query
// for finalizeBlock operations, it also serves the purpose of representing
// part of the state changes happening at finalizeblock level (balance ones)
func (c converter) FinalizeBlockTxHash(hash []byte) string {
final := append([]byte{FinalizeBlockHashStart}, hash...)
return fmt.Sprintf("%X", final)
}

// HashToTxType takes the provided hash bytes from rosetta and discerns if they are
// a deliver tx type or endblock/begin block hash, returning the real hash afterwards
// a deliver tx type or finalize block hash, returning the real hash afterward
func (c converter) HashToTxType(hashBytes []byte) (txType TransactionType, realHash []byte) {
switch len(hashBytes) {
case DeliverTxSize:
return DeliverTxTx, hashBytes

case BeginEndBlockTxSize:
case FinalizeBlockTxSize:
switch hashBytes[0] {
case BeginBlockHashStart:
return BeginBlockTx, hashBytes[1:]
case EndBlockHashStart:
return EndBlockTx, hashBytes[1:]
case FinalizeBlockHashStart:
return FinalizeBlockHashStart, hashBytes[1:]
default:
return UnrecognizedTx, nil
}
Expand Down
20 changes: 5 additions & 15 deletions converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,36 +179,26 @@ func (s *ConverterTestSuite) TestOpsAndSigners() {
})
}

func (s *ConverterTestSuite) TestBeginEndBlockAndHashToTxType() {
func (s *ConverterTestSuite) TestFinalizeBlockHashToTxType() {
const deliverTxHex = "5229A67AA008B5C5F1A0AEA77D4DEBE146297A30AAEF01777AF10FAD62DD36AB"

deliverTxBytes, err := hex.DecodeString(deliverTxHex)
s.Require().NoError(err)

endBlockTxHex := s.c.ToRosetta().EndBlockTxHash(deliverTxBytes)
beginBlockTxHex := s.c.ToRosetta().BeginBlockTxHash(deliverTxBytes)
finalizeBlockTxHex := s.c.ToRosetta().FinalizeBlockTxHash(deliverTxBytes)

txType, hash := s.c.ToSDK().HashToTxType(deliverTxBytes)

s.Require().Equal(rosetta.DeliverTxTx, txType)
s.Require().Equal(deliverTxBytes, hash, "deliver tx hash should not change")

endBlockTxBytes, err := hex.DecodeString(endBlockTxHex)
finalizeBlockTxBytes, err := hex.DecodeString(finalizeBlockTxHex)
s.Require().NoError(err)

txType, hash = s.c.ToSDK().HashToTxType(endBlockTxBytes)

s.Require().Equal(rosetta.EndBlockTx, txType)
txType, hash = s.c.ToSDK().HashToTxType(finalizeBlockTxBytes)
s.Require().Equal(rosetta.FinalizeBlockTx, txType)
s.Require().Equal(deliverTxBytes, hash, "end block tx hash should be equal to a block hash")

beginBlockTxBytes, err := hex.DecodeString(beginBlockTxHex)
s.Require().NoError(err)

txType, hash = s.c.ToSDK().HashToTxType(beginBlockTxBytes)

s.Require().Equal(rosetta.BeginBlockTx, txType)
s.Require().Equal(deliverTxBytes, hash, "begin block tx hash should be equal to a block hash")

txType, hash = s.c.ToSDK().HashToTxType([]byte("invalid"))

s.Require().Equal(rosetta.UnrecognizedTx, txType)
Expand Down
10 changes: 4 additions & 6 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ const (
// which are not represented as transactions we mock only the balance changes
// happening at those levels as transactions. (check BeginBlockTxHash for more info)
const (
DeliverTxSize = sha256.Size
BeginEndBlockTxSize = DeliverTxSize + 1
EndBlockHashStart = 0x0
BeginBlockHashStart = 0x1
DeliverTxSize = sha256.Size
FinalizeBlockTxSize = DeliverTxSize + 1
FinalizeBlockHashStart = 0x1
)

const (
Expand All @@ -37,8 +36,7 @@ type TransactionType int

const (
UnrecognizedTx TransactionType = iota
BeginBlockTx
EndBlockTx
FinalizeBlockTx
DeliverTxTx
)

Expand Down

0 comments on commit 3eed528

Please sign in to comment.