github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/trie/node.go (about) 1 package trie 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 8 "github.com/quickchainproject/quickchain/common" 9 "github.com/quickchainproject/quickchain/rlp" 10 ) 11 12 var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"} 13 14 type node interface { 15 fstring(string) string 16 cache() (hashNode, bool) 17 canUnload(cachegen, cachelimit uint16) bool 18 } 19 20 type ( 21 fullNode struct { 22 Children [17]node // Actual trie node data to encode/decode (needs custom encoder) 23 flags nodeFlag 24 } 25 shortNode struct { 26 Key []byte 27 Val node 28 flags nodeFlag 29 } 30 hashNode []byte 31 valueNode []byte 32 ) 33 34 // EncodeRLP encodes a full node into the consensus RLP format. 35 func (n *fullNode) EncodeRLP(w io.Writer) error { 36 return rlp.Encode(w, n.Children) 37 } 38 39 func (n *fullNode) copy() *fullNode { copy := *n; return © } 40 func (n *shortNode) copy() *shortNode { copy := *n; return © } 41 42 // nodeFlag contains caching-related metadata about a node. 43 type nodeFlag struct { 44 hash hashNode // cached hash of the node (may be nil) 45 gen uint16 // cache generation counter 46 dirty bool // whether the node has changes that must be written to the database 47 } 48 49 // canUnload tells whether a node can be unloaded. 50 func (n *nodeFlag) canUnload(cachegen, cachelimit uint16) bool { 51 return !n.dirty && cachegen-n.gen >= cachelimit 52 } 53 54 func (n *fullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } 55 func (n *shortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } 56 func (n hashNode) canUnload(uint16, uint16) bool { return false } 57 func (n valueNode) canUnload(uint16, uint16) bool { return false } 58 59 func (n *fullNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } 60 func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } 61 func (n hashNode) cache() (hashNode, bool) { return nil, true } 62 func (n valueNode) cache() (hashNode, bool) { return nil, true } 63 64 // Pretty printing. 65 func (n *fullNode) String() string { return n.fstring("") } 66 func (n *shortNode) String() string { return n.fstring("") } 67 func (n hashNode) String() string { return n.fstring("") } 68 func (n valueNode) String() string { return n.fstring("") } 69 70 func (n *fullNode) fstring(ind string) string { 71 resp := fmt.Sprintf("[\n%s ", ind) 72 for i, node := range n.Children { 73 if node == nil { 74 resp += fmt.Sprintf("%s: <nil> ", indices[i]) 75 } else { 76 resp += fmt.Sprintf("%s: %v", indices[i], node.fstring(ind+" ")) 77 } 78 } 79 return resp + fmt.Sprintf("\n%s] ", ind) 80 } 81 func (n *shortNode) fstring(ind string) string { 82 return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" ")) 83 } 84 func (n hashNode) fstring(ind string) string { 85 return fmt.Sprintf("<%x> ", []byte(n)) 86 } 87 func (n valueNode) fstring(ind string) string { 88 return fmt.Sprintf("%x ", []byte(n)) 89 } 90 91 func mustDecodeNode(hash, buf []byte, cachegen uint16) node { 92 n, err := decodeNode(hash, buf, cachegen) 93 if err != nil { 94 panic(fmt.Sprintf("node %x: %v", hash, err)) 95 } 96 return n 97 } 98 99 // decodeNode parses the RLP encoding of a trie node. 100 func decodeNode(hash, buf []byte, cachegen uint16) (node, error) { 101 if len(buf) == 0 { 102 return nil, io.ErrUnexpectedEOF 103 } 104 elems, _, err := rlp.SplitList(buf) 105 if err != nil { 106 return nil, fmt.Errorf("decode error: %v", err) 107 } 108 switch c, _ := rlp.CountValues(elems); c { 109 case 2: 110 n, err := decodeShort(hash, elems, cachegen) 111 return n, wrapError(err, "short") 112 case 17: 113 n, err := decodeFull(hash, elems, cachegen) 114 return n, wrapError(err, "full") 115 default: 116 return nil, fmt.Errorf("invalid number of list elements: %v", c) 117 } 118 } 119 120 func decodeShort(hash, elems []byte, cachegen uint16) (node, error) { 121 kbuf, rest, err := rlp.SplitString(elems) 122 if err != nil { 123 return nil, err 124 } 125 flag := nodeFlag{hash: hash, gen: cachegen} 126 key := compactToHex(kbuf) 127 if hasTerm(key) { 128 // value node 129 val, _, err := rlp.SplitString(rest) 130 if err != nil { 131 return nil, fmt.Errorf("invalid value node: %v", err) 132 } 133 return &shortNode{key, append(valueNode{}, val...), flag}, nil 134 } 135 r, _, err := decodeRef(rest, cachegen) 136 if err != nil { 137 return nil, wrapError(err, "val") 138 } 139 return &shortNode{key, r, flag}, nil 140 } 141 142 func decodeFull(hash, elems []byte, cachegen uint16) (*fullNode, error) { 143 n := &fullNode{flags: nodeFlag{hash: hash, gen: cachegen}} 144 for i := 0; i < 16; i++ { 145 cld, rest, err := decodeRef(elems, cachegen) 146 if err != nil { 147 return n, wrapError(err, fmt.Sprintf("[%d]", i)) 148 } 149 n.Children[i], elems = cld, rest 150 } 151 val, _, err := rlp.SplitString(elems) 152 if err != nil { 153 return n, err 154 } 155 if len(val) > 0 { 156 n.Children[16] = append(valueNode{}, val...) 157 } 158 return n, nil 159 } 160 161 const hashLen = len(common.Hash{}) 162 163 func decodeRef(buf []byte, cachegen uint16) (node, []byte, error) { 164 kind, val, rest, err := rlp.Split(buf) 165 if err != nil { 166 return nil, buf, err 167 } 168 switch { 169 case kind == rlp.List: 170 // 'embedded' node reference. The encoding must be smaller 171 // than a hash in order to be valid. 172 if size := len(buf) - len(rest); size > hashLen { 173 err := fmt.Errorf("oversized embedded node (size is %d bytes, want size < %d)", size, hashLen) 174 return nil, buf, err 175 } 176 n, err := decodeNode(nil, buf, cachegen) 177 return n, rest, err 178 case kind == rlp.String && len(val) == 0: 179 // empty node 180 return nil, rest, nil 181 case kind == rlp.String && len(val) == 32: 182 return append(hashNode{}, val...), rest, nil 183 default: 184 return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val)) 185 } 186 } 187 188 // wraps a decoding error with information about the path to the 189 // invalid child node (for debugging encoding issues). 190 type decodeError struct { 191 what error 192 stack []string 193 } 194 195 func wrapError(err error, ctx string) error { 196 if err == nil { 197 return nil 198 } 199 if decErr, ok := err.(*decodeError); ok { 200 decErr.stack = append(decErr.stack, ctx) 201 return decErr 202 } 203 return &decodeError{err, []string{ctx}} 204 } 205 206 func (err *decodeError) Error() string { 207 return fmt.Sprintf("%v (decode path: %s)", err.what, strings.Join(err.stack, "<-")) 208 }