mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-23 03:38:35 +00:00
36808b8904
We need this to avoid collapse collisions. Example of such collapse described in https://github.com/nspcc-dev/neo-go/pull/2019#discussion_r689629704.
85 lines
1.9 KiB
Go
85 lines
1.9 KiB
Go
package mpt
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
)
|
|
|
|
// MaxValueLength is a max length of a leaf node value.
|
|
const MaxValueLength = 3 + storage.MaxStorageValueLen + 1
|
|
|
|
// LeafNode represents MPT's leaf node.
|
|
type LeafNode struct {
|
|
BaseNode
|
|
value []byte
|
|
}
|
|
|
|
var _ Node = (*LeafNode)(nil)
|
|
|
|
// NewLeafNode returns hash node with the specified value.
|
|
func NewLeafNode(value []byte) *LeafNode {
|
|
return &LeafNode{value: value}
|
|
}
|
|
|
|
// Type implements Node interface.
|
|
func (n LeafNode) Type() NodeType { return LeafT }
|
|
|
|
// Hash implements BaseNode interface.
|
|
func (n *LeafNode) Hash() util.Uint256 {
|
|
return n.getHash(n)
|
|
}
|
|
|
|
// Bytes implements BaseNode interface.
|
|
func (n *LeafNode) Bytes() []byte {
|
|
return n.getBytes(n)
|
|
}
|
|
|
|
// DecodeBinary implements io.Serializable.
|
|
func (n *LeafNode) DecodeBinary(r *io.BinReader) {
|
|
sz := r.ReadVarUint()
|
|
if sz > MaxValueLength {
|
|
r.Err = fmt.Errorf("leaf node value is too big: %d", sz)
|
|
return
|
|
}
|
|
n.value = make([]byte, sz)
|
|
r.ReadBytes(n.value)
|
|
n.invalidateCache()
|
|
}
|
|
|
|
// EncodeBinary implements io.Serializable.
|
|
func (n LeafNode) EncodeBinary(w *io.BinWriter) {
|
|
w.WriteVarBytes(n.value)
|
|
}
|
|
|
|
// Size implements Node interface.
|
|
func (n *LeafNode) Size() int {
|
|
return io.GetVarSize(len(n.value)) + len(n.value)
|
|
}
|
|
|
|
// MarshalJSON implements json.Marshaler.
|
|
func (n *LeafNode) MarshalJSON() ([]byte, error) {
|
|
return []byte(`{"value":"` + hex.EncodeToString(n.value) + `"}`), nil
|
|
}
|
|
|
|
// UnmarshalJSON implements json.Unmarshaler.
|
|
func (n *LeafNode) UnmarshalJSON(data []byte) error {
|
|
var obj NodeObject
|
|
if err := obj.UnmarshalJSON(data); err != nil {
|
|
return err
|
|
} else if u, ok := obj.Node.(*LeafNode); ok {
|
|
*n = *u
|
|
return nil
|
|
}
|
|
return errors.New("expected leaf node")
|
|
}
|
|
|
|
// Clone implements Node interface.
|
|
func (n *LeafNode) Clone() Node {
|
|
res := *n
|
|
return &res
|
|
}
|