github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/mpt/leaf.go (about)

     1  package mpt
     2  
     3  import (
     4  	"encoding/hex"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/nspcc-dev/neo-go/pkg/config/limits"
     9  	"github.com/nspcc-dev/neo-go/pkg/io"
    10  	"github.com/nspcc-dev/neo-go/pkg/util"
    11  )
    12  
    13  // MaxValueLength is the max length of a leaf node value.
    14  const MaxValueLength = 3 + limits.MaxStorageValueLen + 1
    15  
    16  // LeafNode represents an MPT's leaf node.
    17  type LeafNode struct {
    18  	BaseNode
    19  	value []byte
    20  }
    21  
    22  var _ Node = (*LeafNode)(nil)
    23  
    24  // NewLeafNode returns a hash node with the specified value.
    25  func NewLeafNode(value []byte) *LeafNode {
    26  	return &LeafNode{value: value}
    27  }
    28  
    29  // Type implements Node interface.
    30  func (n LeafNode) Type() NodeType { return LeafT }
    31  
    32  // Hash implements BaseNode interface.
    33  func (n *LeafNode) Hash() util.Uint256 {
    34  	return n.getHash(n)
    35  }
    36  
    37  // Bytes implements BaseNode interface.
    38  func (n *LeafNode) Bytes() []byte {
    39  	return n.getBytes(n)
    40  }
    41  
    42  // DecodeBinary implements io.Serializable.
    43  func (n *LeafNode) DecodeBinary(r *io.BinReader) {
    44  	sz := r.ReadVarUint()
    45  	if sz > MaxValueLength {
    46  		r.Err = fmt.Errorf("leaf node value is too big: %d", sz)
    47  		return
    48  	}
    49  	n.value = make([]byte, sz)
    50  	r.ReadBytes(n.value)
    51  	n.invalidateCache()
    52  }
    53  
    54  // EncodeBinary implements io.Serializable.
    55  func (n LeafNode) EncodeBinary(w *io.BinWriter) {
    56  	w.WriteVarBytes(n.value)
    57  }
    58  
    59  // Size implements Node interface.
    60  func (n *LeafNode) Size() int {
    61  	return io.GetVarSize(len(n.value)) + len(n.value)
    62  }
    63  
    64  // MarshalJSON implements the json.Marshaler.
    65  func (n *LeafNode) MarshalJSON() ([]byte, error) {
    66  	return []byte(`{"value":"` + hex.EncodeToString(n.value) + `"}`), nil
    67  }
    68  
    69  // UnmarshalJSON implements the json.Unmarshaler.
    70  func (n *LeafNode) UnmarshalJSON(data []byte) error {
    71  	var obj NodeObject
    72  	if err := obj.UnmarshalJSON(data); err != nil {
    73  		return err
    74  	} else if u, ok := obj.Node.(*LeafNode); ok {
    75  		*n = *u
    76  		return nil
    77  	}
    78  	return errors.New("expected leaf node")
    79  }
    80  
    81  // Clone implements Node interface.
    82  func (n *LeafNode) Clone() Node {
    83  	res := *n
    84  	return &res
    85  }