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 © } 65 func (n *shortNode) copy() *shortNode { copy := *n; return © } 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