github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/state/tx_result_test.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/gnolang/gno/tm2/pkg/amino"
     8  	abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
     9  	"github.com/gnolang/gno/tm2/pkg/bft/types"
    10  	"github.com/gnolang/gno/tm2/pkg/db/memdb"
    11  	"github.com/gnolang/gno/tm2/pkg/std"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  // generateTxResults generates test transaction results
    17  func generateTxResults(t *testing.T, count int) []*types.TxResult {
    18  	t.Helper()
    19  
    20  	results := make([]*types.TxResult, count)
    21  
    22  	for i := 0; i < count; i++ {
    23  		tx := &std.Tx{
    24  			Memo: fmt.Sprintf("tx %d", i),
    25  		}
    26  
    27  		marshalledTx, err := amino.Marshal(tx)
    28  		require.NoError(t, err)
    29  
    30  		results[i] = &types.TxResult{
    31  			Height:   10,
    32  			Index:    uint32(i),
    33  			Tx:       marshalledTx,
    34  			Response: abci.ResponseDeliverTx{},
    35  		}
    36  	}
    37  
    38  	return results
    39  }
    40  
    41  func TestStoreLoadTxResult(t *testing.T) {
    42  	t.Parallel()
    43  
    44  	t.Run("results found", func(t *testing.T) {
    45  		t.Parallel()
    46  
    47  		var (
    48  			stateDB   = memdb.NewMemDB()
    49  			txResults = generateTxResults(t, 100)
    50  		)
    51  
    52  		// Save the results
    53  		for _, txResult := range txResults {
    54  			saveTxResultIndex(
    55  				stateDB,
    56  				txResult.Tx.Hash(),
    57  				TxResultIndex{
    58  					BlockNum: txResult.Height,
    59  					TxIndex:  txResult.Index,
    60  				},
    61  			)
    62  		}
    63  
    64  		// Verify they are saved correctly
    65  		for _, txResult := range txResults {
    66  			result := TxResultIndex{
    67  				BlockNum: txResult.Height,
    68  				TxIndex:  txResult.Index,
    69  			}
    70  
    71  			dbResult, err := LoadTxResultIndex(stateDB, txResult.Tx.Hash())
    72  			require.NoError(t, err)
    73  
    74  			assert.Equal(t, result.BlockNum, dbResult.BlockNum)
    75  			assert.Equal(t, result.TxIndex, dbResult.TxIndex)
    76  		}
    77  	})
    78  
    79  	t.Run("results not found", func(t *testing.T) {
    80  		t.Parallel()
    81  
    82  		var (
    83  			stateDB   = memdb.NewMemDB()
    84  			txResults = generateTxResults(t, 10)
    85  		)
    86  
    87  		// Verify they are not present
    88  		for _, txResult := range txResults {
    89  			_, err := LoadTxResultIndex(stateDB, txResult.Tx.Hash())
    90  
    91  			expectedErr := NoTxResultForHashError{
    92  				Hash: txResult.Tx.Hash(),
    93  			}
    94  
    95  			require.ErrorContains(t, err, expectedErr.Error())
    96  		}
    97  	})
    98  
    99  	t.Run("results corrupted", func(t *testing.T) {
   100  		t.Parallel()
   101  
   102  		var (
   103  			stateDB         = memdb.NewMemDB()
   104  			corruptedResult = "totally valid amino"
   105  			hash            = []byte("tx hash")
   106  		)
   107  
   108  		// Save the "corrupted" result to the DB
   109  		stateDB.SetSync(CalcTxResultKey(hash), []byte(corruptedResult))
   110  
   111  		txResult, err := LoadTxResultIndex(stateDB, hash)
   112  		require.Nil(t, txResult)
   113  
   114  		assert.ErrorIs(t, err, errTxResultIndexCorrupted)
   115  	})
   116  }