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

     1  package mpt
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  
     7  	"github.com/nspcc-dev/neo-go/pkg/io"
     8  	"github.com/nspcc-dev/neo-go/pkg/util"
     9  )
    10  
    11  const (
    12  	// childrenCount represents the number of children of a branch node.
    13  	childrenCount = 17
    14  	// lastChild is the index of the last child.
    15  	lastChild = childrenCount - 1
    16  )
    17  
    18  // BranchNode represents an MPT's branch node.
    19  type BranchNode struct {
    20  	BaseNode
    21  	Children [childrenCount]Node
    22  }
    23  
    24  var _ Node = (*BranchNode)(nil)
    25  
    26  // NewBranchNode returns a new branch node.
    27  func NewBranchNode() *BranchNode {
    28  	b := new(BranchNode)
    29  	for i := 0; i < childrenCount; i++ {
    30  		b.Children[i] = EmptyNode{}
    31  	}
    32  	return b
    33  }
    34  
    35  // Type implements the Node interface.
    36  func (b *BranchNode) Type() NodeType { return BranchT }
    37  
    38  // Hash implements the BaseNode interface.
    39  func (b *BranchNode) Hash() util.Uint256 {
    40  	return b.getHash(b)
    41  }
    42  
    43  // Bytes implements the BaseNode interface.
    44  func (b *BranchNode) Bytes() []byte {
    45  	return b.getBytes(b)
    46  }
    47  
    48  // Size implements the Node interface.
    49  func (b *BranchNode) Size() int {
    50  	sz := childrenCount
    51  	for i := range b.Children {
    52  		if !isEmpty(b.Children[i]) {
    53  			sz += util.Uint256Size
    54  		}
    55  	}
    56  	return sz
    57  }
    58  
    59  // EncodeBinary implements io.Serializable.
    60  func (b *BranchNode) EncodeBinary(w *io.BinWriter) {
    61  	for i := 0; i < childrenCount; i++ {
    62  		encodeBinaryAsChild(b.Children[i], w)
    63  	}
    64  }
    65  
    66  // DecodeBinary implements io.Serializable.
    67  func (b *BranchNode) DecodeBinary(r *io.BinReader) {
    68  	for i := 0; i < childrenCount; i++ {
    69  		no := new(NodeObject)
    70  		no.DecodeBinary(r)
    71  		b.Children[i] = no.Node
    72  	}
    73  }
    74  
    75  // MarshalJSON implements the json.Marshaler.
    76  func (b *BranchNode) MarshalJSON() ([]byte, error) {
    77  	return json.Marshal(b.Children)
    78  }
    79  
    80  // UnmarshalJSON implements the json.Unmarshaler.
    81  func (b *BranchNode) UnmarshalJSON(data []byte) error {
    82  	var obj NodeObject
    83  	if err := obj.UnmarshalJSON(data); err != nil {
    84  		return err
    85  	} else if u, ok := obj.Node.(*BranchNode); ok {
    86  		*b = *u
    87  		return nil
    88  	}
    89  	return errors.New("expected branch node")
    90  }
    91  
    92  // Clone implements Node interface.
    93  func (b *BranchNode) Clone() Node {
    94  	res := *b
    95  	return &res
    96  }
    97  
    98  // splitPath splits path for a branch node.
    99  func splitPath(path []byte) (byte, []byte) {
   100  	if len(path) != 0 {
   101  		return path[0], path[1:]
   102  	}
   103  	return lastChild, path
   104  }