From ce38d8f423cf0af9f7a8332bdf2e0fd72339fad9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 11 May 2018 20:02:05 +0200 Subject: [PATCH] Minor fix, testcases --- baseapp/baseapp.go | 7 +++-- baseapp/baseapp_test.go | 66 +++++++++++++++++++++++++++++++++++++++- store/gaskvstore_test.go | 42 ++++++++++++++++++++++--- 3 files changed, 107 insertions(+), 8 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 680635b49..50b915dcb 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -291,13 +291,14 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) { query := path[4:] var result sdk.Result switch query { - case "simulate": + case "/simulate": txBytes := req.Data tx, err := app.txDecoder(txBytes) if err != nil { result = err.Result() + } else { + result = app.Simulate(tx) } - result = app.runTx(true, true, txBytes, tx) default: result = sdk.ErrUnknownRequest(fmt.Sprintf("Unknown query: %s", path)).Result() } @@ -398,7 +399,7 @@ func (app *BaseApp) Check(tx sdk.Tx) (result sdk.Result) { } // nolint - full tx execution -func (app *BaseApp) CheckFull(tx sdk.Tx) (result sdk.Result) { +func (app *BaseApp) Simulate(tx sdk.Tx) (result sdk.Result) { return app.runTx(true, true, nil, tx) } diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index dbfd9f5a8..7a5d77ea5 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" "github.com/tendermint/go-crypto" @@ -16,6 +17,7 @@ import ( "github.com/tendermint/tmlibs/log" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) func defaultLogger() log.Logger { @@ -25,7 +27,9 @@ func defaultLogger() log.Logger { func newBaseApp(name string) *BaseApp { logger := defaultLogger() db := dbm.NewMemDB() - return NewBaseApp(name, nil, logger, db, 10000) + codec := wire.NewCodec() + wire.RegisterCrypto(codec) + return NewBaseApp(name, codec, logger, db, 10000) } func TestMountStores(t *testing.T) { @@ -260,6 +264,66 @@ func TestDeliverTx(t *testing.T) { } } +func TestSimulateTx(t *testing.T) { + app := newBaseApp(t.Name()) + + // make a cap key and mount the store + capKey := sdk.NewKVStoreKey("main") + app.MountStoresIAVL(capKey) + err := app.LoadLatestVersion(capKey) // needed to make stores non-nil + assert.Nil(t, err) + + counter := 0 + app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return }) + app.Router().AddRoute(msgType, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + ctx.GasMeter().ConsumeGas(10, "test") + store := ctx.KVStore(capKey) + // ensure store is never written + require.Nil(t, store.Get([]byte("key"))) + store.Set([]byte("key"), []byte("value")) + // check we can see the current header + thisHeader := ctx.BlockHeader() + height := int64(counter) + assert.Equal(t, height, thisHeader.Height) + counter++ + return sdk.Result{} + }) + + tx := testUpdatePowerTx{} // doesn't matter + header := abci.Header{AppHash: []byte("apphash")} + + app.SetTxDecoder(func(txBytes []byte) (sdk.Tx, sdk.Error) { + var ttx testUpdatePowerTx + fromJSON(txBytes, &ttx) + return ttx, nil + }) + + nBlocks := 3 + for blockN := 0; blockN < nBlocks; blockN++ { + // block1 + header.Height = int64(blockN + 1) + app.BeginBlock(abci.RequestBeginBlock{Header: header}) + result := app.Simulate(tx) + require.Equal(t, result.Code, sdk.ABCICodeOK) + require.Equal(t, result.GasUsed, int64(80)) + counter-- + encoded, err := json.Marshal(tx) + require.Nil(t, err) + query := abci.RequestQuery{ + Path: "/app/simulate", + Data: encoded, + } + queryResult := app.Query(query) + require.Equal(t, queryResult.Code, uint32(sdk.ABCICodeOK)) + var res sdk.Result + app.codec.MustUnmarshalBinary(queryResult.Value, &res) + require.Equal(t, res.Code, sdk.ABCICodeOK) + require.Equal(t, res.GasUsed, int64(80)) + app.EndBlock(abci.RequestEndBlock{}) + app.Commit() + } +} + // Test that transactions exceeding gas limits fail func TestTxGasLimits(t *testing.T) { logger := defaultLogger() diff --git a/store/gaskvstore_test.go b/store/gaskvstore_test.go index 4879c327c..524dc5323 100644 --- a/store/gaskvstore_test.go +++ b/store/gaskvstore_test.go @@ -18,17 +18,51 @@ func TestGasKVStoreBasic(t *testing.T) { mem := dbStoreAdapter{dbm.NewMemDB()} meter := sdk.NewGasMeter(1000) st := NewGasKVStore(meter, mem) - require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty") - - mem.Set(keyFmt(1), valFmt(1)) st.Set(keyFmt(1), valFmt(1)) require.Equal(t, valFmt(1), st.Get(keyFmt(1))) + st.Delete(keyFmt(1)) + require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty") + require.Equal(t, meter.GasConsumed(), sdk.Gas(183)) } -func TestGasKVStoreOutOfGas(t *testing.T) { +func TestGasKVStoreIterator(t *testing.T) { + mem := dbStoreAdapter{dbm.NewMemDB()} + meter := sdk.NewGasMeter(1000) + st := NewGasKVStore(meter, mem) + require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty") + require.Empty(t, st.Get(keyFmt(2)), "Expected `key2` to be empty") + st.Set(keyFmt(1), valFmt(1)) + st.Set(keyFmt(2), valFmt(2)) + iterator := st.Iterator(nil, nil) + ka := iterator.Key() + require.Equal(t, ka, keyFmt(1)) + va := iterator.Value() + require.Equal(t, va, valFmt(1)) + iterator.Next() + kb := iterator.Key() + require.Equal(t, kb, keyFmt(2)) + vb := iterator.Value() + require.Equal(t, vb, valFmt(2)) + iterator.Next() + require.False(t, iterator.Valid()) + require.Panics(t, iterator.Next) + require.Equal(t, meter.GasConsumed(), sdk.Gas(356)) +} + +func TestGasKVStoreOutOfGasSet(t *testing.T) { mem := dbStoreAdapter{dbm.NewMemDB()} meter := sdk.NewGasMeter(0) st := NewGasKVStore(meter, mem) require.Panics(t, func() { st.Set(keyFmt(1), valFmt(1)) }, "Expected out-of-gas") } + +func TestGasKVStoreOutOfGasIterator(t *testing.T) { + mem := dbStoreAdapter{dbm.NewMemDB()} + meter := sdk.NewGasMeter(200) + st := NewGasKVStore(meter, mem) + st.Set(keyFmt(1), valFmt(1)) + iterator := st.Iterator(nil, nil) + iterator.Next() + require.Panics(t, func() { iterator.Value() }, "Expected out-of-gas") +}