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 }