Files
bft/msm/block.canoto.go
a4591402c0 Replication response size cap (#440)
* fix: send replication requests up to maxRoundLimit instead of dropping

* add tests for seqs and rounds

* added unsorted seqs and rounds test

* go format

* added test for unsorted seqs and rounds above limit

* go format

* added size limit for replication messages

* go format

* add Size function for all sub-messages instead of using Bytes()

* go format

* fix removed unused import

* fixed and cleaned tests

* changed the order of the test, setup then create the epoch

* moved Size() from ParsedBlock to StateMachineBlock

* removed dependency on canoto, size is computed at first serialization, cashing the full block size

* moved size() to parsedBlock and added a lock

* fixed comments, fixed race

* sizeLock -> lock

* fixed sizeLock mentions

* fix latestFinalizedSeq and latestRound over the size limit, added unit test

* Update common/msg.go

Co-authored-by: Sam Liokumovich <[email protected]>
Signed-off-by: jadalsmail <[email protected]>

* nit: fix Size() comment grammar

* logs err and return if size > remainingBytes

* fix err log ci

* fix: remove err when latest round is above size limit

---------

Signed-off-by: jadalsmail <[email protected]>
Co-authored-by: yacovm <[email protected]>
Co-authored-by: Sam Liokumovich <[email protected]>
2026-08-03 16:32:57 +02:00

218 lines
5.8 KiB
Go

// Code generated by canoto. DO NOT EDIT.
// versions:
// canoto v0.19.0
// source: block.go
package metadata
import (
"io"
"reflect"
"sync/atomic"
"github.com/StephenButtolph/canoto"
)
// Ensure that the generated code is compatible with the library version.
const (
_ uint = canoto.VersionCompatibility - 1
_ uint = 1 - canoto.VersionCompatibility
)
// Ensure that unused imports do not error
var _ = io.ErrUnexpectedEOF
const (
canotoNumber_RawBlock__Metadata = 1
canotoNumber_RawBlock__InnerBlockBytes = 2
canotoTag_RawBlock__Metadata = "\x0a" // canoto.Tag(canotoNumber_RawBlock__Metadata, canoto.Len)
canotoTag_RawBlock__InnerBlockBytes = "\x12" // canoto.Tag(canotoNumber_RawBlock__InnerBlockBytes, canoto.Len)
)
type canotoData_RawBlock struct {
size uint64
}
// CanotoSpec returns the specification of this canoto message.
func (*RawBlock) CanotoSpec(types ...reflect.Type) *canoto.Spec {
types = append(types, reflect.TypeFor[RawBlock]())
var zero RawBlock
s := &canoto.Spec{
Name: "RawBlock",
Fields: []canoto.FieldType{
canoto.FieldTypeFromField(
/*type inference:*/ (&zero.Metadata),
/*FieldNumber: */ canotoNumber_RawBlock__Metadata,
/*Name: */ "Metadata",
/*FixedLength: */ 0,
/*Repeated: */ false,
/*OneOf: */ "",
/*Pointer: */ false,
/*types: */ types,
),
{
FieldNumber: canotoNumber_RawBlock__InnerBlockBytes,
Name: "InnerBlockBytes",
OneOf: "",
TypeBytes: true,
},
},
}
s.CalculateCanotoCache()
return s
}
// UnmarshalCanoto unmarshals a Canoto-encoded byte slice into the struct.
//
// During parsing, the canoto cache is saved.
func (c *RawBlock) UnmarshalCanoto(bytes []byte) error {
r := canoto.Reader{
B: bytes,
}
return c.UnmarshalCanotoFrom(r)
}
// UnmarshalCanotoFrom populates the struct from a [canoto.Reader]. Most users
// should just use UnmarshalCanoto.
//
// During parsing, the canoto cache is saved.
//
// This function enables configuration of reader options.
func (c *RawBlock) UnmarshalCanotoFrom(r canoto.Reader) error {
// Zero the struct before unmarshaling.
*c = RawBlock{}
atomic.StoreUint64(&c.canotoData.size, uint64(len(r.B)))
var minField uint32
for canoto.HasNext(&r) {
field, wireType, err := canoto.ReadTag(&r)
if err != nil {
return err
}
if field < minField {
return canoto.ErrInvalidFieldOrder
}
switch field {
case canotoNumber_RawBlock__Metadata:
if wireType != canoto.Len {
return canoto.ErrUnexpectedWireType
}
// Read the bytes for the field.
originalUnsafe := r.Unsafe
r.Unsafe = true
var msgBytes []byte
if err := canoto.ReadBytes(&r, &msgBytes); err != nil {
return err
}
if len(msgBytes) == 0 {
return canoto.ErrZeroValue
}
r.Unsafe = originalUnsafe
// Unmarshal the field from the bytes.
remainingBytes := r.B
r.B = msgBytes
if err := (&c.Metadata).UnmarshalCanotoFrom(r); err != nil {
return err
}
r.B = remainingBytes
case canotoNumber_RawBlock__InnerBlockBytes:
if wireType != canoto.Len {
return canoto.ErrUnexpectedWireType
}
if err := canoto.ReadBytes(&r, &c.InnerBlockBytes); err != nil {
return err
}
if len(c.InnerBlockBytes) == 0 {
return canoto.ErrZeroValue
}
default:
return canoto.ErrUnknownField
}
minField = field + 1
}
return nil
}
// ValidCanoto validates that the struct can be correctly marshaled into the
// Canoto format.
//
// Specifically, ValidCanoto ensures:
// 1. All OneOfs are specified at most once.
// 2. All strings are valid utf-8.
// 3. All custom fields are ValidCanoto.
func (c *RawBlock) ValidCanoto() bool {
if !(&c.Metadata).ValidCanoto() {
return false
}
return true
}
// CalculateCanotoCache populates size and OneOf caches based on the current
// values in the struct.
//
// It is not safe to copy this struct concurrently.
func (c *RawBlock) CalculateCanotoCache() {
var size uint64
(&c.Metadata).CalculateCanotoCache()
if fieldSize := (&c.Metadata).CachedCanotoSize(); fieldSize != 0 {
size += uint64(len(canotoTag_RawBlock__Metadata)) + canoto.SizeUint(fieldSize) + fieldSize
}
if len(c.InnerBlockBytes) != 0 {
size += uint64(len(canotoTag_RawBlock__InnerBlockBytes)) + canoto.SizeBytes(c.InnerBlockBytes)
}
atomic.StoreUint64(&c.canotoData.size, size)
}
// CachedCanotoSize returns the previously calculated size of the Canoto
// representation from CalculateCanotoCache.
//
// If CalculateCanotoCache has not yet been called, it will return 0.
//
// If the struct has been modified since the last call to CalculateCanotoCache,
// the returned size may be incorrect.
func (c *RawBlock) CachedCanotoSize() uint64 {
return atomic.LoadUint64(&c.canotoData.size)
}
// MarshalCanoto returns the Canoto representation of this struct.
//
// It is assumed that this struct is ValidCanoto.
//
// It is not safe to copy this struct concurrently.
func (c *RawBlock) MarshalCanoto() []byte {
c.CalculateCanotoCache()
w := canoto.Writer{
B: make([]byte, 0, c.CachedCanotoSize()),
}
w = c.MarshalCanotoInto(w)
return w.B
}
// MarshalCanotoInto writes the struct into a [canoto.Writer] and returns the
// resulting [canoto.Writer]. Most users should just use MarshalCanoto.
//
// It is assumed that CalculateCanotoCache has been called since the last
// modification to this struct.
//
// It is assumed that this struct is ValidCanoto.
//
// It is not safe to copy this struct concurrently.
func (c *RawBlock) MarshalCanotoInto(w canoto.Writer) canoto.Writer {
if fieldSize := (&c.Metadata).CachedCanotoSize(); fieldSize != 0 {
canoto.Append(&w, canotoTag_RawBlock__Metadata)
canoto.AppendUint(&w, fieldSize)
w = (&c.Metadata).MarshalCanotoInto(w)
}
if len(c.InnerBlockBytes) != 0 {
canoto.Append(&w, canotoTag_RawBlock__InnerBlockBytes)
canoto.AppendBytes(&w, c.InnerBlockBytes)
}
return w
}