github.com/klaytn/klaytn@v1.10.2/storage/statedb/node.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from trie/node.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package statedb 22 23 import ( 24 "fmt" 25 "io" 26 "strings" 27 28 "github.com/klaytn/klaytn/common" 29 "github.com/klaytn/klaytn/rlp" 30 ) 31 32 var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"} 33 34 type node interface { 35 fstring(string) string 36 cache() (hashNode, bool) 37 lenEncoded() uint16 38 } 39 40 type ( 41 fullNode struct { 42 Children [17]node // Actual trie node data to encode/decode (needs custom encoder) 43 flags nodeFlag 44 } 45 shortNode struct { 46 Key []byte 47 Val node 48 flags nodeFlag 49 } 50 hashNode []byte 51 valueNode []byte 52 ) 53 54 // nilValueNode is used when collapsing internal trie nodes for hashing, since 55 // unset children need to serialize correctly. 56 var nilValueNode = valueNode(nil) 57 58 // EncodeRLP encodes a full node into the consensus RLP format. 59 func (n *fullNode) EncodeRLP(w io.Writer) error { 60 var nodes [17]node 61 62 for i, child := range &n.Children { 63 if child != nil { 64 nodes[i] = child 65 } else { 66 nodes[i] = nilValueNode 67 } 68 } 69 return rlp.Encode(w, nodes) 70 } 71 72 func (n *fullNode) copy() *fullNode { copy := *n; return © } 73 func (n *shortNode) copy() *shortNode { copy := *n; return © } 74 75 // nodeFlag contains caching-related metadata about a node. 76 type nodeFlag struct { 77 hash hashNode // cached hash of the node (may be nil). 78 dirty bool // whether the node has changes that must be written to the database. 79 lenEncoded uint16 // lenEncoded caches the encoding length of the node. 80 } 81 82 func (n *fullNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } 83 func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } 84 func (n hashNode) cache() (hashNode, bool) { return nil, true } 85 func (n valueNode) cache() (hashNode, bool) { return nil, true } 86 87 func (n *fullNode) lenEncoded() uint16 { return n.flags.lenEncoded } 88 func (n *shortNode) lenEncoded() uint16 { return n.flags.lenEncoded } 89 func (n hashNode) lenEncoded() uint16 { return 0 } 90 func (n valueNode) lenEncoded() uint16 { return 0 } 91 92 // Pretty printing. 93 func (n *fullNode) String() string { return n.fstring("") } 94 func (n *shortNode) String() string { return n.fstring("") } 95 func (n hashNode) String() string { return n.fstring("") } 96 func (n valueNode) String() string { return n.fstring("") } 97 98 func (n *fullNode) fstring(ind string) string { 99 resp := fmt.Sprintf("[\n%s ", ind) 100 for i, node := range &n.Children { 101 if node == nil { 102 resp += fmt.Sprintf("%s: <nil> ", indices[i]) 103 } else { 104 resp += fmt.Sprintf("%s: %v", indices[i], node.fstring(ind+" ")) 105 } 106 } 107 return resp + fmt.Sprintf("\n%s] ", ind) 108 } 109 110 func (n *shortNode) fstring(ind string) string { 111 return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" ")) 112 } 113 114 func (n hashNode) fstring(ind string) string { 115 return fmt.Sprintf("<%x> ", []byte(n)) 116 } 117 118 func (n valueNode) fstring(ind string) string { 119 return fmt.Sprintf("%x ", []byte(n)) 120 } 121 122 func mustDecodeNode(hash, buf []byte) node { 123 n, err := decodeNode(hash, buf) 124 if err != nil { 125 panic(fmt.Sprintf("node %x: %v", hash, err)) 126 } 127 return n 128 } 129 130 // decodeNode parses the RLP encoding of a trie node. 131 func decodeNode(hash, buf []byte) (node, error) { 132 if len(buf) == 0 { 133 return nil, io.ErrUnexpectedEOF 134 } 135 elems, _, err := rlp.SplitList(buf) 136 if err != nil { 137 return nil, fmt.Errorf("decode error: %v", err) 138 } 139 switch c, _ := rlp.CountValues(elems); c { 140 case 2: 141 n, err := decodeShort(hash, elems) 142 return n, wrapError(err, "short") 143 case 17: 144 n, err := decodeFull(hash, elems) 145 return n, wrapError(err, "full") 146 default: 147 return nil, fmt.Errorf("invalid number of list elements: %v", c) 148 } 149 } 150 151 func decodeShort(hash, elems []byte) (node, error) { 152 kbuf, rest, err := rlp.SplitString(elems) 153 if err != nil { 154 return nil, err 155 } 156 flag := nodeFlag{hash: hash} 157 key := compactToHex(kbuf) 158 if hasTerm(key) { 159 // value node 160 val, _, err := rlp.SplitString(rest) 161 if err != nil { 162 return nil, fmt.Errorf("invalid value node: %v", err) 163 } 164 return &shortNode{key, append(valueNode{}, val...), flag}, nil 165 } 166 r, _, err := decodeRef(rest) 167 if err != nil { 168 return nil, wrapError(err, "val") 169 } 170 return &shortNode{key, r, flag}, nil 171 } 172 173 func decodeFull(hash, elems []byte) (*fullNode, error) { 174 n := &fullNode{flags: nodeFlag{hash: hash}} 175 for i := 0; i < 16; i++ { 176 cld, rest, err := decodeRef(elems) 177 if err != nil { 178 return n, wrapError(err, fmt.Sprintf("[%d]", i)) 179 } 180 n.Children[i], elems = cld, rest 181 } 182 val, _, err := rlp.SplitString(elems) 183 if err != nil { 184 return n, err 185 } 186 if len(val) > 0 { 187 n.Children[16] = append(valueNode{}, val...) 188 } 189 return n, nil 190 } 191 192 const hashLen = len(common.Hash{}) 193 194 func decodeRef(buf []byte) (node, []byte, error) { 195 kind, val, rest, err := rlp.Split(buf) 196 if err != nil { 197 return nil, buf, err 198 } 199 switch { 200 case kind == rlp.List: 201 // 'embedded' node reference. The encoding must be smaller 202 // than a hash in order to be valid. 203 if size := len(buf) - len(rest); size > hashLen { 204 err := fmt.Errorf("oversized embedded node (size is %d bytes, want size < %d)", size, hashLen) 205 return nil, buf, err 206 } 207 n, err := decodeNode(nil, buf) 208 return n, rest, err 209 case kind == rlp.String && len(val) == 0: 210 // empty node 211 return nil, rest, nil 212 case kind == rlp.String && len(val) == 32: 213 return append(hashNode{}, val...), rest, nil 214 default: 215 return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val)) 216 } 217 } 218 219 // wraps a decoding error with information about the path to the 220 // invalid child node (for debugging encoding issues). 221 type decodeError struct { 222 what error 223 stack []string 224 } 225 226 func wrapError(err error, ctx string) error { 227 if err == nil { 228 return nil 229 } 230 if decErr, ok := err.(*decodeError); ok { 231 decErr.stack = append(decErr.stack, ctx) 232 return decErr 233 } 234 return &decodeError{err, []string{ctx}} 235 } 236 237 func (err *decodeError) Error() string { 238 return fmt.Sprintf("%v (decode path: %s)", err.what, strings.Join(err.stack, "<-")) 239 }