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