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