From 4c3aa4dbacf961f90175674e6647f454f45b709a Mon Sep 17 00:00:00 2001 From: likhita-809 <78951027+likhita-809@users.noreply.github.com> Date: Mon, 27 Sep 2021 12:23:49 +0530 Subject: [PATCH] fix: Charge gas even when there are no entries in gaskv (#10218) ## Description Closes: #10127 Charge gas for seeks with empty ranges --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CHANGELOG.md | 1 + store/gaskv/store.go | 15 ++++++--------- store/gaskv/store_test.go | 21 +++++++++++++++++---- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d26e8e3a60c4..93c94e4923f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -120,6 +120,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes +* (store) [#10218](https://github.com/cosmos/cosmos-sdk/pull/10218) Charge gas even when there are no entries while seeking. * (x/genutil) [#10104](https://github.com/cosmos/cosmos-sdk/pull/10104) Ensure the `init` command reads the `--home` flag value correctly. * [\#9651](https://github.com/cosmos/cosmos-sdk/pull/9651) Change inconsistent limit of `0` to `MaxUint64` on InfiniteGasMeter and add GasRemaining func to GasMeter. * [\#9639](https://github.com/cosmos/cosmos-sdk/pull/9639) Check store keys length before accessing them by making sure that `key` is of length `m+1` (for `key[n:m]`) diff --git a/store/gaskv/store.go b/store/gaskv/store.go index aa9a29b7c153..6fbc43fcf050 100644 --- a/store/gaskv/store.go +++ b/store/gaskv/store.go @@ -108,9 +108,7 @@ func (gs *Store) iterator(start, end []byte, ascending bool) types.Iterator { } gi := newGasIterator(gs.gasMeter, gs.gasConfig, parent) - if gi.Valid() { - gi.(*gasIterator).consumeSeekGas() - } + gi.(*gasIterator).consumeSeekGas() return gi } @@ -143,10 +141,7 @@ func (gi *gasIterator) Valid() bool { // in the iterator. It incurs a flat gas cost for seeking and a variable gas // cost based on the current value's length if the iterator is valid. func (gi *gasIterator) Next() { - if gi.Valid() { - gi.consumeSeekGas() - } - + gi.consumeSeekGas() gi.parent.Next() } @@ -177,8 +172,10 @@ func (gi *gasIterator) Error() error { // consumeSeekGas consumes on each iteration step a flat gas cost and a variable gas cost // based on the current value's length. func (gi *gasIterator) consumeSeekGas() { - value := gi.Value() + if gi.Valid() { + value := gi.Value() - gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostPerByte*types.Gas(len(value)), types.GasValuePerByteDesc) + gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostPerByte*types.Gas(len(value)), types.GasValuePerByteDesc) + } gi.gasMeter.ConsumeGas(gi.gasConfig.IterNextCostFlat, types.GasIterNextCostFlatDesc) } diff --git a/store/gaskv/store_test.go b/store/gaskv/store_test.go index e111a72329a7..f926c7b7250e 100644 --- a/store/gaskv/store_test.go +++ b/store/gaskv/store_test.go @@ -4,13 +4,12 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/store/dbadapter" "github.com/cosmos/cosmos-sdk/store/gaskv" "github.com/cosmos/cosmos-sdk/store/types" - - "github.com/stretchr/testify/require" ) func bz(s string) []byte { return []byte(s) } @@ -41,14 +40,18 @@ func TestGasKVStoreBasic(t *testing.T) { func TestGasKVStoreIterator(t *testing.T) { mem := dbadapter.Store{DB: dbm.NewMemDB()} - meter := types.NewGasMeter(10000) + meter := types.NewGasMeter(100000) st := gaskv.NewStore(mem, meter, types.KVGasConfig()) require.False(t, st.Has(keyFmt(1))) require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty") require.Empty(t, st.Get(keyFmt(2)), "Expected `key2` to be empty") + require.Empty(t, st.Get(keyFmt(3)), "Expected `key3` to be empty") + st.Set(keyFmt(1), valFmt(1)) require.True(t, st.Has(keyFmt(1))) st.Set(keyFmt(2), valFmt(2)) + require.True(t, st.Has(keyFmt(2))) + st.Set(keyFmt(3), valFmt(0)) iterator := st.Iterator(nil, nil) start, end := iterator.Domain() @@ -71,8 +74,16 @@ func TestGasKVStoreIterator(t *testing.T) { vb := iterator.Value() require.Equal(t, vb, valFmt(2)) iterator.Next() + require.Equal(t, types.Gas(13377), meter.GasConsumed()) + kc := iterator.Key() + require.Equal(t, kc, keyFmt(3)) + vc := iterator.Value() + require.Equal(t, vc, valFmt(0)) + iterator.Next() + require.Equal(t, types.Gas(13446), meter.GasConsumed()) require.False(t, iterator.Valid()) require.Panics(t, iterator.Next) + require.Equal(t, types.Gas(13476), meter.GasConsumed()) require.NoError(t, iterator.Error()) reverseIterator := st.ReverseIterator(nil, nil) @@ -81,6 +92,8 @@ func TestGasKVStoreIterator(t *testing.T) { t.Fatal(err) } }) + require.Equal(t, reverseIterator.Key(), keyFmt(3)) + reverseIterator.Next() require.Equal(t, reverseIterator.Key(), keyFmt(2)) reverseIterator.Next() require.Equal(t, reverseIterator.Key(), keyFmt(1)) @@ -88,7 +101,7 @@ func TestGasKVStoreIterator(t *testing.T) { require.False(t, reverseIterator.Valid()) require.Panics(t, reverseIterator.Next) - require.Equal(t, types.Gas(9194), meter.GasConsumed()) + require.Equal(t, types.Gas(13782), meter.GasConsumed()) } func TestGasKVStoreOutOfGasSet(t *testing.T) {