github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/trie/trie.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:45</date> 10 //</624450123581100032> 11 12 13 //包trie实现Merkle Patricia尝试。 14 package trie 15 16 import ( 17 "bytes" 18 "fmt" 19 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/crypto" 22 "github.com/ethereum/go-ethereum/log" 23 "github.com/ethereum/go-ethereum/metrics" 24 ) 25 26 var ( 27 //EmptyRoot是空trie的已知根哈希。 28 emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") 29 30 //EmptyState是空状态trie项的已知哈希。 31 emptyState = crypto.Keccak256Hash(nil) 32 ) 33 34 var ( 35 cacheMissCounter = metrics.NewRegisteredCounter("trie/cachemiss", nil) 36 cacheUnloadCounter = metrics.NewRegisteredCounter("trie/cacheunload", nil) 37 ) 38 39 //cache misses检索测量缓存未命中数的全局计数器 40 //自进程启动后,trie已启动。除了 41 //测试调试目的。 42 func CacheMisses() int64 { 43 return cacheMissCounter.Count() 44 } 45 46 //cacheUnloads检索测量缓存卸载数的全局计数器 47 //自进程启动后,trie执行了操作。除了 48 //测试调试目的。 49 func CacheUnloads() int64 { 50 return cacheUnloadCounter.Count() 51 } 52 53 //leaf callback是当trie操作到达叶时调用的回调类型 54 //节点。状态同步和提交使用它来允许处理外部引用 55 //在帐户和存储尝试之间。 56 type LeafCallback func(leaf []byte, parent common.Hash) error 57 58 //特里尔是梅克尔·帕特里夏·特里尔。 59 //零值是一个没有数据库的空trie。 60 //使用new创建位于数据库顶部的trie。 61 // 62 //同时使用trie不安全。 63 type Trie struct { 64 db *Database 65 root node 66 67 //缓存生成值。 68 //cachegen随着每次提交操作增加一个。 69 //新节点用当前生成标记并卸载 70 //当其生成时间超过cachegen cachelimit时。 71 cachegen, cachelimit uint16 72 } 73 74 //setcachelimit设置要保留的“缓存生成数”。 75 //通过调用commit来创建缓存生成。 76 func (t *Trie) SetCacheLimit(l uint16) { 77 t.cachelimit = l 78 } 79 80 //newflag返回新创建节点的缓存标志值。 81 func (t *Trie) newFlag() nodeFlag { 82 return nodeFlag{dirty: true, gen: t.cachegen} 83 } 84 85 //新建使用数据库中的现有根节点创建trie。 86 // 87 //如果根是空字符串的零哈希或sha3哈希,则 88 //trie最初为空,不需要数据库。否则, 89 //如果db为nil,new将死机;如果root为nil,则返回MissingNodeError。 90 //数据库中不存在。访问trie将按需从db加载节点。 91 func New(root common.Hash, db *Database) (*Trie, error) { 92 if db == nil { 93 panic("trie.New called without a database") 94 } 95 trie := &Trie{ 96 db: db, 97 } 98 if root != (common.Hash{}) && root != emptyRoot { 99 rootnode, err := trie.resolveHash(root[:], nil) 100 if err != nil { 101 return nil, err 102 } 103 trie.root = rootnode 104 } 105 return trie, nil 106 } 107 108 //nodeiterator返回返回trie节点的迭代器。迭代开始于 109 //给定开始键之后的键。 110 func (t *Trie) NodeIterator(start []byte) NodeIterator { 111 return newNodeIterator(t, start) 112 } 113 114 //get返回存储在trie中的键的值。 115 //调用方不能修改值字节。 116 func (t *Trie) Get(key []byte) []byte { 117 res, err := t.TryGet(key) 118 if err != nil { 119 log.Error(fmt.Sprintf("Unhandled trie error: %v", err)) 120 } 121 return res 122 } 123 124 //Tryget返回存储在trie中的键的值。 125 //调用方不能修改值字节。 126 //如果在数据库中找不到节点,则返回MissingNodeError。 127 func (t *Trie) TryGet(key []byte) ([]byte, error) { 128 key = keybytesToHex(key) 129 value, newroot, didResolve, err := t.tryGet(t.root, key, 0) 130 if err == nil && didResolve { 131 t.root = newroot 132 } 133 return value, err 134 } 135 136 func (t *Trie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode node, didResolve bool, err error) { 137 switch n := (origNode).(type) { 138 case nil: 139 return nil, nil, false, nil 140 case valueNode: 141 return n, n, false, nil 142 case *shortNode: 143 if len(key)-pos < len(n.Key) || !bytes.Equal(n.Key, key[pos:pos+len(n.Key)]) { 144 //在trie中找不到密钥 145 return nil, n, false, nil 146 } 147 value, newnode, didResolve, err = t.tryGet(n.Val, key, pos+len(n.Key)) 148 if err == nil && didResolve { 149 n = n.copy() 150 n.Val = newnode 151 n.flags.gen = t.cachegen 152 } 153 return value, n, didResolve, err 154 case *fullNode: 155 value, newnode, didResolve, err = t.tryGet(n.Children[key[pos]], key, pos+1) 156 if err == nil && didResolve { 157 n = n.copy() 158 n.flags.gen = t.cachegen 159 n.Children[key[pos]] = newnode 160 } 161 return value, n, didResolve, err 162 case hashNode: 163 child, err := t.resolveHash(n, key[:pos]) 164 if err != nil { 165 return nil, n, true, err 166 } 167 value, newnode, _, err := t.tryGet(child, key, pos) 168 return value, newnode, true, err 169 default: 170 panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode)) 171 } 172 } 173 174 //更新trie中的关联键和值。后续呼叫 175 //get将返回值。如果值的长度为零,则任何现有值 176 //从trie中删除,调用get将返回nil。 177 // 178 //当值字节是 179 //存储在trie中。 180 func (t *Trie) Update(key, value []byte) { 181 if err := t.TryUpdate(key, value); err != nil { 182 log.Error(fmt.Sprintf("Unhandled trie error: %v", err)) 183 } 184 } 185 186 //TryUpdate将键与trie中的值关联。后续呼叫 187 //get将返回值。如果值的长度为零,则任何现有值 188 //从trie中删除,调用get将返回nil。 189 // 190 //当值字节是 191 //存储在trie中。 192 // 193 //如果在数据库中找不到节点,则返回MissingNodeError。 194 func (t *Trie) TryUpdate(key, value []byte) error { 195 k := keybytesToHex(key) 196 if len(value) != 0 { 197 _, n, err := t.insert(t.root, nil, k, valueNode(value)) 198 if err != nil { 199 return err 200 } 201 t.root = n 202 } else { 203 _, n, err := t.delete(t.root, nil, k) 204 if err != nil { 205 return err 206 } 207 t.root = n 208 } 209 return nil 210 } 211 212 func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error) { 213 if len(key) == 0 { 214 if v, ok := n.(valueNode); ok { 215 return !bytes.Equal(v, value.(valueNode)), value, nil 216 } 217 return true, value, nil 218 } 219 switch n := n.(type) { 220 case *shortNode: 221 matchlen := prefixLen(key, n.Key) 222 //如果整个键匹配,则保持此短节点不变 223 //只更新值。 224 if matchlen == len(n.Key) { 225 dirty, nn, err := t.insert(n.Val, append(prefix, key[:matchlen]...), key[matchlen:], value) 226 if !dirty || err != nil { 227 return false, n, err 228 } 229 return true, &shortNode{n.Key, nn, t.newFlag()}, nil 230 } 231 //否则,在不同的索引处进行分支。 232 branch := &fullNode{flags: t.newFlag()} 233 var err error 234 _, branch.Children[n.Key[matchlen]], err = t.insert(nil, append(prefix, n.Key[:matchlen+1]...), n.Key[matchlen+1:], n.Val) 235 if err != nil { 236 return false, nil, err 237 } 238 _, branch.Children[key[matchlen]], err = t.insert(nil, append(prefix, key[:matchlen+1]...), key[matchlen+1:], value) 239 if err != nil { 240 return false, nil, err 241 } 242 //如果此短代码出现在索引0处,则将其替换为分支。 243 if matchlen == 0 { 244 return true, branch, nil 245 } 246 //否则,将其替换为通向分支的短节点。 247 return true, &shortNode{key[:matchlen], branch, t.newFlag()}, nil 248 249 case *fullNode: 250 dirty, nn, err := t.insert(n.Children[key[0]], append(prefix, key[0]), key[1:], value) 251 if !dirty || err != nil { 252 return false, n, err 253 } 254 n = n.copy() 255 n.flags = t.newFlag() 256 n.Children[key[0]] = nn 257 return true, n, nil 258 259 case nil: 260 return true, &shortNode{key, value, t.newFlag()}, nil 261 262 case hashNode: 263 //我们击中了一个尚未加载的部分trie。负载 264 //并插入到节点中。这将使所有子节点保持打开状态 265 //trie中值的路径。 266 rn, err := t.resolveHash(n, prefix) 267 if err != nil { 268 return false, nil, err 269 } 270 dirty, nn, err := t.insert(rn, prefix, key, value) 271 if !dirty || err != nil { 272 return false, rn, err 273 } 274 return true, nn, nil 275 276 default: 277 panic(fmt.Sprintf("%T: invalid node: %v", n, n)) 278 } 279 } 280 281 //删除从trie中删除键的任何现有值。 282 func (t *Trie) Delete(key []byte) { 283 if err := t.TryDelete(key); err != nil { 284 log.Error(fmt.Sprintf("Unhandled trie error: %v", err)) 285 } 286 } 287 288 //Trydelete从trie中删除键的任何现有值。 289 //如果在数据库中找不到节点,则返回MissingNodeError。 290 func (t *Trie) TryDelete(key []byte) error { 291 k := keybytesToHex(key) 292 _, n, err := t.delete(t.root, nil, k) 293 if err != nil { 294 return err 295 } 296 t.root = n 297 return nil 298 } 299 300 //delete返回删除键的trie的新根。 301 //它通过简化将trie简化为最小形式 302 //递归删除后,节点正在向上移动。 303 func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { 304 switch n := n.(type) { 305 case *shortNode: 306 matchlen := prefixLen(key, n.Key) 307 if matchlen < len(n.Key) { 308 return false, n, nil //不匹配时不替换n 309 } 310 if matchlen == len(key) { 311 return true, nil, nil //对整个匹配完全删除n 312 } 313 //密钥比N.key长。删除其余后缀 314 //从子目录。孩子在这里永远不可能是零,因为 315 //Subrie必须包含至少两个具有键的其他值 316 //比N.key长。 317 dirty, child, err := t.delete(n.Val, append(prefix, key[:len(n.Key)]...), key[len(n.Key):]) 318 if !dirty || err != nil { 319 return false, n, err 320 } 321 switch child := child.(type) { 322 case *shortNode: 323 //从子目录中删除将其还原为另一个子目录 324 //短节点。合并节点以避免创建 325 //短代码…,短代码…。使用concat(其中 326 //总是创建一个新切片),而不是附加到 327 //避免修改n.key,因为它可能与共享 328 //其他节点。 329 return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil 330 default: 331 return true, &shortNode{n.Key, child, t.newFlag()}, nil 332 } 333 334 case *fullNode: 335 dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:]) 336 if !dirty || err != nil { 337 return false, n, err 338 } 339 n = n.copy() 340 n.flags = t.newFlag() 341 n.Children[key[0]] = nn 342 343 //检查删除后还有多少非零条目,以及 344 //如果只有一个条目,则将完整节点缩减为短节点 345 //左边。因为N至少有两个孩子 346 //删除前(否则将不是完整节点)n 347 //不能减为零。 348 // 349 //循环完成后,pos包含单个 350 //如果n至少包含两个,则保留在n或-2中的值 351 //价值观。 352 pos := -1 353 for i, cld := range &n.Children { 354 if cld != nil { 355 if pos == -1 { 356 pos = i 357 } else { 358 pos = -2 359 break 360 } 361 } 362 } 363 if pos >= 0 { 364 if pos != 16 { 365 //如果其余条目是短节点,则它将替换 366 //它的钥匙把丢失的小齿钉在 367 //前面。这样可以避免创建无效的 368 //短代码…,短代码…。进入以来 369 //可能尚未加载,仅为此解决 370 //检查。 371 cnode, err := t.resolve(n.Children[pos], prefix) 372 if err != nil { 373 return false, nil, err 374 } 375 if cnode, ok := cnode.(*shortNode); ok { 376 k := append([]byte{byte(pos)}, cnode.Key...) 377 return true, &shortNode{k, cnode.Val, t.newFlag()}, nil 378 } 379 } 380 //否则,n替换为一个半字节的短节点 381 //包含孩子。 382 return true, &shortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil 383 } 384 //n仍然包含至少两个值,不能减少。 385 return true, n, nil 386 387 case valueNode: 388 return true, nil, nil 389 390 case nil: 391 return false, nil, nil 392 393 case hashNode: 394 //我们击中了一个尚未加载的部分trie。负载 395 //并从中删除。这将使所有子节点保持打开状态 396 //trie中值的路径。 397 rn, err := t.resolveHash(n, prefix) 398 if err != nil { 399 return false, nil, err 400 } 401 dirty, nn, err := t.delete(rn, prefix, key) 402 if !dirty || err != nil { 403 return false, rn, err 404 } 405 return true, nn, nil 406 407 default: 408 panic(fmt.Sprintf("%T: invalid node: %v (%v)", n, n, key)) 409 } 410 } 411 412 func concat(s1 []byte, s2 ...byte) []byte { 413 r := make([]byte, len(s1)+len(s2)) 414 copy(r, s1) 415 copy(r[len(s1):], s2) 416 return r 417 } 418 419 func (t *Trie) resolve(n node, prefix []byte) (node, error) { 420 if n, ok := n.(hashNode); ok { 421 return t.resolveHash(n, prefix) 422 } 423 return n, nil 424 } 425 426 func (t *Trie) resolveHash(n hashNode, prefix []byte) (node, error) { 427 cacheMissCounter.Inc(1) 428 429 hash := common.BytesToHash(n) 430 if node := t.db.node(hash, t.cachegen); node != nil { 431 return node, nil 432 } 433 return nil, &MissingNodeError{NodeHash: hash, Path: prefix} 434 } 435 436 //根返回trie的根哈希。 437 //已弃用:请改用哈希。 438 func (t *Trie) Root() []byte { return t.Hash().Bytes() } 439 440 //哈希返回trie的根哈希。它不会写信给 441 //即使trie没有数据库也可以使用。 442 func (t *Trie) Hash() common.Hash { 443 hash, cached, _ := t.hashRoot(nil, nil) 444 t.root = cached 445 return common.BytesToHash(hash.(hashNode)) 446 } 447 448 //提交将所有节点写入trie的内存数据库,跟踪内部 449 //和外部(用于帐户尝试)引用。 450 func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) { 451 if t.db == nil { 452 panic("commit called on trie with nil database") 453 } 454 hash, cached, err := t.hashRoot(t.db, onleaf) 455 if err != nil { 456 return common.Hash{}, err 457 } 458 t.root = cached 459 t.cachegen++ 460 return common.BytesToHash(hash.(hashNode)), nil 461 } 462 463 func (t *Trie) hashRoot(db *Database, onleaf LeafCallback) (node, node, error) { 464 if t.root == nil { 465 return hashNode(emptyRoot.Bytes()), nil, nil 466 } 467 h := newHasher(t.cachegen, t.cachelimit, onleaf) 468 defer returnHasherToPool(h) 469 return h.hash(t.root, db, true) 470 } 471