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 }