github.com/annchain/OG@v0.0.9/trie/node.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package trie 18 19 import ( 20 "bytes" 21 "fmt" 22 "io" 23 "strings" 24 25 "github.com/tinylib/msgp/msgp" 26 ) 27 28 var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"} 29 30 type Node interface { 31 fstring(string) string 32 nodeType() nodetype 33 cache() (HashNode, bool) 34 canUnload(cachegen, cachelimit uint16) bool 35 encodeNode() []byte 36 String() string 37 DecodeMsg(dc *msgp.Reader) error 38 EncodeMsg(en *msgp.Writer) error 39 MarshalMsg(b []byte) ([]byte, error) 40 Msgsize() int 41 } 42 43 //go:generate msgp 44 45 //msgp:tuple FullNode 46 type FullNode struct { 47 Children [17]Node // Actual trie node data to encode/decode (needs custom encoder) 48 flags nodeFlag 49 } 50 51 //msgp:tuple ShortNode 52 type ShortNode struct { 53 Key []byte 54 Val Node 55 flags nodeFlag 56 } 57 58 //msgp: HashNode 59 type HashNode []byte 60 61 //msgp: ValueNode 62 type ValueNode []byte 63 64 func (n *FullNode) copy() *FullNode { copy := *n; return © } 65 func (n *ShortNode) copy() *ShortNode { copy := *n; return © } 66 67 // nodeFlag contains caching-related metadata about a node. 68 type nodeFlag struct { 69 hash HashNode // cached hash of the node (may be nil) 70 gen uint16 // cache generation counter 71 dirty bool // whether the node has changes that must be written to the database 72 } 73 74 // canUnload tells whether a node can be unloaded. 75 func (n *nodeFlag) canUnload(cachegen, cachelimit uint16) bool { 76 return !n.dirty && cachegen-n.gen >= cachelimit 77 } 78 79 type nodetype int 80 81 const ( 82 nilnode nodetype = iota 83 fullnode 84 shortnode 85 hashnode 86 valuenode 87 ) 88 89 func (n *FullNode) nodeType() nodetype { return fullnode } 90 func (n *ShortNode) nodeType() nodetype { return shortnode } 91 func (n HashNode) nodeType() nodetype { return hashnode } 92 func (n ValueNode) nodeType() nodetype { return valuenode } 93 94 func (n *FullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } 95 func (n *ShortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } 96 func (n HashNode) canUnload(uint16, uint16) bool { return false } 97 func (n ValueNode) canUnload(uint16, uint16) bool { return false } 98 99 func (n *FullNode) cache() (HashNode, bool) { return n.flags.hash, n.flags.dirty } 100 func (n *ShortNode) cache() (HashNode, bool) { return n.flags.hash, n.flags.dirty } 101 func (n HashNode) cache() (HashNode, bool) { return nil, true } 102 func (n ValueNode) cache() (HashNode, bool) { return nil, true } 103 104 // Pretty printing. 105 func (n *FullNode) String() string { return n.fstring("") } 106 func (n *ShortNode) String() string { return n.fstring("") } 107 func (n HashNode) String() string { return n.fstring("") } 108 func (n ValueNode) String() string { return n.fstring("") } 109 110 func (n *FullNode) fstring(ind string) string { 111 resp := fmt.Sprintf("[\n%s ", ind) 112 for i, node := range n.Children { 113 if node == nil { 114 resp += fmt.Sprintf("%s: <nil> ", indices[i]) 115 } else { 116 resp += fmt.Sprintf("%s: %v", indices[i], node.fstring(ind+" ")) 117 } 118 } 119 return resp + fmt.Sprintf("\n%s] ", ind) 120 } 121 func (n *ShortNode) fstring(ind string) string { 122 return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" ")) 123 } 124 func (n HashNode) fstring(ind string) string { 125 return fmt.Sprintf("<%x> ", []byte(n)) 126 } 127 func (n ValueNode) fstring(ind string) string { 128 return fmt.Sprintf("%x ", []byte(n)) 129 } 130 131 var ( 132 encodePrefixFullNode = []byte("f") 133 encodePrefixShortNode = []byte("s") 134 encodePrefixHashNode = []byte("h") 135 encodePrefixValueNode = []byte("v") 136 ) 137 138 func (n *FullNode) encodeNode() []byte { 139 data, _ := n.MarshalMsg(nil) 140 return append(encodePrefixFullNode, data...) 141 } 142 func (n *ShortNode) encodeNode() []byte { 143 data, _ := n.MarshalMsg(nil) 144 return append(encodePrefixShortNode, data...) 145 } 146 func (n HashNode) encodeNode() []byte { 147 data, _ := n.MarshalMsg(nil) 148 return append(encodePrefixHashNode, data...) 149 } 150 func (n ValueNode) encodeNode() []byte { 151 data, _ := n.MarshalMsg(nil) 152 return append(encodePrefixValueNode, data...) 153 } 154 155 func mustDecodeNode(hash, buf []byte, cachegen uint16) Node { 156 n, err := decodeNode(hash, buf, cachegen) 157 if err != nil { 158 panic(fmt.Sprintf("node %x: %v", hash, err)) 159 } 160 return n 161 } 162 163 // decodeNode parses the msgp encoding of a trie node. 164 func decodeNode(hash, buf []byte, cachegen uint16) (Node, error) { 165 if len(buf) == 0 { 166 return nil, io.ErrUnexpectedEOF 167 } 168 169 prefix := buf[:len(encodePrefixFullNode)] 170 data := buf[len(encodePrefixFullNode):] 171 172 if bytes.Equal(prefix, encodePrefixFullNode) { 173 n, err := decodeFull(hash, data, cachegen) 174 175 //log.Tracef("Panic debug, decode Fullnode, hash: %x, data: %x, fullnode: %s", hash, data, n.String()) 176 return n, wrapError(err, "full") 177 } 178 if bytes.Equal(prefix, encodePrefixShortNode) { 179 n, err := decodeShort(hash, data, cachegen) 180 181 //log.Tracef("Panic debug, decode Shortnode, hash: %x, data: %x, shortnode: %s", hash, data, n.String()) 182 return n, wrapError(err, "short") 183 } 184 return nil, fmt.Errorf("invalid prefix of encoded node: %v", prefix) 185 } 186 187 func decodeFull(hash, data []byte, cachegen uint16) (*FullNode, error) { 188 var n FullNode 189 _, err := n.UnmarshalMsg(data) 190 if err != nil { 191 return &n, err 192 } 193 194 flag := nodeFlag{hash: hash, gen: cachegen} 195 n.flags = flag 196 return &n, nil 197 } 198 199 func decodeShort(hash, data []byte, cachegen uint16) (Node, error) { 200 var n ShortNode 201 _, err := n.UnmarshalMsg(data) 202 if err != nil { 203 return &n, err 204 } 205 n.Key = compactToHex(n.Key) 206 207 flag := nodeFlag{hash: hash, gen: cachegen} 208 n.flags = flag 209 210 return &n, nil 211 } 212 213 // wraps a decoding error with information about the path to the 214 // invalid child node (for debugging encoding issues). 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 }