github.com/ledgerwatch/erigon-lib@v1.0.0/kv/memdb/memory_mutation_test.go (about)

     1  /*
     2     Copyright 2022 Erigon contributors
     3     Licensed under the Apache License, Version 2.0 (the "License");
     4     you may not use this file except in compliance with the License.
     5     You may obtain a copy of the License at
     6         http://www.apache.org/licenses/LICENSE-2.0
     7     Unless required by applicable law or agreed to in writing, software
     8     distributed under the License is distributed on an "AS IS" BASIS,
     9     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10     See the License for the specific language governing permissions and
    11     limitations under the License.
    12  */
    13  
    14  package memdb
    15  
    16  import (
    17  	"testing"
    18  
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/ledgerwatch/erigon-lib/kv"
    23  )
    24  
    25  func initializeDbNonDupSort(rwTx kv.RwTx) {
    26  	rwTx.Put(kv.HashedAccounts, []byte("AAAA"), []byte("value"))
    27  	rwTx.Put(kv.HashedAccounts, []byte("CAAA"), []byte("value1"))
    28  	rwTx.Put(kv.HashedAccounts, []byte("CBAA"), []byte("value2"))
    29  	rwTx.Put(kv.HashedAccounts, []byte("CCAA"), []byte("value3"))
    30  }
    31  
    32  func TestPutAppendHas(t *testing.T) {
    33  	_, rwTx := NewTestTx(t)
    34  
    35  	initializeDbNonDupSort(rwTx)
    36  
    37  	batch := NewMemoryBatch(rwTx, "")
    38  	require.NoError(t, batch.Append(kv.HashedAccounts, []byte("AAAA"), []byte("value1.5")))
    39  	require.Error(t, batch.Append(kv.HashedAccounts, []byte("AAAA"), []byte("value1.3")))
    40  	require.NoError(t, batch.Put(kv.HashedAccounts, []byte("AAAA"), []byte("value1.3")))
    41  	require.NoError(t, batch.Append(kv.HashedAccounts, []byte("CBAA"), []byte("value3.5")))
    42  	require.Error(t, batch.Append(kv.HashedAccounts, []byte("CBAA"), []byte("value3.1")))
    43  	require.NoError(t, batch.AppendDup(kv.HashedAccounts, []byte("CBAA"), []byte("value3.1")))
    44  	require.Error(t, batch.Append(kv.HashedAccounts, []byte("AAAA"), []byte("value1.3")))
    45  
    46  	require.Nil(t, batch.Flush(rwTx))
    47  
    48  	exist, err := batch.Has(kv.HashedAccounts, []byte("AAAA"))
    49  	require.Nil(t, err)
    50  	require.Equal(t, exist, true)
    51  
    52  	val, err := batch.GetOne(kv.HashedAccounts, []byte("AAAA"))
    53  	require.Nil(t, err)
    54  	require.Equal(t, val, []byte("value1.3"))
    55  
    56  	exist, err = batch.Has(kv.HashedAccounts, []byte("KKKK"))
    57  	require.Nil(t, err)
    58  	require.Equal(t, exist, false)
    59  }
    60  
    61  func TestLastMiningDB(t *testing.T) {
    62  	_, rwTx := NewTestTx(t)
    63  
    64  	initializeDbNonDupSort(rwTx)
    65  
    66  	batch := NewMemoryBatch(rwTx, "")
    67  	batch.Put(kv.HashedAccounts, []byte("BAAA"), []byte("value4"))
    68  	batch.Put(kv.HashedAccounts, []byte("BCAA"), []byte("value5"))
    69  
    70  	cursor, err := batch.Cursor(kv.HashedAccounts)
    71  	require.NoError(t, err)
    72  
    73  	key, value, err := cursor.Last()
    74  	require.NoError(t, err)
    75  
    76  	require.Equal(t, key, []byte("CCAA"))
    77  	require.Equal(t, value, []byte("value3"))
    78  
    79  	key, value, err = cursor.Next()
    80  	require.NoError(t, err)
    81  	require.Equal(t, key, []byte(nil))
    82  	require.Equal(t, value, []byte(nil))
    83  }
    84  
    85  func TestLastMiningMem(t *testing.T) {
    86  	_, rwTx := NewTestTx(t)
    87  
    88  	initializeDbNonDupSort(rwTx)
    89  
    90  	batch := NewMemoryBatch(rwTx, "")
    91  	batch.Put(kv.HashedAccounts, []byte("BAAA"), []byte("value4"))
    92  	batch.Put(kv.HashedAccounts, []byte("DCAA"), []byte("value5"))
    93  
    94  	cursor, err := batch.Cursor(kv.HashedAccounts)
    95  	require.NoError(t, err)
    96  
    97  	key, value, err := cursor.Last()
    98  	require.NoError(t, err)
    99  
   100  	require.Equal(t, key, []byte("DCAA"))
   101  	require.Equal(t, value, []byte("value5"))
   102  
   103  	key, value, err = cursor.Next()
   104  	require.NoError(t, err)
   105  	require.Equal(t, key, []byte(nil))
   106  	require.Equal(t, value, []byte(nil))
   107  }
   108  
   109  func TestDeleteMining(t *testing.T) {
   110  	_, rwTx := NewTestTx(t)
   111  
   112  	initializeDbNonDupSort(rwTx)
   113  	batch := NewMemoryBatch(rwTx, "")
   114  	batch.Put(kv.HashedAccounts, []byte("BAAA"), []byte("value4"))
   115  	batch.Put(kv.HashedAccounts, []byte("DCAA"), []byte("value5"))
   116  	batch.Put(kv.HashedAccounts, []byte("FCAA"), []byte("value5"))
   117  
   118  	batch.Delete(kv.HashedAccounts, []byte("BAAA"))
   119  	batch.Delete(kv.HashedAccounts, []byte("CBAA"))
   120  
   121  	cursor, err := batch.Cursor(kv.HashedAccounts)
   122  	require.NoError(t, err)
   123  
   124  	key, value, err := cursor.SeekExact([]byte("BAAA"))
   125  	require.NoError(t, err)
   126  	require.Equal(t, key, []byte(nil))
   127  	require.Equal(t, value, []byte(nil))
   128  
   129  	key, value, err = cursor.SeekExact([]byte("CBAA"))
   130  	require.NoError(t, err)
   131  	require.Equal(t, key, []byte(nil))
   132  	require.Equal(t, value, []byte(nil))
   133  }
   134  
   135  func TestFlush(t *testing.T) {
   136  	_, rwTx := NewTestTx(t)
   137  
   138  	initializeDbNonDupSort(rwTx)
   139  	batch := NewMemoryBatch(rwTx, "")
   140  	batch.Put(kv.HashedAccounts, []byte("BAAA"), []byte("value4"))
   141  	batch.Put(kv.HashedAccounts, []byte("AAAA"), []byte("value5"))
   142  	batch.Put(kv.HashedAccounts, []byte("FCAA"), []byte("value5"))
   143  
   144  	require.NoError(t, batch.Flush(rwTx))
   145  
   146  	value, err := rwTx.GetOne(kv.HashedAccounts, []byte("BAAA"))
   147  	require.NoError(t, err)
   148  	require.Equal(t, value, []byte("value4"))
   149  
   150  	value, err = rwTx.GetOne(kv.HashedAccounts, []byte("AAAA"))
   151  	require.NoError(t, err)
   152  	require.Equal(t, value, []byte("value5"))
   153  }
   154  
   155  func TestForEach(t *testing.T) {
   156  	_, rwTx := NewTestTx(t)
   157  
   158  	initializeDbNonDupSort(rwTx)
   159  
   160  	batch := NewMemoryBatch(rwTx, "")
   161  	batch.Put(kv.HashedAccounts, []byte("FCAA"), []byte("value5"))
   162  	require.NoError(t, batch.Flush(rwTx))
   163  
   164  	var keys []string
   165  	var values []string
   166  	err := batch.ForEach(kv.HashedAccounts, []byte("XYAZ"), func(k, v []byte) error {
   167  		keys = append(keys, string(k))
   168  		values = append(values, string(v))
   169  		return nil
   170  	})
   171  	require.Nil(t, err)
   172  	require.Nil(t, keys)
   173  	require.Nil(t, values)
   174  
   175  	err = batch.ForEach(kv.HashedAccounts, []byte("CC"), func(k, v []byte) error {
   176  		keys = append(keys, string(k))
   177  		values = append(values, string(v))
   178  		return nil
   179  	})
   180  	require.Nil(t, err)
   181  	require.Equal(t, []string{"CCAA", "FCAA"}, keys)
   182  	require.Equal(t, []string{"value3", "value5"}, values)
   183  
   184  	var keys1 []string
   185  	var values1 []string
   186  
   187  	err = batch.ForEach(kv.HashedAccounts, []byte("A"), func(k, v []byte) error {
   188  		keys1 = append(keys1, string(k))
   189  		values1 = append(values1, string(v))
   190  		return nil
   191  	})
   192  	require.Nil(t, err)
   193  	require.Equal(t, []string{"AAAA", "CAAA", "CBAA", "CCAA", "FCAA"}, keys1)
   194  	require.Equal(t, []string{"value", "value1", "value2", "value3", "value5"}, values1)
   195  }
   196  
   197  func TestForPrefix(t *testing.T) {
   198  	_, rwTx := NewTestTx(t)
   199  
   200  	initializeDbNonDupSort(rwTx)
   201  
   202  	batch := NewMemoryBatch(rwTx, "")
   203  	var keys1 []string
   204  	var values1 []string
   205  
   206  	err := batch.ForPrefix(kv.HashedAccounts, []byte("AB"), func(k, v []byte) error {
   207  		keys1 = append(keys1, string(k))
   208  		values1 = append(values1, string(v))
   209  		return nil
   210  	})
   211  	require.Nil(t, err)
   212  	require.Nil(t, keys1)
   213  	require.Nil(t, values1)
   214  
   215  	err = batch.ForPrefix(kv.HashedAccounts, []byte("AAAA"), func(k, v []byte) error {
   216  		keys1 = append(keys1, string(k))
   217  		values1 = append(values1, string(v))
   218  		return nil
   219  	})
   220  	require.Nil(t, err)
   221  	require.Equal(t, []string{"AAAA"}, keys1)
   222  	require.Equal(t, []string{"value"}, values1)
   223  
   224  	var keys []string
   225  	var values []string
   226  	err = batch.ForPrefix(kv.HashedAccounts, []byte("C"), func(k, v []byte) error {
   227  		keys = append(keys, string(k))
   228  		values = append(values, string(v))
   229  		return nil
   230  	})
   231  	require.Nil(t, err)
   232  	require.Equal(t, []string{"CAAA", "CBAA", "CCAA"}, keys)
   233  	require.Equal(t, []string{"value1", "value2", "value3"}, values)
   234  }
   235  
   236  func TestForAmount(t *testing.T) {
   237  	_, rwTx := NewTestTx(t)
   238  
   239  	initializeDbNonDupSort(rwTx)
   240  
   241  	batch := NewMemoryBatch(rwTx, "")
   242  	defer batch.Close()
   243  
   244  	var keys []string
   245  	var values []string
   246  	err := batch.ForAmount(kv.HashedAccounts, []byte("C"), uint32(3), func(k, v []byte) error {
   247  		keys = append(keys, string(k))
   248  		values = append(values, string(v))
   249  		return nil
   250  	})
   251  
   252  	require.Nil(t, err)
   253  	require.Equal(t, []string{"CAAA", "CBAA", "CCAA"}, keys)
   254  	require.Equal(t, []string{"value1", "value2", "value3"}, values)
   255  
   256  	var keys1 []string
   257  	var values1 []string
   258  	err = batch.ForAmount(kv.HashedAccounts, []byte("C"), uint32(10), func(k, v []byte) error {
   259  		keys1 = append(keys1, string(k))
   260  		values1 = append(values1, string(v))
   261  		return nil
   262  	})
   263  
   264  	require.Nil(t, err)
   265  	require.Equal(t, []string{"CAAA", "CBAA", "CCAA"}, keys1)
   266  	require.Equal(t, []string{"value1", "value2", "value3"}, values1)
   267  }
   268  
   269  func TestGetOneAfterClearBucket(t *testing.T) {
   270  	_, rwTx := NewTestTx(t)
   271  
   272  	initializeDbNonDupSort(rwTx)
   273  
   274  	batch := NewMemoryBatch(rwTx, "")
   275  	defer batch.Close()
   276  
   277  	err := batch.ClearBucket(kv.HashedAccounts)
   278  	require.Nil(t, err)
   279  
   280  	cond := batch.isTableCleared(kv.HashedAccounts)
   281  	require.True(t, cond)
   282  
   283  	val, err := batch.GetOne(kv.HashedAccounts, []byte("A"))
   284  	require.Nil(t, err)
   285  	require.Nil(t, val)
   286  
   287  	val, err = batch.GetOne(kv.HashedAccounts, []byte("AAAA"))
   288  	require.Nil(t, err)
   289  	require.Nil(t, val)
   290  }
   291  
   292  func TestSeekExactAfterClearBucket(t *testing.T) {
   293  	_, rwTx := NewTestTx(t)
   294  
   295  	initializeDbNonDupSort(rwTx)
   296  
   297  	batch := NewMemoryBatch(rwTx, "")
   298  	defer batch.Close()
   299  
   300  	err := batch.ClearBucket(kv.HashedAccounts)
   301  	require.Nil(t, err)
   302  
   303  	cond := batch.isTableCleared(kv.HashedAccounts)
   304  	require.True(t, cond)
   305  
   306  	cursor, err := batch.RwCursor(kv.HashedAccounts)
   307  	require.NoError(t, err)
   308  
   309  	key, val, err := cursor.SeekExact([]byte("AAAA"))
   310  	require.Nil(t, err)
   311  	assert.Nil(t, key)
   312  	assert.Nil(t, val)
   313  
   314  	err = cursor.Put([]byte("AAAA"), []byte("valueX"))
   315  	require.Nil(t, err)
   316  
   317  	key, val, err = cursor.SeekExact([]byte("AAAA"))
   318  	require.Nil(t, err)
   319  	assert.Equal(t, []byte("AAAA"), key)
   320  	assert.Equal(t, []byte("valueX"), val)
   321  
   322  	key, val, err = cursor.SeekExact([]byte("BBBB"))
   323  	require.Nil(t, err)
   324  	assert.Nil(t, key)
   325  	assert.Nil(t, val)
   326  }
   327  
   328  func TestFirstAfterClearBucket(t *testing.T) {
   329  	_, rwTx := NewTestTx(t)
   330  
   331  	initializeDbNonDupSort(rwTx)
   332  
   333  	batch := NewMemoryBatch(rwTx, "")
   334  	defer batch.Close()
   335  
   336  	err := batch.ClearBucket(kv.HashedAccounts)
   337  	require.Nil(t, err)
   338  
   339  	err = batch.Put(kv.HashedAccounts, []byte("BBBB"), []byte("value5"))
   340  	require.Nil(t, err)
   341  
   342  	cursor, err := batch.Cursor(kv.HashedAccounts)
   343  	require.NoError(t, err)
   344  
   345  	key, val, err := cursor.First()
   346  	require.Nil(t, err)
   347  	assert.Equal(t, []byte("BBBB"), key)
   348  	assert.Equal(t, []byte("value5"), val)
   349  
   350  	key, val, err = cursor.Next()
   351  	require.Nil(t, err)
   352  	assert.Nil(t, key)
   353  	assert.Nil(t, val)
   354  }
   355  
   356  func TestIncReadSequence(t *testing.T) {
   357  	_, rwTx := NewTestTx(t)
   358  
   359  	initializeDbNonDupSort(rwTx)
   360  
   361  	batch := NewMemoryBatch(rwTx, "")
   362  	defer batch.Close()
   363  
   364  	_, err := batch.IncrementSequence(kv.HashedAccounts, uint64(12))
   365  	require.Nil(t, err)
   366  
   367  	val, err := batch.ReadSequence(kv.HashedAccounts)
   368  	require.Nil(t, err)
   369  	require.Equal(t, val, uint64(12))
   370  }
   371  
   372  func initializeDbDupSort(rwTx kv.RwTx) {
   373  	rwTx.Put(kv.AccountChangeSet, []byte("key1"), []byte("value1.1"))
   374  	rwTx.Put(kv.AccountChangeSet, []byte("key3"), []byte("value3.1"))
   375  	rwTx.Put(kv.AccountChangeSet, []byte("key1"), []byte("value1.3"))
   376  	rwTx.Put(kv.AccountChangeSet, []byte("key3"), []byte("value3.3"))
   377  }
   378  
   379  func TestNext(t *testing.T) {
   380  	_, rwTx := NewTestTx(t)
   381  
   382  	initializeDbDupSort(rwTx)
   383  
   384  	batch := NewMemoryBatch(rwTx, "")
   385  	defer batch.Close()
   386  
   387  	batch.Put(kv.AccountChangeSet, []byte("key1"), []byte("value1.2"))
   388  
   389  	cursor, err := batch.CursorDupSort(kv.AccountChangeSet)
   390  	require.NoError(t, err)
   391  
   392  	k, v, err := cursor.First()
   393  	require.Nil(t, err)
   394  	assert.Equal(t, []byte("key1"), k)
   395  	assert.Equal(t, []byte("value1.1"), v)
   396  
   397  	k, v, err = cursor.Next()
   398  	require.Nil(t, err)
   399  	assert.Equal(t, []byte("key1"), k)
   400  	assert.Equal(t, []byte("value1.2"), v)
   401  
   402  	k, v, err = cursor.Next()
   403  	require.Nil(t, err)
   404  	assert.Equal(t, []byte("key1"), k)
   405  	assert.Equal(t, []byte("value1.3"), v)
   406  
   407  	k, v, err = cursor.Next()
   408  	require.Nil(t, err)
   409  	assert.Equal(t, []byte("key3"), k)
   410  	assert.Equal(t, []byte("value3.1"), v)
   411  
   412  	k, v, err = cursor.Next()
   413  	require.Nil(t, err)
   414  	assert.Equal(t, []byte("key3"), k)
   415  	assert.Equal(t, []byte("value3.3"), v)
   416  
   417  	k, v, err = cursor.Next()
   418  	require.Nil(t, err)
   419  	assert.Nil(t, k)
   420  	assert.Nil(t, v)
   421  }
   422  
   423  func TestNextNoDup(t *testing.T) {
   424  	_, rwTx := NewTestTx(t)
   425  
   426  	initializeDbDupSort(rwTx)
   427  
   428  	batch := NewMemoryBatch(rwTx, "")
   429  	defer batch.Close()
   430  
   431  	batch.Put(kv.AccountChangeSet, []byte("key2"), []byte("value2.1"))
   432  	batch.Put(kv.AccountChangeSet, []byte("key2"), []byte("value2.2"))
   433  
   434  	cursor, err := batch.CursorDupSort(kv.AccountChangeSet)
   435  	require.NoError(t, err)
   436  
   437  	k, _, err := cursor.First()
   438  	require.Nil(t, err)
   439  	assert.Equal(t, []byte("key1"), k)
   440  
   441  	k, _, err = cursor.NextNoDup()
   442  	require.Nil(t, err)
   443  	assert.Equal(t, []byte("key2"), k)
   444  
   445  	k, _, err = cursor.NextNoDup()
   446  	require.Nil(t, err)
   447  	assert.Equal(t, []byte("key3"), k)
   448  }
   449  
   450  func TestDeleteCurrentDuplicates(t *testing.T) {
   451  	_, rwTx := NewTestTx(t)
   452  
   453  	initializeDbDupSort(rwTx)
   454  
   455  	batch := NewMemoryBatch(rwTx, "")
   456  	defer batch.Close()
   457  
   458  	cursor, err := batch.RwCursorDupSort(kv.AccountChangeSet)
   459  	require.NoError(t, err)
   460  
   461  	require.NoError(t, cursor.Put([]byte("key3"), []byte("value3.2")))
   462  
   463  	key, _, err := cursor.SeekExact([]byte("key3"))
   464  	require.NoError(t, err)
   465  	require.Equal(t, []byte("key3"), key)
   466  
   467  	require.NoError(t, cursor.DeleteCurrentDuplicates())
   468  
   469  	require.NoError(t, batch.Flush(rwTx))
   470  
   471  	var keys []string
   472  	var values []string
   473  	err = rwTx.ForEach(kv.AccountChangeSet, nil, func(k, v []byte) error {
   474  		keys = append(keys, string(k))
   475  		values = append(values, string(v))
   476  		return nil
   477  	})
   478  	require.NoError(t, err)
   479  
   480  	require.Equal(t, []string{"key1", "key1"}, keys)
   481  	require.Equal(t, []string{"value1.1", "value1.3"}, values)
   482  }
   483  
   484  func TestSeekBothRange(t *testing.T) {
   485  	_, rwTx := NewTestTx(t)
   486  
   487  	rwTx.Put(kv.AccountChangeSet, []byte("key1"), []byte("value1.1"))
   488  	rwTx.Put(kv.AccountChangeSet, []byte("key3"), []byte("value3.3"))
   489  
   490  	batch := NewMemoryBatch(rwTx, "")
   491  	defer batch.Close()
   492  
   493  	cursor, err := batch.RwCursorDupSort(kv.AccountChangeSet)
   494  	require.NoError(t, err)
   495  
   496  	require.NoError(t, cursor.Put([]byte("key3"), []byte("value3.1")))
   497  	require.NoError(t, cursor.Put([]byte("key1"), []byte("value1.3")))
   498  
   499  	v, err := cursor.SeekBothRange([]byte("key2"), []byte("value1.2"))
   500  	require.NoError(t, err)
   501  	// SeekBothRange does exact match of the key, but range match of the value, so we get nil here
   502  	require.Nil(t, v)
   503  
   504  	v, err = cursor.SeekBothRange([]byte("key3"), []byte("value3.2"))
   505  	require.NoError(t, err)
   506  	require.Equal(t, "value3.3", string(v))
   507  }
   508  
   509  func initializeDbAutoConversion(rwTx kv.RwTx) {
   510  	rwTx.Put(kv.PlainState, []byte("A"), []byte("0"))
   511  	rwTx.Put(kv.PlainState, []byte("A..........................._______________________________A"), []byte("1"))
   512  	rwTx.Put(kv.PlainState, []byte("A..........................._______________________________C"), []byte("2"))
   513  	rwTx.Put(kv.PlainState, []byte("B"), []byte("8"))
   514  	rwTx.Put(kv.PlainState, []byte("C"), []byte("9"))
   515  	rwTx.Put(kv.PlainState, []byte("D..........................._______________________________A"), []byte("3"))
   516  	rwTx.Put(kv.PlainState, []byte("D..........................._______________________________C"), []byte("4"))
   517  }
   518  
   519  func TestAutoConversion(t *testing.T) {
   520  	_, rwTx := NewTestTx(t)
   521  
   522  	initializeDbAutoConversion(rwTx)
   523  
   524  	batch := NewMemoryBatch(rwTx, "")
   525  	defer batch.Close()
   526  
   527  	c, err := batch.RwCursor(kv.PlainState)
   528  	require.NoError(t, err)
   529  
   530  	// key length conflict
   531  	require.Error(t, c.Put([]byte("A..........................."), []byte("?")))
   532  
   533  	require.NoError(t, c.Delete([]byte("A..........................._______________________________A")))
   534  	require.NoError(t, c.Put([]byte("B"), []byte("7")))
   535  	require.NoError(t, c.Delete([]byte("C")))
   536  	require.NoError(t, c.Put([]byte("D..........................._______________________________C"), []byte("6")))
   537  	require.NoError(t, c.Put([]byte("D..........................._______________________________E"), []byte("5")))
   538  
   539  	k, v, err := c.First()
   540  	require.NoError(t, err)
   541  	assert.Equal(t, []byte("A"), k)
   542  	assert.Equal(t, []byte("0"), v)
   543  
   544  	k, v, err = c.Next()
   545  	require.NoError(t, err)
   546  	assert.Equal(t, []byte("A..........................._______________________________C"), k)
   547  	assert.Equal(t, []byte("2"), v)
   548  
   549  	k, v, err = c.Next()
   550  	require.NoError(t, err)
   551  	assert.Equal(t, []byte("B"), k)
   552  	assert.Equal(t, []byte("7"), v)
   553  
   554  	k, v, err = c.Next()
   555  	require.NoError(t, err)
   556  	assert.Equal(t, []byte("D..........................._______________________________A"), k)
   557  	assert.Equal(t, []byte("3"), v)
   558  
   559  	k, v, err = c.Next()
   560  	require.NoError(t, err)
   561  	assert.Equal(t, []byte("D..........................._______________________________C"), k)
   562  	assert.Equal(t, []byte("6"), v)
   563  
   564  	k, v, err = c.Next()
   565  	require.NoError(t, err)
   566  	assert.Equal(t, []byte("D..........................._______________________________E"), k)
   567  	assert.Equal(t, []byte("5"), v)
   568  
   569  	k, v, err = c.Next()
   570  	require.NoError(t, err)
   571  	assert.Nil(t, k)
   572  	assert.Nil(t, v)
   573  }
   574  
   575  func TestAutoConversionDelete(t *testing.T) {
   576  	_, rwTx := NewTestTx(t)
   577  
   578  	initializeDbAutoConversion(rwTx)
   579  
   580  	batch := NewMemoryBatch(rwTx, "")
   581  	defer batch.Close()
   582  
   583  	c, err := batch.RwCursor(kv.PlainState)
   584  	require.NoError(t, err)
   585  
   586  	require.NoError(t, c.Delete([]byte("A..........................._______________________________A")))
   587  	require.NoError(t, c.Delete([]byte("A..........................._______________________________C")))
   588  	require.NoError(t, c.Delete([]byte("B")))
   589  	require.NoError(t, c.Delete([]byte("C")))
   590  
   591  	k, v, err := c.First()
   592  	require.NoError(t, err)
   593  	assert.Equal(t, []byte("A"), k)
   594  	assert.Equal(t, []byte("0"), v)
   595  
   596  	k, v, err = c.Next()
   597  	require.NoError(t, err)
   598  	assert.Equal(t, []byte("D..........................._______________________________A"), k)
   599  	assert.Equal(t, []byte("3"), v)
   600  
   601  	k, v, err = c.Next()
   602  	require.NoError(t, err)
   603  	assert.Equal(t, []byte("D..........................._______________________________C"), k)
   604  	assert.Equal(t, []byte("4"), v)
   605  
   606  	k, v, err = c.Next()
   607  	require.NoError(t, err)
   608  	assert.Nil(t, k)
   609  	assert.Nil(t, v)
   610  }
   611  
   612  func TestAutoConversionSeekBothRange(t *testing.T) {
   613  	_, rwTx := NewTestTx(t)
   614  
   615  	initializeDbAutoConversion(rwTx)
   616  
   617  	batch := NewMemoryBatch(rwTx, "")
   618  	defer batch.Close()
   619  
   620  	c, err := batch.RwCursorDupSort(kv.PlainState)
   621  	require.NoError(t, err)
   622  
   623  	require.NoError(t, c.Delete([]byte("A..........................._______________________________A")))
   624  	require.NoError(t, c.Put([]byte("D..........................._______________________________C"), []byte("6")))
   625  	require.NoError(t, c.Put([]byte("D..........................._______________________________E"), []byte("5")))
   626  
   627  	v, err := c.SeekBothRange([]byte("A..........................."), []byte("_______________________________A"))
   628  	require.NoError(t, err)
   629  	assert.Equal(t, []byte("_______________________________C2"), v)
   630  
   631  	_, v, err = c.NextDup()
   632  	require.NoError(t, err)
   633  	assert.Nil(t, v)
   634  
   635  	v, err = c.SeekBothRange([]byte("A..........................."), []byte("_______________________________X"))
   636  	require.NoError(t, err)
   637  	assert.Nil(t, v)
   638  
   639  	v, err = c.SeekBothRange([]byte("B..........................."), []byte(""))
   640  	require.NoError(t, err)
   641  	assert.Nil(t, v)
   642  
   643  	v, err = c.SeekBothRange([]byte("C..........................."), []byte(""))
   644  	require.NoError(t, err)
   645  	assert.Nil(t, v)
   646  
   647  	v, err = c.SeekBothRange([]byte("D..........................."), []byte(""))
   648  	require.NoError(t, err)
   649  	assert.Equal(t, []byte("_______________________________A3"), v)
   650  
   651  	_, v, err = c.NextDup()
   652  	require.NoError(t, err)
   653  	assert.Equal(t, []byte("_______________________________C6"), v)
   654  
   655  	_, v, err = c.NextDup()
   656  	require.NoError(t, err)
   657  	assert.Equal(t, []byte("_______________________________E5"), v)
   658  
   659  	_, v, err = c.NextDup()
   660  	require.NoError(t, err)
   661  	assert.Nil(t, v)
   662  
   663  	v, err = c.SeekBothRange([]byte("X..........................."), []byte("_______________________________Y"))
   664  	require.NoError(t, err)
   665  	assert.Nil(t, v)
   666  }