github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/trie/secure_trie_test.go (about)

     1  package trie
     2  
     3  import (
     4  	"bytes"
     5  	"runtime"
     6  	"sync"
     7  	"testing"
     8  
     9  	"github.com/neatlab/neatio/neatdb/memorydb"
    10  	"github.com/neatlab/neatio/utilities/common"
    11  	"github.com/neatlab/neatio/utilities/crypto"
    12  )
    13  
    14  func newEmptySecure() *SecureTrie {
    15  	trie, _ := NewSecure(common.Hash{}, NewDatabase(memorydb.New()))
    16  	return trie
    17  }
    18  
    19  func makeTestSecureTrie() (*Database, *SecureTrie, map[string][]byte) {
    20  
    21  	triedb := NewDatabase(memorydb.New())
    22  	trie, _ := NewSecure(common.Hash{}, triedb)
    23  
    24  	content := make(map[string][]byte)
    25  	for i := byte(0); i < 255; i++ {
    26  
    27  		key, val := common.LeftPadBytes([]byte{1, i}, 32), []byte{i}
    28  		content[string(key)] = val
    29  		trie.Update(key, val)
    30  
    31  		key, val = common.LeftPadBytes([]byte{2, i}, 32), []byte{i}
    32  		content[string(key)] = val
    33  		trie.Update(key, val)
    34  
    35  		for j := byte(3); j < 13; j++ {
    36  			key, val = common.LeftPadBytes([]byte{j, i}, 32), []byte{j, i}
    37  			content[string(key)] = val
    38  			trie.Update(key, val)
    39  		}
    40  	}
    41  	trie.Commit(nil)
    42  
    43  	return triedb, trie, content
    44  }
    45  
    46  func TestSecureDelete(t *testing.T) {
    47  	trie := newEmptySecure()
    48  	vals := []struct{ k, v string }{
    49  		{"do", "verb"},
    50  		{"ether", "wookiedoo"},
    51  		{"horse", "stallion"},
    52  		{"shaman", "horse"},
    53  		{"doge", "coin"},
    54  		{"ether", ""},
    55  		{"dog", "puppy"},
    56  		{"shaman", ""},
    57  	}
    58  	for _, val := range vals {
    59  		if val.v != "" {
    60  			trie.Update([]byte(val.k), []byte(val.v))
    61  		} else {
    62  			trie.Delete([]byte(val.k))
    63  		}
    64  	}
    65  	hash := trie.Hash()
    66  	exp := common.HexToHash("29b235a58c3c25ab83010c327d5932bcf05324b7d6b1185e650798034783ca9d")
    67  	if hash != exp {
    68  		t.Errorf("expected %x got %x", exp, hash)
    69  	}
    70  }
    71  
    72  func TestSecureGetKey(t *testing.T) {
    73  	trie := newEmptySecure()
    74  	trie.Update([]byte("foo"), []byte("bar"))
    75  
    76  	key := []byte("foo")
    77  	value := []byte("bar")
    78  	seckey := crypto.Keccak256(key)
    79  
    80  	if !bytes.Equal(trie.Get(key), value) {
    81  		t.Errorf("Get did not return bar")
    82  	}
    83  	if k := trie.GetKey(seckey); !bytes.Equal(k, key) {
    84  		t.Errorf("GetKey returned %q, want %q", k, key)
    85  	}
    86  }
    87  
    88  func TestSecureTrieConcurrency(t *testing.T) {
    89  
    90  	_, trie, _ := makeTestSecureTrie()
    91  
    92  	threads := runtime.NumCPU()
    93  	tries := make([]*SecureTrie, threads)
    94  	for i := 0; i < threads; i++ {
    95  		cpy := *trie
    96  		tries[i] = &cpy
    97  	}
    98  
    99  	pend := new(sync.WaitGroup)
   100  	pend.Add(threads)
   101  	for i := 0; i < threads; i++ {
   102  		go func(index int) {
   103  			defer pend.Done()
   104  
   105  			for j := byte(0); j < 255; j++ {
   106  
   107  				key, val := common.LeftPadBytes([]byte{byte(index), 1, j}, 32), []byte{j}
   108  				tries[index].Update(key, val)
   109  
   110  				key, val = common.LeftPadBytes([]byte{byte(index), 2, j}, 32), []byte{j}
   111  				tries[index].Update(key, val)
   112  
   113  				for k := byte(3); k < 13; k++ {
   114  					key, val = common.LeftPadBytes([]byte{byte(index), k, j}, 32), []byte{k, j}
   115  					tries[index].Update(key, val)
   116  				}
   117  			}
   118  			tries[index].Commit(nil)
   119  		}(i)
   120  	}
   121  
   122  	pend.Wait()
   123  }