github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/trie/proof_test.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // Copyright 2019 The go-aigar Authors 3 // This file is part of the go-aigar library. 4 // 5 // The go-aigar library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser 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-aigar 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 Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>. 17 18 package trie 19 20 import ( 21 "bytes" 22 crand "crypto/rand" 23 mrand "math/rand" 24 "testing" 25 "time" 26 27 "github.com/AigarNetwork/aigar/common" 28 "github.com/AigarNetwork/aigar/crypto" 29 "github.com/AigarNetwork/aigar/ethdb/memorydb" 30 ) 31 32 func init() { 33 mrand.Seed(time.Now().Unix()) 34 } 35 36 // makeProvers creates Merkle trie provers based on different implementations to 37 // test all variations. 38 func makeProvers(trie *Trie) []func(key []byte) *memorydb.Database { 39 var provers []func(key []byte) *memorydb.Database 40 41 // Create a direct trie based Merkle prover 42 provers = append(provers, func(key []byte) *memorydb.Database { 43 proof := memorydb.New() 44 trie.Prove(key, 0, proof) 45 return proof 46 }) 47 // Create a leaf iterator based Merkle prover 48 provers = append(provers, func(key []byte) *memorydb.Database { 49 proof := memorydb.New() 50 if it := NewIterator(trie.NodeIterator(key)); it.Next() && bytes.Equal(key, it.Key) { 51 for _, p := range it.Prove() { 52 proof.Put(crypto.Keccak256(p), p) 53 } 54 } 55 return proof 56 }) 57 return provers 58 } 59 60 func TestProof(t *testing.T) { 61 trie, vals := randomTrie(500) 62 root := trie.Hash() 63 for i, prover := range makeProvers(trie) { 64 for _, kv := range vals { 65 proof := prover(kv.k) 66 if proof == nil { 67 t.Fatalf("prover %d: missing key %x while constructing proof", i, kv.k) 68 } 69 val, _, err := VerifyProof(root, kv.k, proof) 70 if err != nil { 71 t.Fatalf("prover %d: failed to verify proof for key %x: %v\nraw proof: %x", i, kv.k, err, proof) 72 } 73 if !bytes.Equal(val, kv.v) { 74 t.Fatalf("prover %d: verified value mismatch for key %x: have %x, want %x", i, kv.k, val, kv.v) 75 } 76 } 77 } 78 } 79 80 func TestOneElementProof(t *testing.T) { 81 trie := new(Trie) 82 updateString(trie, "k", "v") 83 for i, prover := range makeProvers(trie) { 84 proof := prover([]byte("k")) 85 if proof == nil { 86 t.Fatalf("prover %d: nil proof", i) 87 } 88 if proof.Len() != 1 { 89 t.Errorf("prover %d: proof should have one element", i) 90 } 91 val, _, err := VerifyProof(trie.Hash(), []byte("k"), proof) 92 if err != nil { 93 t.Fatalf("prover %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) 94 } 95 if !bytes.Equal(val, []byte("v")) { 96 t.Fatalf("prover %d: verified value mismatch: have %x, want 'k'", i, val) 97 } 98 } 99 } 100 101 func TestBadProof(t *testing.T) { 102 trie, vals := randomTrie(800) 103 root := trie.Hash() 104 for i, prover := range makeProvers(trie) { 105 for _, kv := range vals { 106 proof := prover(kv.k) 107 if proof == nil { 108 t.Fatalf("prover %d: nil proof", i) 109 } 110 it := proof.NewIterator() 111 for i, d := 0, mrand.Intn(proof.Len()); i <= d; i++ { 112 it.Next() 113 } 114 key := it.Key() 115 val, _ := proof.Get(key) 116 proof.Delete(key) 117 it.Release() 118 119 mutateByte(val) 120 proof.Put(crypto.Keccak256(val), val) 121 122 if _, _, err := VerifyProof(root, kv.k, proof); err == nil { 123 t.Fatalf("prover %d: expected proof to fail for key %x", i, kv.k) 124 } 125 } 126 } 127 } 128 129 // Tests that missing keys can also be proven. The test explicitly uses a single 130 // entry trie and checks for missing keys both before and after the single entry. 131 func TestMissingKeyProof(t *testing.T) { 132 trie := new(Trie) 133 updateString(trie, "k", "v") 134 135 for i, key := range []string{"a", "j", "l", "z"} { 136 proof := memorydb.New() 137 trie.Prove([]byte(key), 0, proof) 138 139 if proof.Len() != 1 { 140 t.Errorf("test %d: proof should have one element", i) 141 } 142 val, _, err := VerifyProof(trie.Hash(), []byte(key), proof) 143 if err != nil { 144 t.Fatalf("test %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) 145 } 146 if val != nil { 147 t.Fatalf("test %d: verified value mismatch: have %x, want nil", i, val) 148 } 149 } 150 } 151 152 // mutateByte changes one byte in b. 153 func mutateByte(b []byte) { 154 for r := mrand.Intn(len(b)); ; { 155 new := byte(mrand.Intn(255)) 156 if new != b[r] { 157 b[r] = new 158 break 159 } 160 } 161 } 162 163 func BenchmarkProve(b *testing.B) { 164 trie, vals := randomTrie(100) 165 var keys []string 166 for k := range vals { 167 keys = append(keys, k) 168 } 169 170 b.ResetTimer() 171 for i := 0; i < b.N; i++ { 172 kv := vals[keys[i%len(keys)]] 173 proofs := memorydb.New() 174 if trie.Prove(kv.k, 0, proofs); proofs.Len() == 0 { 175 b.Fatalf("zero length proof for %x", kv.k) 176 } 177 } 178 } 179 180 func BenchmarkVerifyProof(b *testing.B) { 181 trie, vals := randomTrie(100) 182 root := trie.Hash() 183 var keys []string 184 var proofs []*memorydb.Database 185 for k := range vals { 186 keys = append(keys, k) 187 proof := memorydb.New() 188 trie.Prove([]byte(k), 0, proof) 189 proofs = append(proofs, proof) 190 } 191 192 b.ResetTimer() 193 for i := 0; i < b.N; i++ { 194 im := i % len(keys) 195 if _, _, err := VerifyProof(root, []byte(keys[im]), proofs[im]); err != nil { 196 b.Fatalf("key %x: %v", keys[im], err) 197 } 198 } 199 } 200 201 func randomTrie(n int) (*Trie, map[string]*kv) { 202 trie := new(Trie) 203 vals := make(map[string]*kv) 204 for i := byte(0); i < 100; i++ { 205 value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 206 value2 := &kv{common.LeftPadBytes([]byte{i + 10}, 32), []byte{i}, false} 207 trie.Update(value.k, value.v) 208 trie.Update(value2.k, value2.v) 209 vals[string(value.k)] = value 210 vals[string(value2.k)] = value2 211 } 212 for i := 0; i < n; i++ { 213 value := &kv{randBytes(32), randBytes(20), false} 214 trie.Update(value.k, value.v) 215 vals[string(value.k)] = value 216 } 217 return trie, vals 218 } 219 220 func randBytes(n int) []byte { 221 r := make([]byte, n) 222 crand.Read(r) 223 return r 224 }