github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/trie/node.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  //</624450123048423424>
    11  
    12  
    13  package trie
    14  
    15  import (
    16  	"fmt"
    17  	"io"
    18  	"strings"
    19  
    20  	"github.com/ethereum/go-ethereum/common"
    21  	"github.com/ethereum/go-ethereum/rlp"
    22  )
    23  
    24  var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"}
    25  
    26  type node interface {
    27  	fstring(string) string
    28  	cache() (hashNode, bool)
    29  	canUnload(cachegen, cachelimit uint16) bool
    30  }
    31  
    32  type (
    33  	fullNode struct {
    34  Children [17]node //要编码/解码的实际trie节点数据(需要自定义编码器)
    35  		flags    nodeFlag
    36  	}
    37  	shortNode struct {
    38  		Key   []byte
    39  		Val   node
    40  		flags nodeFlag
    41  	}
    42  	hashNode  []byte
    43  	valueNode []byte
    44  )
    45  
    46  //nilvalueNode用于折叠内部trie节点进行哈希,因为
    47  //未设置的子级需要正确序列化。
    48  var nilValueNode = valueNode(nil)
    49  
    50  //encoderlp将完整节点编码为共识rlp格式。
    51  func (n *fullNode) EncodeRLP(w io.Writer) error {
    52  	var nodes [17]node
    53  
    54  	for i, child := range &n.Children {
    55  		if child != nil {
    56  			nodes[i] = child
    57  		} else {
    58  			nodes[i] = nilValueNode
    59  		}
    60  	}
    61  	return rlp.Encode(w, nodes)
    62  }
    63  
    64  func (n *fullNode) copy() *fullNode   { copy := *n; return &copy }
    65  func (n *shortNode) copy() *shortNode { copy := *n; return &copy }
    66  
    67  //nodeFlag包含关于节点的缓存相关元数据。
    68  type nodeFlag struct {
    69  hash  hashNode //节点的缓存哈希(可以为零)
    70  gen   uint16   //缓存生成计数器
    71  dirty bool     //节点是否有必须写入数据库的更改
    72  }
    73  
    74  //canUnload指示是否可以卸载节点。
    75  func (n *nodeFlag) canUnload(cachegen, cachelimit uint16) bool {
    76  	return !n.dirty && cachegen-n.gen >= cachelimit
    77  }
    78  
    79  func (n *fullNode) canUnload(gen, limit uint16) bool  { return n.flags.canUnload(gen, limit) }
    80  func (n *shortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
    81  func (n hashNode) canUnload(uint16, uint16) bool      { return false }
    82  func (n valueNode) canUnload(uint16, uint16) bool     { return false }
    83  
    84  func (n *fullNode) cache() (hashNode, bool)  { return n.flags.hash, n.flags.dirty }
    85  func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty }
    86  func (n hashNode) cache() (hashNode, bool)   { return nil, true }
    87  func (n valueNode) cache() (hashNode, bool)  { return nil, true }
    88  
    89  //印刷精美。
    90  func (n *fullNode) String() string  { return n.fstring("") }
    91  func (n *shortNode) String() string { return n.fstring("") }
    92  func (n hashNode) String() string   { return n.fstring("") }
    93  func (n valueNode) String() string  { return n.fstring("") }
    94  
    95  func (n *fullNode) fstring(ind string) string {
    96  	resp := fmt.Sprintf("[\n%s  ", ind)
    97  	for i, node := range &n.Children {
    98  		if node == nil {
    99  			resp += fmt.Sprintf("%s: <nil> ", indices[i])
   100  		} else {
   101  			resp += fmt.Sprintf("%s: %v", indices[i], node.fstring(ind+"  "))
   102  		}
   103  	}
   104  	return resp + fmt.Sprintf("\n%s] ", ind)
   105  }
   106  func (n *shortNode) fstring(ind string) string {
   107  	return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+"  "))
   108  }
   109  func (n hashNode) fstring(ind string) string {
   110  	return fmt.Sprintf("<%x> ", []byte(n))
   111  }
   112  func (n valueNode) fstring(ind string) string {
   113  	return fmt.Sprintf("%x ", []byte(n))
   114  }
   115  
   116  func mustDecodeNode(hash, buf []byte, cachegen uint16) node {
   117  	n, err := decodeNode(hash, buf, cachegen)
   118  	if err != nil {
   119  		panic(fmt.Sprintf("node %x: %v", hash, err))
   120  	}
   121  	return n
   122  }
   123  
   124  //decodenode解析trie节点的rlp编码。
   125  func decodeNode(hash, buf []byte, cachegen uint16) (node, error) {
   126  	if len(buf) == 0 {
   127  		return nil, io.ErrUnexpectedEOF
   128  	}
   129  	elems, _, err := rlp.SplitList(buf)
   130  	if err != nil {
   131  		return nil, fmt.Errorf("decode error: %v", err)
   132  	}
   133  	switch c, _ := rlp.CountValues(elems); c {
   134  	case 2:
   135  		n, err := decodeShort(hash, elems, cachegen)
   136  		return n, wrapError(err, "short")
   137  	case 17:
   138  		n, err := decodeFull(hash, elems, cachegen)
   139  		return n, wrapError(err, "full")
   140  	default:
   141  		return nil, fmt.Errorf("invalid number of list elements: %v", c)
   142  	}
   143  }
   144  
   145  func decodeShort(hash, elems []byte, cachegen uint16) (node, error) {
   146  	kbuf, rest, err := rlp.SplitString(elems)
   147  	if err != nil {
   148  		return nil, err
   149  	}
   150  	flag := nodeFlag{hash: hash, gen: cachegen}
   151  	key := compactToHex(kbuf)
   152  	if hasTerm(key) {
   153  //价值节点
   154  		val, _, err := rlp.SplitString(rest)
   155  		if err != nil {
   156  			return nil, fmt.Errorf("invalid value node: %v", err)
   157  		}
   158  		return &shortNode{key, append(valueNode{}, val...), flag}, nil
   159  	}
   160  	r, _, err := decodeRef(rest, cachegen)
   161  	if err != nil {
   162  		return nil, wrapError(err, "val")
   163  	}
   164  	return &shortNode{key, r, flag}, nil
   165  }
   166  
   167  func decodeFull(hash, elems []byte, cachegen uint16) (*fullNode, error) {
   168  	n := &fullNode{flags: nodeFlag{hash: hash, gen: cachegen}}
   169  	for i := 0; i < 16; i++ {
   170  		cld, rest, err := decodeRef(elems, cachegen)
   171  		if err != nil {
   172  			return n, wrapError(err, fmt.Sprintf("[%d]", i))
   173  		}
   174  		n.Children[i], elems = cld, rest
   175  	}
   176  	val, _, err := rlp.SplitString(elems)
   177  	if err != nil {
   178  		return n, err
   179  	}
   180  	if len(val) > 0 {
   181  		n.Children[16] = append(valueNode{}, val...)
   182  	}
   183  	return n, nil
   184  }
   185  
   186  const hashLen = len(common.Hash{})
   187  
   188  func decodeRef(buf []byte, cachegen uint16) (node, []byte, error) {
   189  	kind, val, rest, err := rlp.Split(buf)
   190  	if err != nil {
   191  		return nil, buf, err
   192  	}
   193  	switch {
   194  	case kind == rlp.List:
   195  //“Embedded”节点引用。编码必须更小
   196  //而不是散列以便有效。
   197  		if size := len(buf) - len(rest); size > hashLen {
   198  			err := fmt.Errorf("oversized embedded node (size is %d bytes, want size < %d)", size, hashLen)
   199  			return nil, buf, err
   200  		}
   201  		n, err := decodeNode(nil, buf, cachegen)
   202  		return n, rest, err
   203  	case kind == rlp.String && len(val) == 0:
   204  //空节点
   205  		return nil, rest, nil
   206  	case kind == rlp.String && len(val) == 32:
   207  		return append(hashNode{}, val...), rest, nil
   208  	default:
   209  		return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val))
   210  	}
   211  }
   212  
   213  //使用有关到的路径的信息包装解码错误
   214  //子节点无效(用于调试编码问题)。
   215  type decodeError struct {
   216  	what  error
   217  	stack []string
   218  }
   219  
   220  func wrapError(err error, ctx string) error {
   221  	if err == nil {
   222  		return nil
   223  	}
   224  	if decErr, ok := err.(*decodeError); ok {
   225  		decErr.stack = append(decErr.stack, ctx)
   226  		return decErr
   227  	}
   228  	return &decodeError{err, []string{ctx}}
   229  }
   230  
   231  func (err *decodeError) Error() string {
   232  	return fmt.Sprintf("%v (decode path: %s)", err.what, strings.Join(err.stack, "<-"))
   233  }
   234