forked from TrueCloudLab/neoneo-go
9c478378e1
Because there is no distinct type field in JSONized nodes, distinction is made via payload itself, thus all unmarshaling is done via NodeObject.
82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
package mpt
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
)
|
|
|
|
// HashNode represents MPT's hash node.
|
|
type HashNode struct {
|
|
hash util.Uint256
|
|
valid bool
|
|
}
|
|
|
|
var _ Node = (*HashNode)(nil)
|
|
|
|
// NewHashNode returns hash node with the specified hash.
|
|
func NewHashNode(h util.Uint256) *HashNode {
|
|
return &HashNode{
|
|
hash: h,
|
|
valid: true,
|
|
}
|
|
}
|
|
|
|
// Type implements Node interface.
|
|
func (h *HashNode) Type() NodeType { return HashT }
|
|
|
|
// Hash implements Node interface.
|
|
func (h *HashNode) Hash() util.Uint256 {
|
|
if !h.valid {
|
|
panic("can't get hash of an empty HashNode")
|
|
}
|
|
return h.hash
|
|
}
|
|
|
|
// IsEmpty returns true iff h is an empty node i.e. contains no hash.
|
|
func (h *HashNode) IsEmpty() bool { return !h.valid }
|
|
|
|
// DecodeBinary implements io.Serializable.
|
|
func (h *HashNode) DecodeBinary(r *io.BinReader) {
|
|
sz := r.ReadVarUint()
|
|
switch sz {
|
|
case 0:
|
|
h.valid = false
|
|
case util.Uint256Size:
|
|
h.valid = true
|
|
r.ReadBytes(h.hash[:])
|
|
default:
|
|
r.Err = fmt.Errorf("invalid hash node size: %d", sz)
|
|
}
|
|
}
|
|
|
|
// EncodeBinary implements io.Serializable.
|
|
func (h HashNode) EncodeBinary(w *io.BinWriter) {
|
|
if !h.valid {
|
|
w.WriteVarUint(0)
|
|
return
|
|
}
|
|
w.WriteVarBytes(h.hash[:])
|
|
}
|
|
|
|
// MarshalJSON implements json.Marshaler.
|
|
func (h *HashNode) MarshalJSON() ([]byte, error) {
|
|
if !h.valid {
|
|
return []byte(`{}`), nil
|
|
}
|
|
return []byte(`{"hash":"` + h.hash.StringLE() + `"}`), nil
|
|
}
|
|
|
|
// UnmarshalJSON implements json.Unmarshaler.
|
|
func (h *HashNode) UnmarshalJSON(data []byte) error {
|
|
var obj NodeObject
|
|
if err := obj.UnmarshalJSON(data); err != nil {
|
|
return err
|
|
} else if u, ok := obj.Node.(*HashNode); ok {
|
|
*h = *u
|
|
return nil
|
|
}
|
|
return errors.New("expected hash node")
|
|
}
|