github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/keeper/ante_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	types2 "github.com/fibonacci-chain/fbc/libs/tendermint/types"
     8  
     9  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    10  
    11  	"github.com/fibonacci-chain/fbc/x/wasm/keeper"
    12  
    13  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store"
    14  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    15  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    16  	dbm "github.com/fibonacci-chain/fbc/libs/tm-db"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  
    20  	"github.com/fibonacci-chain/fbc/x/wasm/types"
    21  )
    22  
    23  func TestCountTxDecorator(t *testing.T) {
    24  	types2.UnittestOnlySetMilestoneEarthHeight(1)
    25  	keyWasm := sdk.NewKVStoreKey(types.StoreKey)
    26  	db := dbm.NewMemDB()
    27  	ms := store.NewCommitMultiStore(db)
    28  	ms.MountStoreWithDB(keyWasm, sdk.StoreTypeIAVL, db)
    29  	require.NoError(t, ms.LoadLatestVersion())
    30  	const myCurrentBlockHeight = 100
    31  
    32  	specs := map[string]struct {
    33  		setupDB        func(t *testing.T, ctx sdk.Context)
    34  		simulate       bool
    35  		nextAssertAnte func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error)
    36  		expErr         bool
    37  	}{
    38  		"no initial counter set": {
    39  			setupDB: func(t *testing.T, ctx sdk.Context) {},
    40  			nextAssertAnte: func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
    41  				gotCounter, ok := types.TXCounter(ctx)
    42  				require.True(t, ok)
    43  				assert.Equal(t, uint32(0), gotCounter)
    44  				// and stored +1
    45  				bz := ctx.MultiStore().GetKVStore(keyWasm).Get(types.TXCounterPrefix)
    46  				assert.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, myCurrentBlockHeight, 0, 0, 0, 1}, bz)
    47  				return ctx, nil
    48  			},
    49  		},
    50  		"persistent counter incremented - big endian": {
    51  			setupDB: func(t *testing.T, ctx sdk.Context) {
    52  				bz := []byte{0, 0, 0, 0, 0, 0, 0, myCurrentBlockHeight, 1, 0, 0, 2}
    53  				ctx.MultiStore().GetKVStore(keyWasm).Set(types.TXCounterPrefix, bz)
    54  			},
    55  			nextAssertAnte: func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
    56  				gotCounter, ok := types.TXCounter(ctx)
    57  				require.True(t, ok)
    58  				assert.Equal(t, uint32(1<<24+2), gotCounter)
    59  				// and stored +1
    60  				bz := ctx.MultiStore().GetKVStore(keyWasm).Get(types.TXCounterPrefix)
    61  				assert.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, myCurrentBlockHeight, 1, 0, 0, 3}, bz)
    62  				return ctx, nil
    63  			},
    64  		},
    65  		"old height counter replaced": {
    66  			setupDB: func(t *testing.T, ctx sdk.Context) {
    67  				previousHeight := byte(myCurrentBlockHeight - 1)
    68  				bz := []byte{0, 0, 0, 0, 0, 0, 0, previousHeight, 0, 0, 0, 1}
    69  				ctx.MultiStore().GetKVStore(keyWasm).Set(types.TXCounterPrefix, bz)
    70  			},
    71  			nextAssertAnte: func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
    72  				gotCounter, ok := types.TXCounter(ctx)
    73  				require.True(t, ok)
    74  				assert.Equal(t, uint32(0), gotCounter)
    75  				// and stored +1
    76  				bz := ctx.MultiStore().GetKVStore(keyWasm).Get(types.TXCounterPrefix)
    77  				assert.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, myCurrentBlockHeight, 0, 0, 0, 1}, bz)
    78  				return ctx, nil
    79  			},
    80  		},
    81  		"simulation not persisted": {
    82  			setupDB: func(t *testing.T, ctx sdk.Context) {
    83  			},
    84  			simulate: true,
    85  			nextAssertAnte: func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
    86  				_, ok := types.TXCounter(ctx)
    87  				assert.False(t, ok)
    88  				require.True(t, simulate)
    89  				// and not stored
    90  				assert.False(t, ctx.MultiStore().GetKVStore(keyWasm).Has(types.TXCounterPrefix))
    91  				return ctx, nil
    92  			},
    93  		},
    94  	}
    95  	for name, spec := range specs {
    96  		t.Run(name, func(t *testing.T) {
    97  			ctx := sdk.NewContext(ms.CacheMultiStore(), abci.Header{
    98  				Height: myCurrentBlockHeight,
    99  				Time:   time.Date(2021, time.September, 27, 12, 0, 0, 0, time.UTC),
   100  			}, false, log.NewNopLogger())
   101  
   102  			spec.setupDB(t, ctx)
   103  			var anyTx sdk.Tx
   104  
   105  			// when
   106  			t.Log("name", name, "simluate", spec.simulate)
   107  			ante := keeper.NewCountTXDecorator(keyWasm)
   108  			_, gotErr := ante.AnteHandle(ctx, anyTx, spec.simulate, spec.nextAssertAnte)
   109  			if spec.expErr {
   110  				require.Error(t, gotErr)
   111  				return
   112  			}
   113  			require.NoError(t, gotErr)
   114  		})
   115  	}
   116  }
   117  
   118  func TestLimitSimulationGasDecorator(t *testing.T) {
   119  	var (
   120  		hundred sdk.Gas = 100
   121  		zero    sdk.Gas = 0
   122  	)
   123  	specs := map[string]struct {
   124  		customLimit *sdk.Gas
   125  		consumeGas  sdk.Gas
   126  		maxBlockGas int64
   127  		simulation  bool
   128  		expErr      interface{}
   129  	}{
   130  		"custom limit set": {
   131  			customLimit: &hundred,
   132  			consumeGas:  hundred + 1,
   133  			maxBlockGas: -1,
   134  			simulation:  true,
   135  			expErr:      sdk.ErrorOutOfGas{Descriptor: "testing"},
   136  		},
   137  		"block limit set": {
   138  			maxBlockGas: 100,
   139  			consumeGas:  hundred + 1,
   140  			simulation:  true,
   141  			expErr:      sdk.ErrorOutOfGas{Descriptor: "testing"},
   142  		},
   143  		"no limits set": {
   144  			maxBlockGas: -1,
   145  			consumeGas:  hundred + 1,
   146  			simulation:  true,
   147  		},
   148  		"both limits set, custom applies": {
   149  			customLimit: &hundred,
   150  			consumeGas:  hundred - 1,
   151  			maxBlockGas: 10,
   152  			simulation:  true,
   153  		},
   154  		"not a simulation": {
   155  			customLimit: &hundred,
   156  			consumeGas:  hundred + 1,
   157  			simulation:  false,
   158  		},
   159  		"zero custom limit": {
   160  			customLimit: &zero,
   161  			simulation:  true,
   162  			expErr:      "gas limit must not be zero",
   163  		},
   164  	}
   165  	for name, spec := range specs {
   166  		t.Run(name, func(t *testing.T) {
   167  			nextAnte := consumeGasAnteHandler(spec.consumeGas)
   168  			ctx := &sdk.Context{}
   169  			ctx.SetGasMeter(sdk.NewInfiniteGasMeter())
   170  			ctx.SetConsensusParams(&abci.ConsensusParams{Block: &abci.BlockParams{MaxGas: spec.maxBlockGas}})
   171  			// when
   172  			if spec.expErr != nil {
   173  				require.PanicsWithValue(t, spec.expErr, func() {
   174  					ante := keeper.NewLimitSimulationGasDecorator(spec.customLimit)
   175  					ante.AnteHandle(*ctx, nil, spec.simulation, nextAnte)
   176  				})
   177  				return
   178  			}
   179  			ante := keeper.NewLimitSimulationGasDecorator(spec.customLimit)
   180  			ante.AnteHandle(*ctx, nil, spec.simulation, nextAnte)
   181  		})
   182  	}
   183  }
   184  
   185  func consumeGasAnteHandler(gasToConsume sdk.Gas) sdk.AnteHandler {
   186  	return func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
   187  		ctx.GasMeter().ConsumeGas(gasToConsume, "testing")
   188  		return ctx, nil
   189  	}
   190  }