github.com/turingchain2020/turingchain@v1.1.21/system/store/mavl/db/tree_test.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package mavl
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"math/rand"
    13  	"os"
    14  	"sort"
    15  	"sync"
    16  	"testing"
    17  
    18  	"unsafe"
    19  
    20  	. "github.com/turingchain2020/turingchain/common"
    21  	"github.com/turingchain2020/turingchain/common/db"
    22  	"github.com/turingchain2020/turingchain/common/log"
    23  	"github.com/turingchain2020/turingchain/types"
    24  	"github.com/golang/protobuf/proto"
    25  	"github.com/stretchr/testify/assert"
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  func init() {
    30  	log.SetLogLevel("error")
    31  }
    32  
    33  const (
    34  	strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
    35  )
    36  
    37  // Constructs an alphanumeric string of given length.
    38  func RandStr(length int) string {
    39  	chars := []byte{}
    40  MAIN_LOOP:
    41  	for {
    42  		val := rand.Int63()
    43  		for i := 0; i < 10; i++ {
    44  			v := int(val & 0x3f) // rightmost 6 bits
    45  			if v >= 62 {         // only 62 characters in strChars
    46  				val >>= 6
    47  				continue
    48  			} else {
    49  				chars = append(chars, strChars[v])
    50  				if len(chars) == length {
    51  					break MAIN_LOOP
    52  				}
    53  				val >>= 6
    54  			}
    55  		}
    56  	}
    57  
    58  	return string(chars)
    59  }
    60  
    61  func randstr(length int) string {
    62  	return RandStr(length)
    63  }
    64  
    65  func RandInt32() uint32 {
    66  	return rand.Uint32()
    67  }
    68  
    69  func i2b(i int32) []byte {
    70  	bbuf := bytes.NewBuffer([]byte{})
    71  	binary.Write(bbuf, binary.BigEndian, i)
    72  	return Sha256(bbuf.Bytes())
    73  }
    74  
    75  // 测试set和get功能
    76  func TestBasic(t *testing.T) {
    77  	var tree = NewTree(nil, true, nil)
    78  	up := tree.Set([]byte("1"), []byte("one"))
    79  	if up {
    80  		t.Error("Did not expect an update (should have been create)")
    81  	}
    82  	up = tree.Set([]byte("2"), []byte("two"))
    83  	if up {
    84  		t.Error("Did not expect an update (should have been create)")
    85  	}
    86  	up = tree.Set([]byte("2"), []byte("TWO"))
    87  	if !up {
    88  		t.Error("Expected an update")
    89  	}
    90  	up = tree.Set([]byte("5"), []byte("five"))
    91  	if up {
    92  		t.Error("Did not expect an update (should have been create)")
    93  	}
    94  	hash := tree.Hash()
    95  
    96  	t.Log("TestBasic", "roothash", hash)
    97  
    98  	//PrintMAVLNode(tree.root)
    99  
   100  	// Test 0x00
   101  	{
   102  		idx, val, exists := tree.Get([]byte{0x00})
   103  		if exists {
   104  			t.Errorf("Expected no value to exist")
   105  		}
   106  		if idx != 0 {
   107  			t.Errorf("Unexpected idx %x", idx)
   108  		}
   109  		if string(val) != "" {
   110  			t.Errorf("Unexpected value %v", string(val))
   111  		}
   112  	}
   113  
   114  	// Test "1"
   115  	{
   116  		idx, val, exists := tree.Get([]byte("1"))
   117  		if !exists {
   118  			t.Errorf("Expected value to exist")
   119  		}
   120  		if idx != 0 {
   121  			t.Errorf("Unexpected idx %x", idx)
   122  		}
   123  		if string(val) != "one" {
   124  			t.Errorf("Unexpected value %v", string(val))
   125  		}
   126  	}
   127  
   128  	// Test "2"
   129  	{
   130  		idx, val, exists := tree.Get([]byte("2"))
   131  		if !exists {
   132  			t.Errorf("Expected value to exist")
   133  		}
   134  		if idx != 1 {
   135  			t.Errorf("Unexpected idx %x", idx)
   136  		}
   137  		if string(val) != "TWO" {
   138  			t.Errorf("Unexpected value %v", string(val))
   139  		}
   140  	}
   141  
   142  	// Test "4"
   143  	{
   144  		idx, val, exists := tree.Get([]byte("4"))
   145  		if exists {
   146  			t.Errorf("Expected no value to exist")
   147  		}
   148  		if idx != 2 {
   149  			t.Errorf("Unexpected idx %x", idx)
   150  		}
   151  		if string(val) != "" {
   152  			t.Errorf("Unexpected value %v", string(val))
   153  		}
   154  	}
   155  }
   156  func TestTreeHeightAndSize(t *testing.T) {
   157  	dir, err := ioutil.TempDir("", "datastore")
   158  	require.NoError(t, err)
   159  	t.Log(dir)
   160  
   161  	db := db.NewDB("mavltree", "leveldb", dir, 100)
   162  
   163  	// Create some random key value pairs
   164  	records := make(map[string]string)
   165  
   166  	count := 14
   167  	for i := 0; i < count; i++ {
   168  		records[randstr(20)] = randstr(20)
   169  	}
   170  
   171  	// Construct some tree and save it
   172  	t1 := NewTree(db, true, nil)
   173  
   174  	for key, value := range records {
   175  		t1.Set([]byte(key), []byte(value))
   176  	}
   177  
   178  	for key, value := range records {
   179  		index, t2value, _ := t1.Get([]byte(key))
   180  		if string(t2value) != value {
   181  			t.Log("TestTreeHeightAndSize", "index", index, "key", []byte(key))
   182  		}
   183  	}
   184  	t1.Hash()
   185  	//PrintMAVLNode(t1.root)
   186  	t1.Save()
   187  	if int32(count) != t1.Size() {
   188  		t.Error("TestTreeHeightAndSize Size != count", "treesize", t1.Size(), "count", count)
   189  	}
   190  	//t.Log("TestTreeHeightAndSize", "treeheight", t1.Height(), "leafcount", count)
   191  	//t.Log("TestTreeHeightAndSize", "treesize", t1.Size())
   192  	db.Close()
   193  }
   194  
   195  //获取共享的老数据
   196  func TestSetAndGetOld(t *testing.T) {
   197  	dir, err := ioutil.TempDir("", "datastore")
   198  	require.NoError(t, err)
   199  	t.Log(dir)
   200  	dbm := db.NewDB("mavltree", "leveldb", dir, 100)
   201  	t1 := NewTree(dbm, true, nil)
   202  	t1.Set([]byte("1"), []byte("1"))
   203  	t1.Set([]byte("2"), []byte("2"))
   204  
   205  	hash := t1.Hash()
   206  	t1.Save()
   207  
   208  	//t2 在t1的基础上再做修改
   209  	t2 := NewTree(dbm, true, nil)
   210  	t2.Load(hash)
   211  	t2.Set([]byte("2"), []byte("22"))
   212  	hash = t2.Hash()
   213  	t2.Save()
   214  
   215  	t3 := NewTree(dbm, true, nil)
   216  	t3.Load(hash)
   217  	_, v, _ := t3.Get([]byte("1"))
   218  	assert.Equal(t, []byte("1"), v)
   219  
   220  	_, v, _ = t3.Get([]byte("2"))
   221  	assert.Equal(t, []byte("22"), v)
   222  }
   223  
   224  //开启mvcc 和 prefix 要保证 hash 不变
   225  func TestHashSame(t *testing.T) {
   226  	dir, err := ioutil.TempDir("", "datastore")
   227  	require.NoError(t, err)
   228  	t.Log(dir)
   229  	dbm := db.NewDB("mavltree", "leveldb", dir, 100)
   230  
   231  	t1 := NewTree(dbm, true, nil)
   232  	t1.Set([]byte("1"), []byte("1"))
   233  	t1.Set([]byte("2"), []byte("2"))
   234  
   235  	hash1 := t1.Hash()
   236  
   237  	treeCfg := &TreeConfig{
   238  		EnableMavlPrefix: true,
   239  		EnableMVCC:       true,
   240  	}
   241  	//t2 在t1的基础上再做修改
   242  	t2 := NewTree(dbm, true, treeCfg)
   243  	t2.Set([]byte("1"), []byte("1"))
   244  	t2.Set([]byte("2"), []byte("2"))
   245  	hash2 := t2.Hash()
   246  	assert.Equal(t, hash1, hash2)
   247  }
   248  
   249  func TestHashSame2(t *testing.T) {
   250  	dir, err := ioutil.TempDir("", "datastore")
   251  	require.NoError(t, err)
   252  	t.Log(dir)
   253  
   254  	db1 := db.NewDB("test1", "leveldb", dir, 100)
   255  	prevHash := make([]byte, 32)
   256  	strs1 := make(map[string]bool)
   257  	for i := 0; i < 5; i++ {
   258  		prevHash, err = saveBlock(db1, int64(i), prevHash, 1000, false, nil)
   259  		assert.Nil(t, err)
   260  		str := ToHex(prevHash)
   261  		fmt.Println("unable", str)
   262  		strs1[str] = true
   263  	}
   264  
   265  	db2 := db.NewDB("test2", "leveldb", dir, 100)
   266  	prevHash = prevHash[:0]
   267  
   268  	treeCfg := &TreeConfig{
   269  		EnableMavlPrefix: true,
   270  		EnableMVCC:       true,
   271  	}
   272  
   273  	for i := 0; i < 5; i++ {
   274  		prevHash, err = saveBlock(db2, int64(i), prevHash, 1000, false, treeCfg)
   275  		assert.Nil(t, err)
   276  		str := ToHex(prevHash)
   277  		fmt.Println("enable", str)
   278  		if ok := strs1[str]; !ok {
   279  			t.Error("enable Prefix have a different hash")
   280  		}
   281  	}
   282  
   283  }
   284  
   285  //测试hash,save,load以及节点value值的更新功能
   286  func TestPersistence(t *testing.T) {
   287  	dir, err := ioutil.TempDir("", "datastore")
   288  	require.NoError(t, err)
   289  	t.Log(dir)
   290  
   291  	dbm := db.NewDB("mavltree", "leveldb", dir, 100)
   292  
   293  	records := make(map[string]string)
   294  
   295  	recordbaks := make(map[string]string)
   296  
   297  	for i := 0; i < 10; i++ {
   298  		records[randstr(20)] = randstr(20)
   299  	}
   300  
   301  	enableMvcc := false
   302  	mvccdb := db.NewMVCC(dbm)
   303  
   304  	t1 := NewTree(dbm, true, nil)
   305  
   306  	for key, value := range records {
   307  		//t1.Set([]byte(key), []byte(value))
   308  		kindsSet(t1, mvccdb, []byte(key), []byte(value), 0, enableMvcc)
   309  		//t.Log("TestPersistence tree1 set", "key", key, "value", value)
   310  		recordbaks[key] = randstr(20)
   311  	}
   312  
   313  	hash := t1.Hash()
   314  	t1.Save()
   315  
   316  	t.Log("TestPersistence", "roothash1", hash)
   317  
   318  	// Load a tree
   319  	t2 := NewTree(dbm, true, nil)
   320  	t2.Load(hash)
   321  
   322  	for key, value := range records {
   323  		//_, t2value, _ := t2.Get([]byte(key))
   324  		_, t2value, _ := kindsGet(t2, mvccdb, []byte(key), 0, enableMvcc)
   325  		if string(t2value) != value {
   326  			t.Fatalf("Invalid value. Expected %v, got %v", value, t2value)
   327  		}
   328  	}
   329  
   330  	// update 5个key的value在hash2 tree中,验证这个5个key在hash和hash2中的值不一样
   331  	var count int
   332  	for key, value := range recordbaks {
   333  		count++
   334  		if count > 5 {
   335  			break
   336  		}
   337  		//t2.Set([]byte(key), []byte(value))
   338  		kindsSet(t2, mvccdb, []byte(key), []byte(value), 1, enableMvcc)
   339  		//t.Log("TestPersistence insert new node treee2", "key", string(key), "value", string(value))
   340  
   341  	}
   342  
   343  	hash2 := t2.Hash()
   344  	t2.Save()
   345  	t.Log("TestPersistence", "roothash2", hash2)
   346  
   347  	// 重新加载hash
   348  
   349  	t11 := NewTree(dbm, true, nil)
   350  	t11.Load(hash)
   351  
   352  	t.Log("------tree11------TestPersistence---------")
   353  	for key, value := range records {
   354  		//_, t2value, _ := t11.Get([]byte(key))
   355  		_, t2value, _ := kindsGet(t11, mvccdb, []byte(key), 0, enableMvcc)
   356  		if string(t2value) != value {
   357  			t.Fatalf("tree11 Invalid value. Expected %v, got %v", value, t2value)
   358  		}
   359  	}
   360  	//重新加载hash2
   361  	t22 := NewTree(dbm, true, nil)
   362  	t22.Load(hash2)
   363  	t.Log("------tree22------TestPersistence---------")
   364  
   365  	//有5个key对应的value值有变化
   366  	for key, value := range records {
   367  		//_, t2value, _ := t22.Get([]byte(key))
   368  		_, t2value, _ := kindsGet(t22, mvccdb, []byte(key), 0, enableMvcc)
   369  		if string(t2value) != value {
   370  			t.Log("tree22 value update.", "oldvalue", value, "newvalue", string(t2value), "key", key)
   371  		}
   372  	}
   373  	count = 0
   374  	for key, value := range recordbaks {
   375  		count++
   376  		if count > 5 {
   377  			break
   378  		}
   379  		//_, t2value, _ := t22.Get([]byte(key))
   380  		_, t2value, _ := kindsGet(t22, mvccdb, []byte(key), 1, enableMvcc)
   381  		if string(t2value) != value {
   382  			t.Logf("tree2222 Invalid value. Expected %v, got %v,key %v", value, string(t2value), key)
   383  		}
   384  	}
   385  	dbm.Close()
   386  }
   387  
   388  func kindsGet(t *Tree, mvccdb *db.MVCCHelper, key []byte, version int64, enableMvcc bool) (index int32, value []byte, exists bool) {
   389  	if enableMvcc {
   390  		if mvccdb != nil {
   391  			value, err := mvccdb.GetV(key, version)
   392  			if err != nil {
   393  				return 0, nil, false
   394  			}
   395  			return 0, value, true
   396  		}
   397  	} else {
   398  		if t != nil {
   399  			return t.Get(key)
   400  		}
   401  	}
   402  	return 0, nil, false
   403  }
   404  
   405  func kindsSet(t *Tree, mvccdb *db.MVCCHelper, key []byte, value []byte, version int64, enableMvcc bool) (updated bool) {
   406  	if enableMvcc {
   407  		if mvccdb != nil {
   408  			err := mvccdb.SetV(key, value, version)
   409  			if err != nil {
   410  				panic(fmt.Errorf("mvccdb cant setv %s", err.Error()))
   411  			}
   412  		}
   413  	}
   414  	return t.Set(key, value)
   415  }
   416  
   417  //测试key:value对的proof证明功能
   418  func TestIAVLProof(t *testing.T) {
   419  	dir, err := ioutil.TempDir("", "datastore")
   420  	require.NoError(t, err)
   421  	t.Log(dir)
   422  
   423  	db := db.NewDB("mavltree", "leveldb", dir, 100)
   424  
   425  	var tree = NewTree(db, true, nil)
   426  
   427  	for i := 0; i < 10; i++ {
   428  		key := fmt.Sprintf("TestIAVLProof key:%d!", i)
   429  		value := fmt.Sprintf("TestIAVLProof value:%d!", i)
   430  		tree.Set([]byte(key), []byte(value))
   431  	}
   432  
   433  	// Persist the items so far
   434  	hash1 := tree.Save()
   435  
   436  	// Add more items so it's not all persisted
   437  	for i := 0; i < 10; i++ {
   438  		key := fmt.Sprintf("TestIAVLProof KEY:%d!", i)
   439  		value := fmt.Sprintf("TestIAVLProof VALUE:%d!", i)
   440  		tree.Set([]byte(key), []byte(value))
   441  	}
   442  
   443  	rootHashBytes := tree.Hash()
   444  	hashetr := ToHex(rootHashBytes)
   445  	hashbyte, _ := FromHex(hashetr)
   446  
   447  	t.Log("TestIAVLProof", "rootHashBytes", rootHashBytes)
   448  	t.Log("TestIAVLProof", "hashetr", hashetr)
   449  	t.Log("TestIAVLProof", "hashbyte", hashbyte)
   450  
   451  	var KEY9proofbyte []byte
   452  
   453  	for i := 0; i < 10; i++ {
   454  		key := fmt.Sprintf("TestIAVLProof KEY:%d!", i)
   455  		value := fmt.Sprintf("TestIAVLProof VALUE:%d!", i)
   456  		keyBytes := []byte(key)
   457  		valueBytes := []byte(value)
   458  		_, KEY9proofbyte, _ = tree.Proof(keyBytes)
   459  		value2, proof := tree.ConstructProof(keyBytes)
   460  		if !bytes.Equal(value2, valueBytes) {
   461  			t.Log("TestIAVLProof", "value2", string(value2), "value", string(valueBytes))
   462  		}
   463  		if proof != nil {
   464  			istrue := proof.Verify([]byte(key), []byte(value), rootHashBytes)
   465  			if !istrue {
   466  				t.Error("TestIAVLProof Verify fail", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", rootHashBytes)
   467  			}
   468  		}
   469  	}
   470  
   471  	t.Log("TestIAVLProof test Persistence data----------------")
   472  	tree = NewTree(db, true, nil)
   473  
   474  	for i := 0; i < 10; i++ {
   475  		key := fmt.Sprintf("TestIAVLProof key:%d!", i)
   476  		value := fmt.Sprintf("TestIAVLProof value:%d!", i)
   477  		keyBytes := []byte(key)
   478  		valueBytes := []byte(value)
   479  
   480  		value2, proofbyte, _ := tree.Proof(keyBytes)
   481  		if !bytes.Equal(value2, valueBytes) {
   482  			t.Log("TestIAVLProof", "value2", string(value2), "value", string(valueBytes))
   483  		}
   484  		if proofbyte != nil {
   485  
   486  			leafNode := types.LeafNode{Key: keyBytes, Value: valueBytes, Height: 0, Size: 1}
   487  			leafHash := leafNode.Hash()
   488  
   489  			proof, err := ReadProof(rootHashBytes, leafHash, proofbyte)
   490  			if err != nil {
   491  				t.Log("TestIAVLProof ReadProof err ", "err", err)
   492  			}
   493  			istrue := proof.Verify([]byte(key), []byte(value), rootHashBytes)
   494  			if !istrue {
   495  				t.Log("TestIAVLProof Verify fail!", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", rootHashBytes)
   496  			}
   497  		}
   498  	}
   499  
   500  	roothash := tree.Save()
   501  
   502  	//key:value对的proof,hash1中不存在,roothash中存在
   503  	index := 9
   504  	key := fmt.Sprintf("TestIAVLProof KEY:%d!", index)
   505  	value := fmt.Sprintf("TestIAVLProof VALUE:%d!", index)
   506  	keyBytes := []byte(key)
   507  	valueBytes := []byte(value)
   508  
   509  	leafNode := types.LeafNode{Key: keyBytes, Value: valueBytes, Height: 0, Size: 1}
   510  	leafHash := leafNode.Hash()
   511  
   512  	// verify proof in tree1
   513  	t.Log("TestIAVLProof  Verify key proof in tree1 ", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", hash1)
   514  
   515  	proof, err := ReadProof(hash1, leafHash, KEY9proofbyte)
   516  	if err != nil {
   517  		t.Log("TestIAVLProof ReadProof err ", "err", err)
   518  	}
   519  	istrue := proof.Verify(keyBytes, valueBytes, hash1)
   520  	if !istrue {
   521  		t.Log("TestIAVLProof  key not in tree ", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", hash1)
   522  	}
   523  
   524  	// verify proof in tree2
   525  	t.Log("TestIAVLProof  Verify key proof in tree2 ", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", roothash)
   526  
   527  	proof, err = ReadProof(roothash, leafHash, KEY9proofbyte)
   528  	if err != nil {
   529  		t.Log("TestIAVLProof ReadProof err ", "err", err)
   530  	}
   531  	istrue = proof.Verify(keyBytes, valueBytes, roothash)
   532  	if istrue {
   533  		t.Log("TestIAVLProof  key in tree2 ", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", roothash)
   534  	}
   535  	db.Close()
   536  }
   537  
   538  func TestSetAndGetKVPair(t *testing.T) {
   539  	dir, err := ioutil.TempDir("", "datastore")
   540  	require.NoError(t, err)
   541  	t.Log(dir)
   542  
   543  	db := db.NewDB("mavltree", "leveldb", dir, 100)
   544  
   545  	var storeSet types.StoreSet
   546  	var storeGet types.StoreGet
   547  	var storeDel types.StoreGet
   548  
   549  	total := 10
   550  	storeSet.KV = make([]*types.KeyValue, total)
   551  	storeGet.Keys = make([][]byte, total)
   552  	storeDel.Keys = make([][]byte, total-5)
   553  
   554  	records := make(map[string]string)
   555  
   556  	for i := 0; i < total; i++ {
   557  		records[randstr(20)] = randstr(20)
   558  	}
   559  	i := 0
   560  	for key, value := range records {
   561  		var keyvalue types.KeyValue
   562  		keyvalue.Key = []byte(key)
   563  		keyvalue.Value = []byte(value)
   564  		if i < total {
   565  			storeSet.KV[i] = &keyvalue
   566  			storeGet.Keys[i] = []byte(key)
   567  			if i < total-5 {
   568  				storeDel.Keys[i] = []byte(key)
   569  			}
   570  		}
   571  		i++
   572  	}
   573  	// storeSet hash is nil
   574  	storeSet.StateHash = emptyRoot[:]
   575  	newhash, err := SetKVPair(db, &storeSet, true, nil)
   576  	assert.Nil(t, err)
   577  	//打印指定roothash的tree
   578  	t.Log("TestSetAndGetKVPair newhash tree")
   579  	PrintTreeLeaf(db, newhash, nil)
   580  
   581  	//删除5个节点
   582  	storeDel.StateHash = newhash
   583  	delhash, _, err := DelKVPair(db, &storeDel, nil)
   584  	assert.Nil(t, err)
   585  	//打印指定roothash的tree
   586  	t.Log("TestSetAndGetKVPair delhash tree")
   587  	PrintTreeLeaf(db, delhash, nil)
   588  
   589  	// 在原来的基础上再次插入10个节点
   590  
   591  	var storeSet2 types.StoreSet
   592  	var storeGet2 types.StoreGet
   593  
   594  	total = 10
   595  	storeSet2.KV = make([]*types.KeyValue, total)
   596  	storeGet2.Keys = make([][]byte, total)
   597  
   598  	records2 := make(map[string]string)
   599  
   600  	for j := 0; j < total; j++ {
   601  		records2[randstr(20)] = randstr(20)
   602  	}
   603  	i = 0
   604  	for key, value := range records2 {
   605  		var keyvalue types.KeyValue
   606  		keyvalue.Key = []byte(key)
   607  		keyvalue.Value = []byte(value)
   608  		if i < total {
   609  			storeSet2.KV[i] = &keyvalue
   610  			storeGet2.Keys[i] = []byte(key)
   611  		}
   612  		i++
   613  	}
   614  	// storeSet hash is newhash
   615  	storeSet2.StateHash = delhash
   616  	newhash2, err := SetKVPair(db, &storeSet2, true, nil)
   617  	assert.Nil(t, err)
   618  	t.Log("TestSetAndGetKVPair newhash2 tree")
   619  	PrintTreeLeaf(db, newhash2, nil)
   620  
   621  	t.Log("TestSetAndGetKVPair delhash tree again !!!")
   622  	PrintTreeLeaf(db, delhash, nil)
   623  
   624  	t.Log("TestSetAndGetKVPair newhash tree again !!!")
   625  	PrintTreeLeaf(db, newhash, nil)
   626  	db.Close()
   627  }
   628  
   629  func TestGetAndVerifyKVPairProof(t *testing.T) {
   630  	dir, err := ioutil.TempDir("", "datastore")
   631  	require.NoError(t, err)
   632  	t.Log(dir)
   633  
   634  	db := db.NewDB("mavltree", "leveldb", dir, 100)
   635  
   636  	var storeSet types.StoreSet
   637  	var storeGet types.StoreGet
   638  
   639  	total := 10
   640  	storeSet.KV = make([]*types.KeyValue, total)
   641  	storeGet.Keys = make([][]byte, total)
   642  
   643  	records := make(map[string]string)
   644  
   645  	for i := 0; i < total; i++ {
   646  		records[randstr(20)] = randstr(20)
   647  	}
   648  	i := 0
   649  	for key, value := range records {
   650  		var keyvalue types.KeyValue
   651  		keyvalue.Key = []byte(key)
   652  		keyvalue.Value = []byte(value)
   653  		if i < total {
   654  			storeSet.KV[i] = &keyvalue
   655  			storeGet.Keys[i] = []byte(key)
   656  		}
   657  		i++
   658  	}
   659  	// storeSet hash is nil
   660  	storeSet.StateHash = emptyRoot[:]
   661  	newhash, err := SetKVPair(db, &storeSet, true, nil)
   662  	assert.Nil(t, err)
   663  	for i = 0; i < total; i++ {
   664  		var keyvalue types.KeyValue
   665  
   666  		proof, err := GetKVPairProof(db, newhash, storeGet.Keys[i], nil)
   667  		assert.Nil(t, err)
   668  		keyvalue.Key = storeGet.Keys[i]
   669  		keyvalue.Value = []byte(records[string(storeGet.Keys[i])])
   670  		exit := VerifyKVPairProof(db, newhash, keyvalue, proof)
   671  		if !exit {
   672  			t.Log("TestGetAndVerifyKVPairProof  Verify proof fail!", "keyvalue", keyvalue.String(), "newhash", newhash)
   673  		}
   674  	}
   675  	db.Close()
   676  }
   677  
   678  type traverser struct {
   679  	Values []string
   680  }
   681  
   682  func (t *traverser) view(key, value []byte) bool {
   683  	t.Values = append(t.Values, string(value))
   684  	return false
   685  }
   686  
   687  // 迭代测试
   688  func TestIterateRange(t *testing.T) {
   689  	dir, err := ioutil.TempDir("", "datastore")
   690  	require.NoError(t, err)
   691  	t.Log(dir)
   692  
   693  	db := db.NewDB("mavltree", "leveldb", dir, 100)
   694  	tree := NewTree(db, true, nil)
   695  
   696  	type record struct {
   697  		key   string
   698  		value string
   699  	}
   700  
   701  	records := []record{
   702  		{"abc", "abc"},
   703  		{"low", "low"},
   704  		{"fan", "fan"},
   705  		{"foo", "foo"},
   706  		{"foobaz", "foobaz"},
   707  		{"good", "good"},
   708  		{"foobang", "foobang"},
   709  		{"foobar", "foobar"},
   710  		{"food", "food"},
   711  		{"foml", "foml"},
   712  	}
   713  	keys := make([]string, len(records))
   714  	for i, r := range records {
   715  		keys[i] = r.key
   716  	}
   717  	sort.Strings(keys)
   718  
   719  	for _, r := range records {
   720  		updated := tree.Set([]byte(r.key), []byte(r.value))
   721  		if updated {
   722  			t.Error("should have not been updated")
   723  		}
   724  	}
   725  
   726  	// test traversing the whole node works... in order
   727  	list := []string{}
   728  	tree.Iterate(func(key []byte, value []byte) bool {
   729  		list = append(list, string(value))
   730  		return false
   731  	})
   732  	require.Equal(t, list, []string{"abc", "fan", "foml", "foo", "foobang", "foobar", "foobaz", "food", "good", "low"})
   733  
   734  	trav := traverser{}
   735  	tree.IterateRange([]byte("foo"), []byte("goo"), true, trav.view)
   736  	require.Equal(t, trav.Values, []string{"foo", "foobang", "foobar", "foobaz", "food"})
   737  
   738  	trav = traverser{}
   739  	tree.IterateRangeInclusive([]byte("foo"), []byte("good"), true, trav.view)
   740  	require.Equal(t, trav.Values, []string{"foo", "foobang", "foobar", "foobaz", "food", "good"})
   741  
   742  	trav = traverser{}
   743  	tree.IterateRange(nil, []byte("flap"), true, trav.view)
   744  	require.Equal(t, trav.Values, []string{"abc", "fan"})
   745  
   746  	trav = traverser{}
   747  	tree.IterateRange([]byte("foob"), nil, true, trav.view)
   748  	require.Equal(t, trav.Values, []string{"foobang", "foobar", "foobaz", "food", "good", "low"})
   749  
   750  	trav = traverser{}
   751  	tree.IterateRange([]byte("very"), nil, true, trav.view)
   752  	require.Equal(t, trav.Values, []string(nil))
   753  
   754  	trav = traverser{}
   755  	tree.IterateRange([]byte("fooba"), []byte("food"), true, trav.view)
   756  	require.Equal(t, trav.Values, []string{"foobang", "foobar", "foobaz"})
   757  
   758  	trav = traverser{}
   759  	tree.IterateRange([]byte("fooba"), []byte("food"), false, trav.view)
   760  	require.Equal(t, trav.Values, []string{"foobaz", "foobar", "foobang"})
   761  
   762  	trav = traverser{}
   763  	tree.IterateRange([]byte("g"), nil, false, trav.view)
   764  	require.Equal(t, trav.Values, []string{"low", "good"})
   765  }
   766  
   767  func TestIAVLPrint(t *testing.T) {
   768  	dir, err := ioutil.TempDir("", "datastore")
   769  	require.NoError(t, err)
   770  	t.Log(dir)
   771  	dbm := db.NewDB("test", "leveldb", dir, 100)
   772  	prevHash := make([]byte, 32)
   773  	tree := NewTree(dbm, true, nil)
   774  	tree.Load(prevHash)
   775  	PrintNode(tree.root)
   776  	kvs := genKVShort(0, 10)
   777  	for i, kv := range kvs {
   778  		tree.Set(kv.Key, kv.Value)
   779  		println("insert", i)
   780  		PrintNode(tree.root)
   781  		tree.Hash()
   782  		//println("insert.hash", i)
   783  		//PrintNode(tree.root)
   784  	}
   785  }
   786  
   787  func TestPruningTree(t *testing.T) {
   788  	const txN = 5    // 每个块交易量
   789  	const preB = 500 // 一轮区块数
   790  	const round = 5  // 更新叶子节点次数
   791  	const preDel = preB / 10
   792  	dir, err := ioutil.TempDir("", "datastore")
   793  	require.NoError(t, err)
   794  	t.Log(dir)
   795  	db := db.NewDB("test", "leveldb", dir, 100)
   796  	prevHash := make([]byte, 32)
   797  
   798  	treeCfg := &TreeConfig{
   799  		EnableMavlPrefix: true,
   800  		EnableMavlPrune:  true,
   801  		PruneHeight:      preDel,
   802  	}
   803  
   804  	for j := 0; j < round; j++ {
   805  		for i := 0; i < preB; i++ {
   806  			setPruning(pruningStateStart)
   807  			prevHash, err = saveUpdateBlock(db, int64(i), prevHash, txN, j, int64(j*preB+i), treeCfg)
   808  			assert.Nil(t, err)
   809  			m := int64(j*preB + i)
   810  			if m/int64(preDel) > 1 && m%int64(preDel) == 0 {
   811  				pruningTree(db, m, treeCfg)
   812  			}
   813  		}
   814  		fmt.Printf("round %d over \n", j)
   815  	}
   816  	te := NewTree(db, true, treeCfg)
   817  	err = te.Load(prevHash)
   818  	if err == nil {
   819  		fmt.Printf("te.Load \n")
   820  		for i := 0; i < preB*txN; i++ {
   821  			key := []byte(fmt.Sprintf("my_%018d", i))
   822  			vIndex := round - 1
   823  			value := []byte(fmt.Sprintf("my_%018d_%d", i, vIndex))
   824  			_, v, exist := te.Get(key)
   825  			assert.Equal(t, exist, true)
   826  			assert.Equal(t, value, v)
   827  		}
   828  	}
   829  	PruningTreePrintDB(db, []byte(leafKeyCountPrefix))
   830  	PruningTreePrintDB(db, []byte(hashNodePrefix))
   831  	PruningTreePrintDB(db, []byte(leafNodePrefix))
   832  }
   833  
   834  func genUpdateKV(height int64, txN int64, vIndex int) (kvs []*types.KeyValue) {
   835  	for i := int64(0); i < txN; i++ {
   836  		n := height*txN + i
   837  		key := fmt.Sprintf("my_%018d", n)
   838  		value := fmt.Sprintf("my_%018d_%d", n, vIndex)
   839  		//fmt.Printf("index: %d  i: %d  %v \n", vIndex, i, value)
   840  		kvs = append(kvs, &types.KeyValue{Key: []byte(key), Value: []byte(value)})
   841  	}
   842  	return kvs
   843  }
   844  
   845  func saveUpdateBlock(dbm db.DB, height int64, hash []byte, txN int64, vIndex int, blockHeight int64, treeCfg *TreeConfig) (newHash []byte, err error) {
   846  	t := NewTree(dbm, true, treeCfg)
   847  	t.Load(hash)
   848  	t.SetBlockHeight(blockHeight)
   849  	kvs := genUpdateKV(height, txN, vIndex)
   850  	for _, kv := range kvs {
   851  		t.Set(kv.Key, kv.Value)
   852  	}
   853  	newHash = t.Save()
   854  	return newHash, nil
   855  }
   856  
   857  func TestMaxLevalDbValue(t *testing.T) {
   858  	dir, err := ioutil.TempDir("", "datastore")
   859  	require.NoError(t, err)
   860  	t.Log(dir)
   861  
   862  	db := db.NewDB("mavltree", "leveldb", dir, 100)
   863  	value := make([]byte, 1024*1024*5)
   864  	for i := 0; i < 5; i++ {
   865  		db.Set([]byte(fmt.Sprintf("mmm%d", i)), value)
   866  	}
   867  
   868  	for i := 0; i < 5; i++ {
   869  		_, e := db.Get([]byte(fmt.Sprintf("mmm%d", i)))
   870  		assert.NoError(t, e, "")
   871  		//fmt.Println(v)
   872  	}
   873  }
   874  
   875  func TestGetHash(t *testing.T) {
   876  	//开启前缀时候需要加入在叶子节点hash上加入:5f6d625f2d303030303030303030302d
   877  	/* 叶子节点对应hash值
   878  			k:abc     v:abc     hash:0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d
   879  		    k:fan     v:fan     hash:0x3bf26d01cb0752bcfd60b72348a8fde671f32f51ec276606cd5f35658c172114
   880  		    k:foml    v:foml    hash:0x0ac69b0f4ceee514d09f2816e387cda870c06be28b50bf416de5c0ba90cdfbc0
   881  		    k:foo     v:foo     hash:0x890d4f4450d5ea213b8e63aae98fae548f210b5c8d3486b685cfa86adde16ec2
   882  		    k:foobang v:foobang hash:0x6d46d71882171840bcb61f2b60b69c904a4c30435bf03e63f4ec36bfa47ab2be
   883  			k:foobar  v:foobar  hash:0x5308d1f9b60e831a5df663babbf2a2636ecaf4da3bffed52447faf5ab172cf93
   884  			k:foobaz  v:foobaz  hash:0xcbcb48848f0ce209cfccdf3ddf80740915c9bdede3cb11d0378690ad8b85a68b
   885  		    k:food    v:food    hash:0xe5080908c794168285a090088ae892793d549f3e7069f4feae3677bf3a28ad39
   886  		    k:good    v:good    hash:0x0c99238587914476198da04cbb1555d092f813eaf2e796893084406290188776
   887  		    k:low     v:low     hash:0x5a82d9685c0627c94ac5ba13e819c60e05b577bf6512062cf3dc2b5d9b381786
   888  	        height:0 hash:d95f left: right: parentHash:967b
   889  	        height:0 hash:3bf2 left: right: parentHash:cf1e
   890  			height:0 hash:0ac6 left: right: parentHash:cf1e
   891  			height:1 hash:cf1e left:3bf2 right:0ac6 parentHash:
   892  			height:2 hash:967b left:d95f right:cf1e parentHash:
   893  			height:0 hash:890d left: right: parentHash:c0bf
   894  			height:0 hash:6d46 left: right: parentHash:2f47
   895  			height:0 hash:5308 left: right: parentHash:2f47
   896  			height:1 hash:2f47 left:6d46 right:5308 parentHash:
   897  			height:2 hash:c0bf left:890d right:2f47 parentHash:
   898  			height:3 hash:d556 left:967b right:c0bf parentHash:
   899  			height:0 hash:cbcb left: right: parentHash:121e
   900  			height:0 hash:e508 left: right: parentHash:121e
   901  			height:1 hash:121e left:cbcb right:e508 parentHash:
   902  			height:0 hash:0c99 left: right: parentHash:00ab
   903  			height:0 hash:5a82 left: right: parentHash:00ab
   904  			height:1 hash:00ab left:0c99 right:5a82 parentHash:
   905  			height:2 hash:5202 left:121e right:00ab parentHash:
   906  			height:4 hash:1134 left:d556 right:5202 parentHash:
   907  	*/
   908  
   909  	dir, err := ioutil.TempDir("", "datastore")
   910  	require.NoError(t, err)
   911  	t.Log(dir)
   912  	defer os.Remove(dir)
   913  
   914  	db := db.NewDB("mavltree", "leveldb", dir, 100)
   915  	tree := NewTree(db, true, nil)
   916  
   917  	type record struct {
   918  		key   string
   919  		value string
   920  	}
   921  	records := []record{
   922  		{"abc", "abc"},
   923  		{"low", "low"},
   924  		{"fan", "fan"},
   925  		{"foo", "foo"},
   926  		{"foobaz", "foobaz"},
   927  		{"good", "good"},
   928  		{"foobang", "foobang"},
   929  		{"foobar", "foobar"},
   930  		{"food", "food"},
   931  		{"foml", "foml"},
   932  	}
   933  
   934  	keys := make([]string, len(records))
   935  	for i, r := range records {
   936  		keys[i] = r.key
   937  	}
   938  	sort.Strings(keys)
   939  
   940  	for _, r := range records {
   941  		updated := tree.Set([]byte(r.key), []byte(r.value))
   942  		if updated {
   943  			t.Error("should have not been updated")
   944  		}
   945  	}
   946  	hash := tree.Save()
   947  	//加入前缀的叶子节点
   948  	expecteds := []record{
   949  		{"abc", "0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"},
   950  		{"low", "0x5a82d9685c0627c94ac5ba13e819c60e05b577bf6512062cf3dc2b5d9b381786"},
   951  		{"fan", "0x3bf26d01cb0752bcfd60b72348a8fde671f32f51ec276606cd5f35658c172114"},
   952  		{"foo", "0x890d4f4450d5ea213b8e63aae98fae548f210b5c8d3486b685cfa86adde16ec2"},
   953  
   954  		{"foml", "0x0ac69b0f4ceee514d09f2816e387cda870c06be28b50bf416de5c0ba90cdfbc0"},
   955  		{"foobang", "0x6d46d71882171840bcb61f2b60b69c904a4c30435bf03e63f4ec36bfa47ab2be"},
   956  		{"foobar", "0x5308d1f9b60e831a5df663babbf2a2636ecaf4da3bffed52447faf5ab172cf93"},
   957  		{"foobaz", "0xcbcb48848f0ce209cfccdf3ddf80740915c9bdede3cb11d0378690ad8b85a68b"},
   958  		{"food", "0xe5080908c794168285a090088ae892793d549f3e7069f4feae3677bf3a28ad39"},
   959  		{"good", "0x0c99238587914476198da04cbb1555d092f813eaf2e796893084406290188776"},
   960  	}
   961  
   962  	tr := NewTree(db, true, nil)
   963  	tr.Load(hash)
   964  	for _, val := range expecteds {
   965  		_, hash, exists := tr.GetHash([]byte(val.key))
   966  		if exists {
   967  			require.Equal(t, ToHex(hash), val.value)
   968  		}
   969  	}
   970  	for _, val := range expecteds {
   971  		val.value = "1111"
   972  	}
   973  
   974  	//开启前缀
   975  	treeCfg := &TreeConfig{
   976  		EnableMavlPrefix: true,
   977  		EnableMavlPrune:  true,
   978  	}
   979  
   980  	tree1 := NewTree(db, true, treeCfg)
   981  	for _, r := range records {
   982  		updated := tree1.Set([]byte(r.key), []byte(r.value))
   983  		if updated {
   984  			t.Error("should have not been updated")
   985  		}
   986  	}
   987  	hash1 := tree1.Save()
   988  
   989  	expecteds = []record{
   990  		{"abc", "0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"},
   991  		{"low", "0x5f6d625f2d303030303030303030302d5a82d9685c0627c94ac5ba13e819c60e05b577bf6512062cf3dc2b5d9b381786"},
   992  		{"fan", "0x5f6d625f2d303030303030303030302d3bf26d01cb0752bcfd60b72348a8fde671f32f51ec276606cd5f35658c172114"},
   993  		{"foo", "0x5f6d625f2d303030303030303030302d890d4f4450d5ea213b8e63aae98fae548f210b5c8d3486b685cfa86adde16ec2"},
   994  
   995  		{"foml", "0x5f6d625f2d303030303030303030302d0ac69b0f4ceee514d09f2816e387cda870c06be28b50bf416de5c0ba90cdfbc0"},
   996  		{"foobang", "0x5f6d625f2d303030303030303030302d6d46d71882171840bcb61f2b60b69c904a4c30435bf03e63f4ec36bfa47ab2be"},
   997  		{"foobar", "0x5f6d625f2d303030303030303030302d5308d1f9b60e831a5df663babbf2a2636ecaf4da3bffed52447faf5ab172cf93"},
   998  		{"foobaz", "0x5f6d625f2d303030303030303030302dcbcb48848f0ce209cfccdf3ddf80740915c9bdede3cb11d0378690ad8b85a68b"},
   999  		{"food", "0x5f6d625f2d303030303030303030302de5080908c794168285a090088ae892793d549f3e7069f4feae3677bf3a28ad39"},
  1000  		{"good", "0x5f6d625f2d303030303030303030302d0c99238587914476198da04cbb1555d092f813eaf2e796893084406290188776"},
  1001  	}
  1002  
  1003  	tr1 := NewTree(db, true, treeCfg)
  1004  	tr1.Load(hash1)
  1005  	for _, val := range expecteds {
  1006  		_, hash, exists := tr1.GetHash([]byte(val.key))
  1007  		if exists {
  1008  			require.Equal(t, ToHex(hash), val.value)
  1009  		}
  1010  	}
  1011  }
  1012  
  1013  func TestRemoveLeafCountKey(t *testing.T) {
  1014  	dir, err := ioutil.TempDir("", "datastore")
  1015  	require.NoError(t, err)
  1016  	t.Log(dir)
  1017  	defer os.Remove(dir)
  1018  
  1019  	type record struct {
  1020  		key   string
  1021  		value string
  1022  	}
  1023  	records := []record{
  1024  		{"abc", "abc"},
  1025  		{"low", "low"},
  1026  		{"fan", "fan"},
  1027  		{"foo", "foo"},
  1028  		{"foobaz", "foobaz"},
  1029  	}
  1030  	//开启裁剪
  1031  	treeCfg := &TreeConfig{
  1032  		EnableMavlPrefix: true,
  1033  		EnableMavlPrune:  true,
  1034  	}
  1035  
  1036  	dbm := db.NewDB("mavltree", "leveldb", dir, 100)
  1037  
  1038  	blockHeight := int64(1000)
  1039  	tree := NewTree(dbm, true, treeCfg)
  1040  	tree.SetBlockHeight(blockHeight)
  1041  	for _, r := range records {
  1042  		tree.Set([]byte(r.key), []byte(r.value))
  1043  	}
  1044  	hash := tree.Save()
  1045  
  1046  	var countKeys [][]byte
  1047  	prefix := []byte(leafKeyCountPrefix)
  1048  	it := dbm.Iterator(prefix, nil, true)
  1049  	for it.Rewind(); it.Valid(); it.Next() {
  1050  		k := make([]byte, len(it.Key()))
  1051  		copy(k, it.Key())
  1052  		countKeys = append(countKeys, k)
  1053  	}
  1054  	it.Close()
  1055  
  1056  	// 在blockHeight + 100高度在插入另外
  1057  	tree1 := NewTree(dbm, true, treeCfg)
  1058  	tree1.Load(hash)
  1059  	tree1.SetBlockHeight(blockHeight + 100)
  1060  	records1 := []record{
  1061  		{"abc", "abc1"},
  1062  		{"good", "good"},
  1063  		{"foobang", "foobang"},
  1064  		{"foobar", "foobar"},
  1065  		{"food", "food"},
  1066  		{"foml", "foml"},
  1067  	}
  1068  	for _, r := range records1 {
  1069  		tree1.Set([]byte(r.key), []byte(r.value))
  1070  	}
  1071  	hash1 := tree1.Save()
  1072  
  1073  	mpAllKeys := make(map[string]bool)
  1074  	it = dbm.Iterator(prefix, nil, true)
  1075  	for it.Rewind(); it.Valid(); it.Next() {
  1076  		mpAllKeys[string(it.Key())] = true
  1077  	}
  1078  	it.Close()
  1079  
  1080  	// check
  1081  	tr1 := NewTree(dbm, true, treeCfg)
  1082  	tr1.Load(hash1)
  1083  	tr1.RemoveLeafCountKey(blockHeight)
  1084  	for _, key := range countKeys {
  1085  		_, err := dbm.Get(key)
  1086  		if err == nil {
  1087  			require.Error(t, fmt.Errorf("this kv should not exist"))
  1088  		}
  1089  	}
  1090  	// leave key
  1091  	for _, key := range countKeys {
  1092  		delete(mpAllKeys, string(key))
  1093  	}
  1094  	// check leave key
  1095  	for key := range mpAllKeys {
  1096  		_, err := dbm.Get([]byte(key))
  1097  		if err != nil {
  1098  			require.Error(t, fmt.Errorf("this kv should exist"))
  1099  		}
  1100  	}
  1101  }
  1102  
  1103  func TestIsRemoveLeafCountKey(t *testing.T) {
  1104  	dir, err := ioutil.TempDir("", "datastore")
  1105  	require.NoError(t, err)
  1106  	t.Log(dir)
  1107  	defer os.Remove(dir)
  1108  
  1109  	maxBlockHeight = 0
  1110  	dbm := db.NewDB("mavltree", "leveldb", dir, 100)
  1111  	tree := NewTree(dbm, true, nil)
  1112  	tree.SetBlockHeight(1000)
  1113  	isRe := tree.isRemoveLeafCountKey()
  1114  	require.Equal(t, false, isRe)
  1115  	tree.SetBlockHeight(990)
  1116  	isRe = tree.isRemoveLeafCountKey()
  1117  	require.Equal(t, true, isRe)
  1118  	tree.SetBlockHeight(1000)
  1119  	isRe = tree.isRemoveLeafCountKey()
  1120  	require.Equal(t, true, isRe)
  1121  	tree.SetBlockHeight(1010)
  1122  	isRe = tree.isRemoveLeafCountKey()
  1123  	require.Equal(t, false, isRe)
  1124  	tree.ndb.Commit()
  1125  	require.Equal(t, int64(1010), tree.getMaxBlockHeight())
  1126  
  1127  	var swg sync.WaitGroup
  1128  	for i := 0; i < 20; i++ {
  1129  		swg.Add(1)
  1130  		go func(i int, pwg *sync.WaitGroup, dbn db.DB) {
  1131  			defer swg.Done()
  1132  			tree := NewTree(dbm, true, nil)
  1133  			tree.SetBlockHeight(int64(800 + i))
  1134  			require.Equal(t, true, tree.isRemoveLeafCountKey())
  1135  		}(i, &swg, dbm)
  1136  	}
  1137  	swg.Wait()
  1138  }
  1139  
  1140  func TestGetRootHash(t *testing.T) {
  1141  	hashstr := "0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"
  1142  	hash, err := FromHex(hashstr)
  1143  	require.NoError(t, err)
  1144  	height := 999
  1145  	hashkey := genRootHashHeight(int64(height), hash)
  1146  	actHash, err := getRootHash(hashkey)
  1147  	require.NoError(t, err)
  1148  	require.Equal(t, hash, actHash)
  1149  }
  1150  
  1151  func TestSaveRootHash(t *testing.T) {
  1152  	dir, err := ioutil.TempDir("", "datastore")
  1153  	require.NoError(t, err)
  1154  	t.Log(dir)
  1155  	defer os.Remove(dir)
  1156  
  1157  	treeCfg := &TreeConfig{
  1158  		EnableMavlPrefix: true,
  1159  		EnableMavlPrune:  true,
  1160  	}
  1161  
  1162  	dbm := db.NewDB("mavltree", "leveldb", dir, 100)
  1163  	tree := NewTree(dbm, true, treeCfg)
  1164  	tree.SetBlockHeight(1010)
  1165  	tree.Set([]byte("key:111"), []byte("value:111"))
  1166  	hash := tree.Save()
  1167  	_, err = dbm.Get(genRootHashHeight(1010, hash))
  1168  	require.NoError(t, err)
  1169  }
  1170  
  1171  func TestDelLeafCountKV(t *testing.T) {
  1172  	dir, err := ioutil.TempDir("", "datastore")
  1173  	require.NoError(t, err)
  1174  	t.Log(dir)
  1175  	defer os.Remove(dir)
  1176  
  1177  	type record struct {
  1178  		key   string
  1179  		value string
  1180  	}
  1181  	records := []record{
  1182  		{"abc", "abc"},
  1183  		{"low", "low"},
  1184  		{"fan", "fan"},
  1185  		{"foo", "foo"},
  1186  		{"foobaz", "foobaz"},
  1187  	}
  1188  	//开启裁剪
  1189  	treeCfg := &TreeConfig{
  1190  		EnableMavlPrefix: true,
  1191  		EnableMavlPrune:  true,
  1192  	}
  1193  
  1194  	dbm := db.NewDB("mavltree", "leveldb", dir, 100)
  1195  
  1196  	blockHeight := int64(1000)
  1197  	tree := NewTree(dbm, true, treeCfg)
  1198  	tree.SetBlockHeight(blockHeight)
  1199  	for _, r := range records {
  1200  		tree.Set([]byte(r.key), []byte(r.value))
  1201  	}
  1202  	hash := tree.Save()
  1203  
  1204  	var countKeys [][]byte
  1205  	prefix := []byte(leafKeyCountPrefix)
  1206  	it := dbm.Iterator(prefix, nil, true)
  1207  	for it.Rewind(); it.Valid(); it.Next() {
  1208  		k := make([]byte, len(it.Key()))
  1209  		copy(k, it.Key())
  1210  		countKeys = append(countKeys, k)
  1211  	}
  1212  	it.Close()
  1213  
  1214  	// 在blockHeight + 100高度在插入另外
  1215  	tree1 := NewTree(dbm, true, treeCfg)
  1216  	tree1.Load(hash)
  1217  	tree1.SetBlockHeight(blockHeight + 100)
  1218  	records1 := []record{
  1219  		{"abc", "abc1"},
  1220  		{"good", "good"},
  1221  		{"foobang", "foobang"},
  1222  		{"foobar", "foobar"},
  1223  		{"food", "food"},
  1224  		{"foml", "foml"},
  1225  	}
  1226  	for _, r := range records1 {
  1227  		tree1.Set([]byte(r.key), []byte(r.value))
  1228  	}
  1229  	tree1.Save()
  1230  
  1231  	mpAllKeys := make(map[string]bool)
  1232  	it = dbm.Iterator(prefix, nil, true)
  1233  	for it.Rewind(); it.Valid(); it.Next() {
  1234  		mpAllKeys[string(it.Key())] = true
  1235  	}
  1236  	it.Close()
  1237  
  1238  	// check
  1239  	// del leaf count key
  1240  	err = DelLeafCountKV(dbm, blockHeight, treeCfg)
  1241  	require.NoError(t, err)
  1242  
  1243  	for _, key := range countKeys {
  1244  		_, err := dbm.Get(key)
  1245  		if err == nil {
  1246  			require.Error(t, fmt.Errorf("this kv should not exist"))
  1247  		}
  1248  	}
  1249  	// leave key
  1250  	for _, key := range countKeys {
  1251  		delete(mpAllKeys, string(key))
  1252  	}
  1253  	// check leave key
  1254  	for key := range mpAllKeys {
  1255  		_, err := dbm.Get([]byte(key))
  1256  		if err != nil {
  1257  			require.Error(t, fmt.Errorf("this kv should exist"))
  1258  		}
  1259  	}
  1260  }
  1261  
  1262  func TestGetObsoleteNode(t *testing.T) {
  1263  	dir, err := ioutil.TempDir("", "datastore")
  1264  	require.NoError(t, err)
  1265  	t.Log(dir)
  1266  	defer os.Remove(dir)
  1267  
  1268  	treeCfg := &TreeConfig{
  1269  		EnableMemTree:   true,
  1270  		EnableMemVal:    true,
  1271  		TkCloseCacheLen: 100,
  1272  	}
  1273  
  1274  	InitGlobalMem(treeCfg)
  1275  	db := db.NewDB("mavltree", "leveldb", dir, 100)
  1276  	tree := NewTree(db, true, treeCfg)
  1277  
  1278  	type record struct {
  1279  		key   string
  1280  		value string
  1281  	}
  1282  	records := []record{
  1283  		{"abc", "abc"},
  1284  		{"low", "low"},
  1285  		{"fan", "fan"},
  1286  	}
  1287  
  1288  	for _, r := range records {
  1289  		updated := tree.Set([]byte(r.key), []byte(r.value))
  1290  		if updated {
  1291  			t.Error("should have not been updated")
  1292  		}
  1293  	}
  1294  	hash := tree.Save()
  1295  	obs := tree.getObsoleteNode()
  1296  	require.Equal(t, 0, len(obs))
  1297  	mp := make(map[uint64]struct{})
  1298  	LoadTree2MemDb(db, hash, mp)
  1299  
  1300  	tree1 := NewTree(db, true, treeCfg)
  1301  	tree1.Load(hash)
  1302  	records1 := []record{
  1303  		{"abc", "abc1"},
  1304  		{"low", "low1"},
  1305  		{"fan", "fan1"},
  1306  	}
  1307  
  1308  	for _, r := range records1 {
  1309  		tree1.Set([]byte(r.key), []byte(r.value))
  1310  	}
  1311  	hash1 := tree1.Save()
  1312  	obs = tree1.getObsoleteNode()
  1313  	mp1 := make(map[uint64]struct{})
  1314  	LoadTree2MemDb(db, hash1, mp1)
  1315  	require.Equal(t, len(mp), len(obs)) //做了全部更新,因此旧节点全部删除
  1316  	for ob := range obs {
  1317  		_, ok := mp[uint64(ob)]
  1318  		if !ok {
  1319  			require.Error(t, fmt.Errorf("should exist"))
  1320  		}
  1321  	}
  1322  
  1323  	tree2 := NewTree(db, true, treeCfg)
  1324  	tree2.Load(hash)
  1325  	records2 := []record{
  1326  		{"fan", "fan1"},
  1327  		{"foo", "foo"},
  1328  		{"foobaz", "foobaz"},
  1329  		{"good", "good"},
  1330  	}
  1331  	for _, r := range records2 {
  1332  		tree2.Set([]byte(r.key), []byte(r.value))
  1333  	}
  1334  	hash2 := tree2.Save()
  1335  	obs = tree2.getObsoleteNode()
  1336  	mp2 := make(map[uint64]struct{})
  1337  	LoadTree2MemDb(db, hash2, mp2)
  1338  	//require.Equal(t, 0, len(obs))
  1339  	for ob := range obs {
  1340  		_, ok := mp[uint64(ob)]
  1341  		if !ok {
  1342  			require.Error(t, fmt.Errorf("should exist"))
  1343  		}
  1344  	}
  1345  }
  1346  
  1347  func TestPruningFirstLevelNode(t *testing.T) {
  1348  	dir, err := ioutil.TempDir("", "datastore")
  1349  	require.NoError(t, err)
  1350  	t.Log(dir)
  1351  	defer os.RemoveAll(dir)
  1352  
  1353  	db1 := db.NewDB("mavltree", "leveldb", dir, 100)
  1354  	//add node data
  1355  	nodes1 := []Node{
  1356  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"), height: 1},
  1357  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44a"), height: 5000},
  1358  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44b"), height: 10000},
  1359  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44c"), height: 30000},
  1360  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44e"), height: 40000},
  1361  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44f"), height: 450000},
  1362  	}
  1363  
  1364  	nodes2 := []Node{
  1365  		{key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45d"), height: 1},
  1366  		{key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45a"), height: 5000},
  1367  		{key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45b"), height: 10000},
  1368  		{key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45c"), height: 30000},
  1369  		{key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45e"), height: 40000},
  1370  		{key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45f"), height: 450000},
  1371  	}
  1372  
  1373  	hashNodes1 := []types.PruneData{
  1374  		{Hashs: [][]byte{[]byte("113"), []byte("114"), []byte("115"), []byte("116"), []byte("117"), []byte("118")}},
  1375  		{Hashs: [][]byte{[]byte("123"), []byte("124"), []byte("125"), []byte("126"), []byte("127"), []byte("128")}},
  1376  		{Hashs: [][]byte{[]byte("133"), []byte("134"), []byte("135"), []byte("136"), []byte("137"), []byte("138")}},
  1377  		{Hashs: [][]byte{[]byte("143"), []byte("144"), []byte("145"), []byte("146"), []byte("147"), []byte("148")}},
  1378  		{Hashs: [][]byte{[]byte("153"), []byte("154"), []byte("155"), []byte("156"), []byte("157"), []byte("158")}},
  1379  		{Hashs: [][]byte{[]byte("163"), []byte("164"), []byte("165"), []byte("166"), []byte("167"), []byte("168")}},
  1380  	}
  1381  
  1382  	hashNodes2 := []types.PruneData{
  1383  		{Hashs: [][]byte{[]byte("213"), []byte("214"), []byte("215"), []byte("216"), []byte("217"), []byte("218")}},
  1384  		{Hashs: [][]byte{[]byte("223"), []byte("224"), []byte("225"), []byte("226"), []byte("227"), []byte("228")}},
  1385  		{Hashs: [][]byte{[]byte("233"), []byte("234"), []byte("235"), []byte("236"), []byte("237"), []byte("238")}},
  1386  		{Hashs: [][]byte{[]byte("243"), []byte("244"), []byte("245"), []byte("246"), []byte("247"), []byte("248")}},
  1387  		{Hashs: [][]byte{[]byte("253"), []byte("254"), []byte("255"), []byte("256"), []byte("257"), []byte("258")}},
  1388  		{Hashs: [][]byte{[]byte("263"), []byte("264"), []byte("265"), []byte("266"), []byte("267"), []byte("268")}},
  1389  	}
  1390  
  1391  	batch := db1.NewBatch(true)
  1392  	for i, node := range nodes1 {
  1393  		k := genLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash))
  1394  		data := &types.PruneData{
  1395  			Hashs: hashNodes1[i].Hashs,
  1396  		}
  1397  		v, err := proto.Marshal(data)
  1398  		if err != nil {
  1399  			panic(err)
  1400  		}
  1401  		// 保存索引节点
  1402  		batch.Set(k, v)
  1403  		// 保存叶子节点
  1404  		batch.Set(node.hash, node.key)
  1405  		// 保存hash节点
  1406  		for _, hash := range data.Hashs {
  1407  			batch.Set(hash, hash)
  1408  		}
  1409  	}
  1410  	for i, node := range nodes2 {
  1411  		k := genLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash))
  1412  		data := &types.PruneData{
  1413  			Hashs: hashNodes2[i].Hashs,
  1414  		}
  1415  		v, err := proto.Marshal(data)
  1416  		if err != nil {
  1417  			panic(err)
  1418  		}
  1419  		// 保存索引节点
  1420  		batch.Set(k, v)
  1421  		// 保存叶子节点
  1422  		batch.Set(node.hash, node.key)
  1423  		// 保存hash节点
  1424  		for _, hash := range data.Hashs {
  1425  			batch.Set(hash, hash)
  1426  		}
  1427  	}
  1428  	batch.Write()
  1429  	db1.Close()
  1430  
  1431  	db2 := db.NewDB("mavltree", "leveldb", dir, 100)
  1432  
  1433  	var existHashs [][]byte
  1434  	var noExistHashs [][]byte
  1435  
  1436  	treeCfg := &TreeConfig{
  1437  		PruneHeight: 5000,
  1438  	}
  1439  	//当前高度设置为10000,只能删除高度为1的节点
  1440  	pruningFirstLevel(db2, 10000, treeCfg)
  1441  
  1442  	for i, node := range nodes1 {
  1443  		if i >= 1 {
  1444  			existHashs = append(existHashs, node.hash)
  1445  			existHashs = append(existHashs, hashNodes1[i].Hashs...)
  1446  		} else {
  1447  			noExistHashs = append(noExistHashs, node.hash)
  1448  			noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...)
  1449  		}
  1450  	}
  1451  	for i, node := range nodes2 {
  1452  		if i >= 1 {
  1453  			existHashs = append(existHashs, node.hash)
  1454  			existHashs = append(existHashs, hashNodes1[i].Hashs...)
  1455  		} else {
  1456  			noExistHashs = append(noExistHashs, node.hash)
  1457  			noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...)
  1458  		}
  1459  	}
  1460  	verifyNodeExist(t, db2, existHashs, noExistHashs)
  1461  
  1462  	//当前高度设置为20000, 删除高度为1000的
  1463  	pruningFirstLevel(db2, 20000, treeCfg)
  1464  
  1465  	existHashs = existHashs[:0][:0]
  1466  	existHashs = noExistHashs[:0][:0]
  1467  	for i, node := range nodes1 {
  1468  		if i >= 2 {
  1469  			existHashs = append(existHashs, node.hash)
  1470  			existHashs = append(existHashs, hashNodes1[i].Hashs...)
  1471  		} else {
  1472  			noExistHashs = append(noExistHashs, node.hash)
  1473  			noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...)
  1474  		}
  1475  	}
  1476  	for i, node := range nodes2 {
  1477  		if i >= 2 {
  1478  			existHashs = append(existHashs, node.hash)
  1479  			existHashs = append(existHashs, hashNodes1[i].Hashs...)
  1480  		} else {
  1481  			noExistHashs = append(noExistHashs, node.hash)
  1482  			noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...)
  1483  		}
  1484  	}
  1485  	verifyNodeExist(t, db2, existHashs, noExistHashs)
  1486  
  1487  	//目前还剩下 10000 30000 40000 450000
  1488  	//当前高度设置为510001, 将高度为10000的加入二级节点,删除30000 40000节点
  1489  	pruningFirstLevel(db2, 510001, treeCfg)
  1490  	existHashs = existHashs[:0][:0]
  1491  	existHashs = noExistHashs[:0][:0]
  1492  	for i, node := range nodes1 {
  1493  		if i >= 5 {
  1494  			existHashs = append(existHashs, node.hash)
  1495  			existHashs = append(existHashs, hashNodes1[i].Hashs...)
  1496  		} else if i == 2 {
  1497  
  1498  		} else {
  1499  			noExistHashs = append(noExistHashs, node.hash)
  1500  			noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...)
  1501  		}
  1502  	}
  1503  	for i, node := range nodes2 {
  1504  		if i >= 5 {
  1505  			existHashs = append(existHashs, node.hash)
  1506  			existHashs = append(existHashs, hashNodes1[i].Hashs...)
  1507  		} else if i == 2 {
  1508  
  1509  		} else {
  1510  			noExistHashs = append(noExistHashs, node.hash)
  1511  			noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...)
  1512  		}
  1513  	}
  1514  	verifyNodeExist(t, db2, existHashs, noExistHashs)
  1515  
  1516  	//检查转换成二级裁剪高度的节点
  1517  	var secLevelNodes []*Node
  1518  	secLevelNodes = append(secLevelNodes, &nodes1[2])
  1519  	secLevelNodes = append(secLevelNodes, &nodes2[2])
  1520  	VerifySecLevelCountNodeExist(t, db2, secLevelNodes)
  1521  }
  1522  
  1523  func verifyNodeExist(t *testing.T, dbm db.DB, existHashs [][]byte, noExistHashs [][]byte) {
  1524  	for _, hash := range existHashs {
  1525  		_, err := dbm.Get(hash)
  1526  		if err != nil {
  1527  			require.NoError(t, fmt.Errorf("this node should exist %s", string(hash)))
  1528  		}
  1529  	}
  1530  
  1531  	for _, hash := range noExistHashs {
  1532  		v, err := dbm.Get(hash)
  1533  		if err == nil || len(v) > 0 {
  1534  			require.NoError(t, fmt.Errorf("this node should not exist %s", string(hash)))
  1535  		}
  1536  	}
  1537  }
  1538  
  1539  func VerifySecLevelCountNodeExist(t *testing.T, dbm db.DB, nodes []*Node) {
  1540  	for _, node := range nodes {
  1541  		_, err := dbm.Get(genOldLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash)))
  1542  		if err != nil {
  1543  			require.NoError(t, fmt.Errorf("this node should exist key: %s, hash: %s", string(node.key), string(node.hash)))
  1544  		}
  1545  	}
  1546  }
  1547  
  1548  func TestPruningSecondLevelNode(t *testing.T) {
  1549  	dir, err := ioutil.TempDir("", "datastore")
  1550  	require.NoError(t, err)
  1551  	t.Log(dir)
  1552  	defer os.RemoveAll(dir)
  1553  
  1554  	db1 := db.NewDB("mavltree", "leveldb", dir, 100)
  1555  	//add node data
  1556  	nodes1 := []Node{
  1557  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"), height: 1},
  1558  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44a"), height: 5000},
  1559  		{key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44b"), height: 10000},
  1560  	}
  1561  
  1562  	nodes2 := []Node{
  1563  		{key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45d"), height: 1},
  1564  	}
  1565  
  1566  	hashNodes1 := []types.PruneData{
  1567  		{Hashs: [][]byte{[]byte("113"), []byte("114"), []byte("115"), []byte("116"), []byte("117"), []byte("118")}},
  1568  		{Hashs: [][]byte{[]byte("123"), []byte("124"), []byte("125"), []byte("126"), []byte("127"), []byte("128")}},
  1569  		{Hashs: [][]byte{[]byte("133"), []byte("134"), []byte("135"), []byte("136"), []byte("137"), []byte("138")}},
  1570  	}
  1571  
  1572  	hashNodes2 := []types.PruneData{
  1573  		{Hashs: [][]byte{[]byte("213"), []byte("214"), []byte("215"), []byte("216"), []byte("217"), []byte("218")}},
  1574  	}
  1575  
  1576  	batch := db1.NewBatch(true)
  1577  	for i, node := range nodes1 {
  1578  		k := genOldLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash))
  1579  		data := &types.PruneData{
  1580  			Hashs: hashNodes1[i].Hashs,
  1581  		}
  1582  		v, err := proto.Marshal(data)
  1583  		if err != nil {
  1584  			panic(err)
  1585  		}
  1586  		// 保存索引节点
  1587  		batch.Set(k, v)
  1588  		// 保存叶子节点
  1589  		batch.Set(node.hash, node.key)
  1590  		// 保存hash节点
  1591  		for _, hash := range data.Hashs {
  1592  			batch.Set(hash, hash)
  1593  		}
  1594  	}
  1595  	for i, node := range nodes2 {
  1596  		k := genOldLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash))
  1597  		data := &types.PruneData{
  1598  			Hashs: hashNodes2[i].Hashs,
  1599  		}
  1600  		v, err := proto.Marshal(data)
  1601  		if err != nil {
  1602  			panic(err)
  1603  		}
  1604  		// 保存索引节点
  1605  		batch.Set(k, v)
  1606  		// 保存叶子节点
  1607  		batch.Set(node.hash, node.key)
  1608  		// 保存hash节点
  1609  		for _, hash := range data.Hashs {
  1610  			batch.Set(hash, hash)
  1611  		}
  1612  	}
  1613  	batch.Write()
  1614  	db1.Close()
  1615  
  1616  	db2 := db.NewDB("mavltree", "leveldb", dir, 100)
  1617  
  1618  	var existHashs [][]byte
  1619  	var noExistHashs [][]byte
  1620  
  1621  	//当前高度设置为1500010,只能删除高度为1的节点
  1622  	treeCfg := &TreeConfig{
  1623  		PruneHeight: 5000,
  1624  	}
  1625  	pruningSecondLevel(db2, 1500010, treeCfg)
  1626  
  1627  	for i, node := range nodes1 {
  1628  		if i >= 2 {
  1629  			existHashs = append(existHashs, node.hash)
  1630  			existHashs = append(existHashs, hashNodes1[i].Hashs...)
  1631  		} else {
  1632  			noExistHashs = append(noExistHashs, node.hash)
  1633  			noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...)
  1634  		}
  1635  	}
  1636  	verifyNodeExist(t, db2, existHashs, noExistHashs)
  1637  
  1638  	//检查转换成二级裁剪高度的节点
  1639  	var secLevelNodes []*Node
  1640  	secLevelNodes = append(secLevelNodes, &nodes2[0])
  1641  	VerifyThreeLevelCountNodeExist(t, db2, secLevelNodes)
  1642  }
  1643  
  1644  func VerifyThreeLevelCountNodeExist(t *testing.T, dbm db.DB, nodes []*Node) {
  1645  	for _, node := range nodes {
  1646  		v, err := dbm.Get(genOldLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash)))
  1647  		if err == nil || len(v) > 0 {
  1648  			require.NoError(t, fmt.Errorf("this node should not exist key:%s hash:%s", string(node.key), string(node.hash)))
  1649  		}
  1650  	}
  1651  }
  1652  
  1653  func TestGetHashNode(t *testing.T) {
  1654  	eHashs := [][]byte{
  1655  		[]byte("h44"),
  1656  		[]byte("h33"),
  1657  		[]byte("h22"),
  1658  		[]byte("h11"),
  1659  		[]byte("h00"),
  1660  	}
  1661  
  1662  	root := &Node{
  1663  		key:        []byte("00"),
  1664  		hash:       []byte("h00"),
  1665  		parentNode: nil,
  1666  	}
  1667  
  1668  	node1 := &Node{
  1669  		key:        []byte("11"),
  1670  		hash:       []byte("h11"),
  1671  		parentNode: root,
  1672  	}
  1673  
  1674  	node2 := &Node{
  1675  		key:        []byte("22"),
  1676  		hash:       []byte("h22"),
  1677  		parentNode: node1,
  1678  	}
  1679  
  1680  	node3 := &Node{
  1681  		key:        []byte("33"),
  1682  		hash:       []byte("h33"),
  1683  		parentNode: node2,
  1684  	}
  1685  
  1686  	node4 := &Node{
  1687  		key:        []byte("44"),
  1688  		hash:       []byte("h44"),
  1689  		parentNode: node3,
  1690  	}
  1691  
  1692  	leafN := &Node{
  1693  		key:        []byte("55"),
  1694  		hash:       []byte("h55"),
  1695  		parentNode: node4,
  1696  	}
  1697  
  1698  	hashs := getHashNode(leafN)
  1699  	require.Equal(t, len(eHashs), len(hashs))
  1700  	for _, hash := range hashs {
  1701  		t.Log("hash is ", string(hash))
  1702  		require.Contains(t, eHashs, hash)
  1703  	}
  1704  }
  1705  
  1706  func TestGetKeyHeightFromLeafCountKey(t *testing.T) {
  1707  	key := []byte("123456")
  1708  	hash, err := FromHex("0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d")
  1709  	require.NoError(t, err)
  1710  	height := 100001
  1711  	hashLen := len(hash)
  1712  	hashkey := genLeafCountKey(key, hash, int64(height), hashLen)
  1713  
  1714  	//1
  1715  	key1, height1, hash1, err := getKeyHeightFromLeafCountKey(hashkey)
  1716  	require.NoError(t, err)
  1717  	require.Equal(t, key, key1)
  1718  	require.Equal(t, height, height1)
  1719  	require.Equal(t, hash, hash1)
  1720  
  1721  	//2
  1722  	key = []byte("24525252626988973653")
  1723  	hash, err = FromHex("0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d")
  1724  	require.NoError(t, err)
  1725  	height = 453
  1726  	hashLen = len(hash)
  1727  	hashkey = genLeafCountKey(key, hash, int64(height), hashLen)
  1728  
  1729  	key1, height1, hash1, err = getKeyHeightFromLeafCountKey(hashkey)
  1730  	require.NoError(t, err)
  1731  	require.Equal(t, key, key1)
  1732  	require.Equal(t, height, height1)
  1733  	require.Equal(t, hash, hash1)
  1734  }
  1735  
  1736  func TestGetKeyHeightFromOldLeafCountKey(t *testing.T) {
  1737  	key := []byte("123456")
  1738  	hash, err := FromHex("0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d")
  1739  	require.NoError(t, err)
  1740  	height := 100001
  1741  	hashLen := len(hash)
  1742  	hashkey := genOldLeafCountKey(key, hash, int64(height), hashLen)
  1743  
  1744  	//1
  1745  	key1, height1, hash1, err := getKeyHeightFromOldLeafCountKey(hashkey)
  1746  	require.NoError(t, err)
  1747  	require.Equal(t, key, key1)
  1748  	require.Equal(t, height, height1)
  1749  	require.Equal(t, hash, hash1)
  1750  
  1751  	//2
  1752  	key = []byte("24525252626988973653")
  1753  	hash, err = FromHex("0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d")
  1754  	require.NoError(t, err)
  1755  	height = 453
  1756  	hashLen = len(hash)
  1757  	hashkey = genOldLeafCountKey(key, hash, int64(height), hashLen)
  1758  
  1759  	key1, height1, hash1, err = getKeyHeightFromOldLeafCountKey(hashkey)
  1760  	require.NoError(t, err)
  1761  	require.Equal(t, key, key1)
  1762  	require.Equal(t, height, height1)
  1763  	require.Equal(t, hash, hash1)
  1764  }
  1765  
  1766  func TestPrintSameLeafKey(t *testing.T) {
  1767  	treeCfg := &TreeConfig{
  1768  		EnableMavlPrefix: true,
  1769  		EnableMavlPrune:  true,
  1770  	}
  1771  	type record struct {
  1772  		key   string
  1773  		value string
  1774  	}
  1775  	records := []record{
  1776  		{"abc", "abc"},
  1777  		{"low", "low"},
  1778  		{"fan", "fan"},
  1779  	}
  1780  
  1781  	dir, err := ioutil.TempDir("", "datastore")
  1782  	require.NoError(t, err)
  1783  	t.Log(dir)
  1784  	defer os.Remove(dir)
  1785  
  1786  	db := db.NewDB("mavltree", "leveldb", dir, 100)
  1787  	tree := NewTree(db, true, treeCfg)
  1788  
  1789  	for _, r := range records {
  1790  		updated := tree.Set([]byte(r.key), []byte(r.value))
  1791  		if updated {
  1792  			t.Error("should have not been updated")
  1793  		}
  1794  	}
  1795  	tree.Save()
  1796  	PrintSameLeafKey(db, "abc")
  1797  }
  1798  
  1799  func TestPrintLeafNodeParent(t *testing.T) {
  1800  	treeCfg := &TreeConfig{
  1801  		EnableMavlPrefix: true,
  1802  		EnableMavlPrune:  true,
  1803  	}
  1804  	blockHeight := int64(1000)
  1805  	type record struct {
  1806  		key   string
  1807  		value string
  1808  	}
  1809  	records := []record{
  1810  		{"abc", "abc"},
  1811  		{"low", "low"},
  1812  		{"fan", "fan"},
  1813  	}
  1814  
  1815  	dir, err := ioutil.TempDir("", "datastore")
  1816  	require.NoError(t, err)
  1817  	t.Log(dir)
  1818  	defer os.Remove(dir)
  1819  
  1820  	db := db.NewDB("mavltree", "leveldb", dir, 100)
  1821  	tree := NewTree(db, true, treeCfg)
  1822  	tree.SetBlockHeight(blockHeight)
  1823  	for _, r := range records {
  1824  		updated := tree.Set([]byte(r.key), []byte(r.value))
  1825  		if updated {
  1826  			t.Error("should have not been updated")
  1827  		}
  1828  	}
  1829  	tree.Save()
  1830  	hash, _ := FromHex("0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d")
  1831  	PrintLeafNodeParent(db, []byte("abc"), hash, blockHeight)
  1832  }
  1833  
  1834  func TestPrintNodeDb(t *testing.T) {
  1835  	treeCfg := &TreeConfig{
  1836  		EnableMavlPrefix: true,
  1837  		EnableMavlPrune:  true,
  1838  	}
  1839  	type record struct {
  1840  		key   string
  1841  		value string
  1842  	}
  1843  	records := []record{
  1844  		{"abc", "abc"},
  1845  		{"low", "low"},
  1846  		{"fan", "fan"},
  1847  	}
  1848  
  1849  	dir, err := ioutil.TempDir("", "datastore")
  1850  	require.NoError(t, err)
  1851  	t.Log(dir)
  1852  	defer os.Remove(dir)
  1853  
  1854  	db := db.NewDB("mavltree", "leveldb", dir, 100)
  1855  	tree := NewTree(db, true, treeCfg)
  1856  
  1857  	for _, r := range records {
  1858  		updated := tree.Set([]byte(r.key), []byte(r.value))
  1859  		if updated {
  1860  			t.Error("should have not been updated")
  1861  		}
  1862  	}
  1863  	tree.Save()
  1864  	hash, _ := FromHex("0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d")
  1865  	PrintNodeDb(db, hash)
  1866  }
  1867  
  1868  func BenchmarkDBSet(b *testing.B) {
  1869  	dir, err := ioutil.TempDir("", "datastore")
  1870  	require.NoError(b, err)
  1871  	b.Log(dir)
  1872  	db := db.NewDB("test", "leveldb", dir, 100)
  1873  	prevHash := make([]byte, 32)
  1874  	for i := 0; i < b.N; i++ {
  1875  		prevHash, err = saveBlock(db, int64(i), prevHash, 1000, false, nil)
  1876  		assert.Nil(b, err)
  1877  	}
  1878  }
  1879  
  1880  func BenchmarkDBSetMVCC(b *testing.B) {
  1881  	dir, err := ioutil.TempDir("", "datastore")
  1882  	require.NoError(b, err)
  1883  	b.Log(dir)
  1884  	db := db.NewDB("test", "leveldb", dir, 100)
  1885  	prevHash := make([]byte, 32)
  1886  	for i := 0; i < b.N; i++ {
  1887  		prevHash, err = saveBlock(db, int64(i), prevHash, 1000, true, nil)
  1888  		assert.Nil(b, err)
  1889  	}
  1890  }
  1891  
  1892  func BenchmarkDBGet(b *testing.B) {
  1893  	dir, err := ioutil.TempDir("", "datastore")
  1894  	require.NoError(b, err)
  1895  	b.Log(dir)
  1896  	db := db.NewDB("test", "leveldb", dir, 100)
  1897  	prevHash := make([]byte, 32)
  1898  	for i := 0; i < b.N; i++ {
  1899  		prevHash, err = saveBlock(db, int64(i), prevHash, 1000, false, nil)
  1900  		assert.Nil(b, err)
  1901  		if i%10 == 0 {
  1902  			fmt.Println(prevHash)
  1903  		}
  1904  	}
  1905  	b.ResetTimer()
  1906  	t := NewTree(db, true, nil)
  1907  	t.Load(prevHash)
  1908  	for i := 0; i < b.N*1000; i++ {
  1909  		key := i2b(int32(i))
  1910  		value := Sha256(key)
  1911  		_, v, exist := t.Get(key)
  1912  		assert.Equal(b, exist, true)
  1913  		assert.Equal(b, value, v)
  1914  	}
  1915  }
  1916  
  1917  func BenchmarkDBGetMVCC(b *testing.B) {
  1918  	dir, err := ioutil.TempDir("", "datastore")
  1919  	require.NoError(b, err)
  1920  	defer os.RemoveAll(dir) // clean up
  1921  	os.RemoveAll(dir)       //删除已存在目录
  1922  	b.Log(dir)
  1923  	ldb := db.NewDB("test", "leveldb", dir, 100)
  1924  	prevHash := make([]byte, 32)
  1925  	treeCfg := &TreeConfig{
  1926  		EnableMavlPrefix: true,
  1927  	}
  1928  	for i := 0; i < b.N; i++ {
  1929  		prevHash, err = saveBlock(ldb, int64(i), prevHash, 1000, true, treeCfg)
  1930  		assert.Nil(b, err)
  1931  		if i%10 == 0 {
  1932  			fmt.Println(prevHash)
  1933  		}
  1934  	}
  1935  	b.ResetTimer()
  1936  	mvccdb := db.NewMVCC(ldb)
  1937  	for i := 0; i < b.N*1000; i++ {
  1938  		key := i2b(int32(i))
  1939  		value := Sha256(key)
  1940  		v, err := mvccdb.GetV(key, int64(b.N-1))
  1941  		assert.Nil(b, err)
  1942  		assert.Equal(b, value, v)
  1943  	}
  1944  }
  1945  
  1946  func genKVShort(height int64, txN int64) (kvs []*types.KeyValue) {
  1947  	for i := int64(0); i < txN; i++ {
  1948  		n := height*1000 + i
  1949  		key := []byte(fmt.Sprintf("k:%d", n))
  1950  		value := []byte(fmt.Sprintf("v:%d", n))
  1951  		kvs = append(kvs, &types.KeyValue{Key: key, Value: value})
  1952  	}
  1953  	return kvs
  1954  }
  1955  
  1956  func genKV(height int64, txN int64) (kvs []*types.KeyValue) {
  1957  	for i := int64(0); i < txN; i++ {
  1958  		n := height*txN + i
  1959  		key := i2b(int32(n))
  1960  		value := Sha256(key)
  1961  		kvs = append(kvs, &types.KeyValue{Key: key, Value: value})
  1962  	}
  1963  	return kvs
  1964  }
  1965  
  1966  func saveBlock(dbm db.DB, height int64, hash []byte, txN int64, mvcc bool, treeCfg *TreeConfig) (newHash []byte, err error) {
  1967  	t := NewTree(dbm, true, treeCfg)
  1968  	t.Load(hash)
  1969  	kvs := genKV(height, txN)
  1970  	for _, kv := range kvs {
  1971  		t.Set(kv.Key, kv.Value)
  1972  	}
  1973  	newHash = t.Save()
  1974  	if mvcc {
  1975  		mvccdb := db.NewMVCC(dbm)
  1976  		newkvs, err := mvccdb.AddMVCC(kvs, newHash, hash, height)
  1977  		if err != nil {
  1978  			return nil, err
  1979  		}
  1980  		batch := dbm.NewBatch(true)
  1981  		for _, kv := range newkvs {
  1982  			batch.Set(kv.Key, kv.Value)
  1983  		}
  1984  		err = batch.Write()
  1985  		if err != nil {
  1986  			return nil, err
  1987  		}
  1988  	}
  1989  	return newHash, nil
  1990  }
  1991  
  1992  func TestSize1(t *testing.T) {
  1993  	type storeNode struct {
  1994  		Key       []byte
  1995  		Value     []byte
  1996  		LeftHash  []byte
  1997  		RightHash []byte
  1998  		Height    int32
  1999  		Size      int32
  2000  	}
  2001  	type storeNode1 struct {
  2002  		Key    [][]byte
  2003  		Height int32
  2004  		Size   int32
  2005  	}
  2006  	a := types.StoreNode{}
  2007  	b := storeNode{}
  2008  	var c []byte
  2009  	d := storeNode1{}
  2010  
  2011  	//arcmp := NewTreeARC(10 * 10000)
  2012  	//if arcmp == nil {
  2013  	//	return
  2014  	//}
  2015  	//
  2016  	//for i := 0; i < 10*10000; i++ {
  2017  	//	data := &storeNode{
  2018  	//		Key: []byte("12345678901234567890123456789012"),
  2019  	//		Value: []byte("12345678901234567890123456789012"),
  2020  	//		LeftHash: []byte("12345678901234567890123456789012"),
  2021  	//		RightHash: []byte("12345678901234567890123456789012"),
  2022  	//		//Key: copyBytes([]byte("12345678901234567890123456789012")),
  2023  	//		//Value: copyBytes([]byte("12345678901234567890123456789012")),
  2024  	//		//LeftHash: copyBytes([]byte("12345678901234567890123456789012")),
  2025  	//		//RightHash: copyBytes([]byte("12345678901234567890123456789012")),
  2026  	//		Height: 1,
  2027  	//		Size: 123,
  2028  	//	}
  2029  	//	arcmp.Add(int64(i), data)
  2030  	//}
  2031  
  2032  	//for i := 0; i < 100*10000; i++ {
  2033  	//	data := &storeNode1{}
  2034  	//	data.Height = 123
  2035  	//	data.Size = 123
  2036  	//	d.Key = make([][]byte, 4)
  2037  	//	//d.Key[0] = []byte("12345678901234567890123456789012")
  2038  	//	//d.Key[1] = []byte("12345678901234567890123456789012")
  2039  	//	//d.Key[2] = []byte("12345678901234567890123456789012")
  2040  	//	//d.Key[3] = []byte("12345678901234567890123456789012")
  2041  	//
  2042  	//	d.Key[0] = copyBytes([]byte("12345678901234567890123456789012"))
  2043  	//	d.Key[1] = copyBytes([]byte("12345678901234567890123456789012"))
  2044  	//	d.Key[2] = copyBytes([]byte("12345678901234567890123456789012"))
  2045  	//	d.Key[3] = copyBytes([]byte("12345678901234567890123456789012"))
  2046  	//	arcmp.Add(int64(i), data)
  2047  	//}
  2048  
  2049  	PrintMemStats(1)
  2050  	fmt.Println(unsafe.Sizeof(a), unsafe.Sizeof(b), unsafe.Sizeof(c), unsafe.Sizeof(d), len(d.Key), cap(d.Key))
  2051  }