github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/network/payload/headers.go (about)

     1  package payload
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/nspcc-dev/neo-go/pkg/core/block"
     8  	"github.com/nspcc-dev/neo-go/pkg/io"
     9  )
    10  
    11  // Headers payload.
    12  type Headers struct {
    13  	Hdrs []*block.Header
    14  	// StateRootInHeader specifies whether the header contains a state root.
    15  	StateRootInHeader bool
    16  }
    17  
    18  // Users can at most request 2k headers.
    19  const (
    20  	MaxHeadersAllowed = 2000
    21  )
    22  
    23  // ErrTooManyHeaders is an error returned when too many headers have been received.
    24  var ErrTooManyHeaders = fmt.Errorf("too many headers were received (max: %d)", MaxHeadersAllowed)
    25  
    26  // ErrNoHeaders is returned for zero-elements Headers payload which is considered to be invalid.
    27  var ErrNoHeaders = errors.New("no headers (zero length array)")
    28  
    29  // DecodeBinary implements the Serializable interface.
    30  func (p *Headers) DecodeBinary(br *io.BinReader) {
    31  	lenHeaders := br.ReadVarUint()
    32  
    33  	if br.Err == nil && lenHeaders == 0 {
    34  		br.Err = ErrNoHeaders
    35  		return
    36  	}
    37  
    38  	var limitExceeded bool
    39  
    40  	// C# node does it silently
    41  	if limitExceeded = lenHeaders > MaxHeadersAllowed; limitExceeded {
    42  		lenHeaders = MaxHeadersAllowed
    43  	}
    44  
    45  	p.Hdrs = make([]*block.Header, lenHeaders)
    46  
    47  	for i := 0; i < int(lenHeaders); i++ {
    48  		header := &block.Header{}
    49  		header.StateRootEnabled = p.StateRootInHeader
    50  		header.DecodeBinary(br)
    51  		p.Hdrs[i] = header
    52  	}
    53  
    54  	if br.Err == nil && limitExceeded {
    55  		br.Err = ErrTooManyHeaders
    56  	}
    57  }
    58  
    59  // EncodeBinary implements the Serializable interface.
    60  func (p *Headers) EncodeBinary(bw *io.BinWriter) {
    61  	bw.WriteArray(p.Hdrs)
    62  }