github.com/igggame/nebulas-go@v2.1.0+incompatible/common/mvccdb/mvccdb_test.go (about)

     1  // Copyright (C) 2018 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  package mvccdb
    20  
    21  import (
    22  	"os"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/nebulasio/go-nebulas/common/trie"
    27  	"github.com/nebulasio/go-nebulas/crypto/hash"
    28  	"github.com/nebulasio/go-nebulas/util/byteutils"
    29  
    30  	"github.com/stretchr/testify/assert"
    31  
    32  	"github.com/nebulasio/go-nebulas/storage"
    33  )
    34  
    35  func TestMVCCDB_NewMVCCDB(t *testing.T) {
    36  	storage, _ := storage.NewMemoryStorage()
    37  	db, err := NewMVCCDB(storage, false)
    38  	assert.Nil(t, err)
    39  
    40  	assert.False(t, db.isInTransaction)
    41  	assert.False(t, db.isPreparedDB)
    42  }
    43  
    44  func TestMVCCDB_FunctionEntryCondition(t *testing.T) {
    45  	stor, _ := storage.NewMemoryStorage()
    46  	db, _ := NewMVCCDB(stor, false)
    47  
    48  	assert.Nil(t, db.Begin())
    49  	assert.Equal(t, ErrUnsupportedNestedTransaction, db.Begin())
    50  	assert.Nil(t, db.Commit())
    51  	assert.Equal(t, ErrTransactionNotStarted, db.Commit())
    52  
    53  	assert.Nil(t, db.Begin())
    54  	assert.Nil(t, db.RollBack())
    55  	assert.Equal(t, ErrTransactionNotStarted, db.RollBack())
    56  
    57  	pdb, err := db.Prepare(nil)
    58  	assert.Nil(t, pdb)
    59  	assert.Error(t, ErrTransactionNotStarted, err)
    60  
    61  	tid := "tid"
    62  	assert.Nil(t, db.Begin())
    63  	pdb, err = db.Prepare(nil)
    64  	assert.Nil(t, pdb)
    65  	assert.Equal(t, ErrTidIsNil, err)
    66  
    67  	pdb, err = db.Prepare(tid)
    68  	assert.NotNil(t, pdb)
    69  	assert.Nil(t, err)
    70  
    71  	deps, err := pdb.CheckAndUpdate()
    72  	assert.Equal(t, 0, len(deps))
    73  	assert.Nil(t, err)
    74  
    75  	err = pdb.Reset()
    76  	assert.Nil(t, err)
    77  }
    78  
    79  func TestMVCCDB_KeyChangeOutOfMVCCDB(t *testing.T) {
    80  	stor, _ := storage.NewMemoryStorage()
    81  	db, _ := NewMVCCDB(stor, false)
    82  
    83  	db.Begin()
    84  
    85  	// get non-exist key.
    86  	key := []byte("key")
    87  	val, err := db.Get(key)
    88  	assert.Nil(t, val)
    89  	assert.Equal(t, storage.ErrKeyNotFound, err)
    90  
    91  	// put to storage.
    92  	stor.Put(key, []byte("value"))
    93  
    94  	// get again.
    95  	val, err = db.Get(key)
    96  	assert.Nil(t, val)
    97  	assert.Equal(t, storage.ErrKeyNotFound, err)
    98  }
    99  
   100  func TestMVCCDB_DirectOpts(t *testing.T) {
   101  	storage, _ := storage.NewMemoryStorage()
   102  	db, _ := NewMVCCDB(storage, false)
   103  
   104  	key := []byte("key")
   105  	val := []byte("val")
   106  
   107  	v, err := db.getFromStorage(key)
   108  	assert.Nil(t, v)
   109  	assert.NotNil(t, err)
   110  
   111  	err = db.putToStorage(key, val)
   112  	assert.Nil(t, err)
   113  
   114  	v, err = db.getFromStorage(key)
   115  	assert.Nil(t, err)
   116  	assert.Equal(t, val, v)
   117  
   118  	err = db.delFromStorage(key)
   119  	assert.Nil(t, err)
   120  
   121  	v, err = db.getFromStorage(key)
   122  	assert.Nil(t, v)
   123  	assert.NotNil(t, err)
   124  }
   125  
   126  func TestMVCCDB_OptsWithoutTransaction(t *testing.T) {
   127  	storage, _ := storage.NewMemoryStorage()
   128  	db, _ := NewMVCCDB(storage, false)
   129  
   130  	key := []byte("key")
   131  	val := []byte("val")
   132  
   133  	v, err := db.Get(key)
   134  	assert.Nil(t, v)
   135  	assert.NotNil(t, err)
   136  
   137  	err = db.Put(key, val)
   138  	assert.Nil(t, err)
   139  
   140  	v, err = db.Get(key)
   141  	assert.Nil(t, err)
   142  	assert.Equal(t, val, v)
   143  
   144  	err = db.Del(key)
   145  	assert.Nil(t, err)
   146  
   147  	v, err = db.Get(key)
   148  	assert.Nil(t, v)
   149  	assert.NotNil(t, err)
   150  }
   151  
   152  func TestMVCCDB_OptsWithinTransaction(t *testing.T) {
   153  	store, _ := storage.NewMemoryStorage()
   154  	db, _ := NewMVCCDB(store, false)
   155  
   156  	key := []byte("key")
   157  	val := []byte("val")
   158  
   159  	err := db.Begin()
   160  	assert.Nil(t, err)
   161  	assert.True(t, db.isInTransaction)
   162  
   163  	// unsupported nested transaction.
   164  	err = db.Begin()
   165  	assert.Equal(t, err, ErrUnsupportedNestedTransaction)
   166  
   167  	v, err := db.Get(key)
   168  	assert.Nil(t, v)
   169  	assert.Equal(t, err, storage.ErrKeyNotFound)
   170  
   171  	err = db.Put(key, val)
   172  	assert.Nil(t, err)
   173  
   174  	{
   175  		// other MVCCDB can't read before commit.
   176  		db2, _ := NewMVCCDB(store, false)
   177  		v, err := db2.Get(key)
   178  		assert.Nil(t, v)
   179  		assert.Equal(t, err, storage.ErrKeyNotFound)
   180  	}
   181  
   182  	// commit.
   183  	db.Commit()
   184  
   185  	// read.
   186  	v, err = db.Get(key)
   187  	assert.Nil(t, err)
   188  	assert.Equal(t, val, v)
   189  
   190  	// begin.
   191  	err = db.Begin()
   192  	assert.Nil(t, err)
   193  
   194  	err = db.Del(key)
   195  	assert.Nil(t, err)
   196  
   197  	{
   198  		// other MVCCDB read old value.
   199  		db2, _ := NewMVCCDB(store, false)
   200  		v, err := db2.Get(key)
   201  		assert.Equal(t, val, v)
   202  		assert.Nil(t, err)
   203  	}
   204  
   205  	v, err = db.Get(key)
   206  	assert.Nil(t, v)
   207  	assert.Equal(t, err, storage.ErrKeyNotFound)
   208  
   209  	// rollback.
   210  	db.RollBack()
   211  
   212  	// read.
   213  	v, err = db.Get(key)
   214  	assert.Nil(t, err)
   215  	assert.Equal(t, val, v)
   216  
   217  	{
   218  		// other MVCCDB read old value.
   219  		db2, _ := NewMVCCDB(store, false)
   220  		v, err := db2.Get(key)
   221  		assert.Equal(t, val, v)
   222  		assert.Nil(t, err)
   223  	}
   224  
   225  	// begin.
   226  	err = db.Begin()
   227  	assert.Nil(t, err)
   228  
   229  	err = db.Del(key)
   230  	assert.Nil(t, err)
   231  
   232  	// commit.
   233  	db.Commit()
   234  
   235  	// read.
   236  	v, err = db.Get(key)
   237  	assert.Nil(t, v)
   238  	assert.Equal(t, err, storage.ErrKeyNotFound)
   239  
   240  	{
   241  		// other MVCCDB read nil.
   242  		db2, _ := NewMVCCDB(store, false)
   243  		v, err := db2.Get(key)
   244  		assert.Nil(t, v)
   245  		assert.Equal(t, err, storage.ErrKeyNotFound)
   246  	}
   247  }
   248  
   249  func TestMVCCDB_PrepareAndUpdate(t *testing.T) {
   250  	store, _ := storage.NewMemoryStorage()
   251  	db, _ := NewMVCCDB(store, false)
   252  
   253  	// init base data.
   254  	db.Put([]byte("title"), []byte("this is test program"))
   255  
   256  	// tid0 update.
   257  	{
   258  		db.Begin()
   259  
   260  		tid := "tid0"
   261  		pdb, err := db.Prepare(tid)
   262  		assert.Nil(t, err)
   263  
   264  		pdb.Put([]byte("duration"), []byte("65536"))
   265  		pdb.Put([]byte("creator"), []byte("robin"))
   266  		pdb.Put([]byte("count"), []byte("0"))
   267  		pdb.Put([]byte("createdAt"), []byte("c0"))
   268  		pdb.Put([]byte("updatedAt"), []byte("u0"))
   269  
   270  		deps, err := pdb.CheckAndUpdate()
   271  		assert.Nil(t, err)
   272  		assert.Equal(t, 0, len(deps))
   273  
   274  		db.Commit()
   275  	}
   276  
   277  	// concurrent update.
   278  	db.Begin()
   279  
   280  	type RetValue struct {
   281  		tid     interface{}
   282  		pdb     *MVCCDB
   283  		depends []interface{}
   284  		err     error
   285  	}
   286  
   287  	ret := make([]*RetValue, 0, 2)
   288  
   289  	{
   290  		tid := "tid1"
   291  		pdb, err := db.Prepare(tid)
   292  		assert.Nil(t, err)
   293  		assert.NotNil(t, pdb)
   294  
   295  		pdb.Get([]byte("count"))
   296  		pdb.Put([]byte("count"), []byte("10"))
   297  		pdb.Put([]byte("updatedAt"), []byte("u10"))
   298  
   299  		ret = append(ret, &RetValue{
   300  			tid: tid,
   301  			pdb: pdb,
   302  		})
   303  	}
   304  
   305  	{
   306  		tid := "tid2"
   307  		pdb, err := db.Prepare(tid)
   308  		assert.Nil(t, err)
   309  		assert.NotNil(t, pdb)
   310  
   311  		pdb.Get([]byte("count"))
   312  		pdb.Put([]byte("duration"), []byte("1024"))
   313  		pdb.Put([]byte("updatedAt"), []byte("u20"))
   314  		pdb.Del([]byte("creator"))
   315  		pdb.Put([]byte("description"), []byte("new description"))
   316  
   317  		ret = append(ret, &RetValue{
   318  			tid: tid,
   319  			pdb: pdb,
   320  		})
   321  	}
   322  
   323  	for _, v := range ret {
   324  		deps, err := v.pdb.CheckAndUpdate()
   325  		v.depends = deps
   326  		v.err = err
   327  	}
   328  
   329  	// commit.
   330  	db.Commit()
   331  
   332  	// verify.
   333  	var finalRet, errorRet *RetValue
   334  	for _, v := range ret {
   335  		if v.err == nil {
   336  			finalRet = v
   337  		} else {
   338  			errorRet = v
   339  		}
   340  	}
   341  
   342  	assert.NotNil(t, finalRet)
   343  	assert.NotNil(t, errorRet)
   344  
   345  	assert.Nil(t, finalRet.err)
   346  	assert.Equal(t, ErrStagingTableKeyConfliction, errorRet.err)
   347  
   348  	assert.Equal(t, 0, len(finalRet.depends))
   349  	assert.Equal(t, 0, len(errorRet.depends))
   350  
   351  	// verify value.
   352  	val, err := db.Get([]byte("title"))
   353  	assert.Nil(t, err)
   354  	assert.Equal(t, []byte("this is test program"), val)
   355  
   356  	val, err = db.Get([]byte("duration"))
   357  	assert.Nil(t, err)
   358  	assert.Equal(t, []byte("65536"), val)
   359  
   360  	val, err = db.Get([]byte("creator"))
   361  	assert.Nil(t, err)
   362  	assert.Equal(t, []byte("robin"), val)
   363  
   364  	val, err = db.Get([]byte("count"))
   365  	assert.Nil(t, err)
   366  	assert.Equal(t, []byte("10"), val)
   367  
   368  	val, err = db.Get([]byte("createdAt"))
   369  	assert.Nil(t, err)
   370  	assert.Equal(t, []byte("c0"), val)
   371  
   372  	val, err = db.Get([]byte("updatedAt"))
   373  	assert.Nil(t, err)
   374  	assert.Equal(t, []byte("u10"), val)
   375  
   376  	val, err = db.Get([]byte("description"))
   377  	assert.Equal(t, storage.ErrKeyNotFound, err)
   378  	assert.Nil(t, val)
   379  }
   380  
   381  func TestMVCCDB_ResetAndReuse(t *testing.T) {
   382  	store, _ := storage.NewMemoryStorage()
   383  	db, _ := NewMVCCDB(store, false)
   384  
   385  	// begin.
   386  	db.Begin()
   387  
   388  	key1 := []byte("key1")
   389  	val1_1 := []byte("val1_1")
   390  	val1_2 := []byte("val1_2")
   391  	val1_3 := []byte("val1_3")
   392  
   393  	err := db.Put(key1, val1_1)
   394  	assert.Nil(t, err)
   395  
   396  	// prepare.
   397  	pdb, err := db.Prepare("tid1")
   398  	assert.Nil(t, err)
   399  
   400  	assert.Nil(t, pdb.Del(key1))
   401  	val, err := pdb.Get(key1)
   402  	assert.Nil(t, val)
   403  	assert.Equal(t, storage.ErrKeyNotFound, err)
   404  
   405  	pdb.Reset()
   406  
   407  	assert.Nil(t, pdb.Put(key1, val1_2))
   408  	val, err = pdb.Get(key1)
   409  	assert.Equal(t, val1_2, val)
   410  	assert.Nil(t, err)
   411  
   412  	// nested prepare.
   413  	pdb2, err := pdb.Prepare("tid2")
   414  	assert.Nil(t, err)
   415  	val, err = pdb2.Get(key1)
   416  	assert.Equal(t, val1_2, val)
   417  	assert.Nil(t, err)
   418  
   419  	assert.Nil(t, pdb2.Put(key1, val1_3))
   420  	val, err = pdb2.Get(key1)
   421  	assert.Equal(t, val1_3, val)
   422  	assert.Nil(t, err)
   423  
   424  	// verify pdb,
   425  	val, err = pdb.Get(key1)
   426  	assert.Equal(t, val1_2, val)
   427  	assert.Nil(t, err)
   428  
   429  	// close.
   430  	assert.Nil(t, pdb2.Close())
   431  	assert.Nil(t, pdb.Close())
   432  
   433  	// Commit.
   434  	db.Commit()
   435  
   436  	val, err = db.Get(key1)
   437  	assert.Equal(t, val1_1, val)
   438  	assert.Nil(t, err)
   439  }
   440  
   441  func TestMVCCDB_ClosePreparedDB(t *testing.T) {
   442  	store, _ := storage.NewMemoryStorage()
   443  	db, _ := NewMVCCDB(store, false)
   444  
   445  	// begin.
   446  	db.Begin()
   447  
   448  	key1 := []byte("key1")
   449  	val1_1 := []byte("val1_1")
   450  	val1_2 := []byte("val1_2")
   451  
   452  	assert.Nil(t, db.Put(key1, val1_1))
   453  
   454  	pdb, err := db.Prepare("tid1")
   455  	assert.Nil(t, err)
   456  
   457  	// duplicate prepare.
   458  	v, err := db.Prepare("tid1")
   459  	assert.Nil(t, v)
   460  	assert.Equal(t, ErrTidIsExist, err)
   461  
   462  	// close.
   463  	assert.Nil(t, pdb.Close())
   464  	val, err := pdb.Get(key1)
   465  	assert.Nil(t, val)
   466  	assert.Equal(t, ErrPreparedDBIsClosed, err)
   467  
   468  	err = pdb.Put(key1, val1_2)
   469  	assert.Equal(t, ErrPreparedDBIsClosed, err)
   470  
   471  	err = pdb.Del(key1)
   472  	assert.Equal(t, ErrPreparedDBIsClosed, err)
   473  
   474  	// prepare again
   475  	v, err = db.Prepare("tid1")
   476  	assert.Nil(t, err)
   477  	assert.False(t, pdb == v)
   478  
   479  	assert.Nil(t, v.Put(key1, val1_2))
   480  	val, err = v.Get(key1)
   481  	assert.Equal(t, val1_2, val)
   482  	assert.Nil(t, err)
   483  }
   484  
   485  func TestMVCCDB_ParallelsExeTowTx(t *testing.T) {
   486  	store, _ := storage.NewMemoryStorage()
   487  	db, _ := NewMVCCDB(store, false)
   488  
   489  	// expected t1(a-b) and t2(a-b) parallels execution will be failed.
   490  
   491  	db.Begin()
   492  
   493  	t1, err := db.Prepare("t1")
   494  	assert.Nil(t, err)
   495  	t2, err := db.Prepare("t2")
   496  	assert.Nil(t, err)
   497  
   498  	// 1st time.
   499  	t1.Put([]byte("a"), []byte("9"))
   500  	t1.Put([]byte("b"), []byte("11"))
   501  	t2.Put([]byte("a"), []byte("9"))
   502  	t2.Put([]byte("b"), []byte("11"))
   503  
   504  	// t1 1st: commit, failed.
   505  	deps, err := t1.CheckAndUpdate()
   506  	assert.Nil(t, err)
   507  	assert.Equal(t, 0, len(deps))
   508  
   509  	// t2: 1st, failed.
   510  	deps, err = t2.CheckAndUpdate()
   511  	assert.Equal(t, ErrStagingTableKeyConfliction, err)
   512  
   513  	// t2: 2nd, succeed.
   514  	t2.Close()
   515  	t2, err = db.Prepare("t2")
   516  	assert.Nil(t, err)
   517  
   518  	t2.Put([]byte("a"), []byte("9"))
   519  	t2.Put([]byte("b"), []byte("11"))
   520  	deps, err = t2.CheckAndUpdate()
   521  	assert.Nil(t, err)
   522  	assert.Equal(t, 1, len(deps))
   523  	assert.Equal(t, "t1", deps[0])
   524  }
   525  
   526  func TestPerformance(t *testing.T) {
   527  	store, _ := storage.NewRocksStorage("test.db")
   528  	defer os.RemoveAll("test.db")
   529  	db, _ := NewMVCCDB(store, true)
   530  
   531  	// begin.
   532  	db.Begin()
   533  
   534  	val := []byte("kbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghaadgncdgkenkbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghaadgncdgkenkbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghaadgncdgkenkbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghakbtiuwgqybgheb l dvhjbgkajbn ba.dkghoeubgkjabgk.jdbga;kdjhguibnaklefgn;ndjghao;idngsndbghaadgncdgken")
   535  	assert.Equal(t, len(val), 3640)
   536  
   537  	for i := 0; i < 400; i++ {
   538  		pdb, err := db.Prepare(byteutils.Hex(hash.Sha3256(byteutils.FromInt32(int32(i)))))
   539  		for j := 0; j < 20; j++ {
   540  			assert.Nil(t, db.Put(byteutils.FromInt32(int32(i*20+j)), val))
   541  		}
   542  		_, err = pdb.CheckAndUpdate()
   543  		assert.Nil(t, err)
   544  	}
   545  
   546  	start := time.Now().UnixNano()
   547  	err := db.Commit()
   548  	end := time.Now().UnixNano()
   549  	assert.Nil(t, err)
   550  	assert.True(t, (end-start) < 1000000000, "%s", end-start)
   551  }
   552  
   553  func TestOperateAfterParentClosed(t *testing.T) {
   554  	store, _ := storage.NewMemoryStorage()
   555  	db, _ := NewMVCCDB(store, true)
   556  
   557  	db.Begin()
   558  	tx1, err := db.Prepare("1")
   559  	assert.Nil(t, err)
   560  	tree1, err := trie.NewTrie(nil, tx1, false)
   561  	assert.Nil(t, err)
   562  	tree1.Put([]byte("111111"), []byte("111"))
   563  	tree1.Put([]byte("111112"), []byte("112"))
   564  	tx1.CheckAndUpdate()
   565  
   566  	tx2, err := db.Prepare("2")
   567  	assert.Nil(t, err)
   568  	tree2, err := trie.NewTrie(tree1.RootHash(), tx2, false)
   569  	assert.Nil(t, err)
   570  
   571  	db.RollBack()
   572  
   573  	bytes, err := tree2.Put([]byte("111113"), []byte("113"))
   574  	assert.Nil(t, bytes)
   575  	assert.Equal(t, err, ErrPreparedDBIsClosed)
   576  }