package query import ( "errors" "fmt" "github.com/OffchainLabs/go-bitfield" ) // bitlistInfo holds information about a SSZ Bitlist type. // // Same as listInfo, but limit/length are in bits, not elements. type bitlistInfo struct { // limit is the maximum number of bits in the bitlist. limit uint64 // length is the actual number of bits at runtime (0 if not set). length uint64 } func (l *bitlistInfo) Limit() uint64 { if l == nil { return 0 } return l.limit } func (l *bitlistInfo) Length() uint64 { if l == nil { return 0 } return l.length } func (l *bitlistInfo) SetLength(length uint64) error { if l == nil { return errors.New("bitlistInfo is nil") } if length > l.limit { return fmt.Errorf("length %d exceeds limit %d", length, l.limit) } l.length = length return nil } // SetLengthFromBytes determines the actual bitlist length from SSZ-encoded bytes. func (l *bitlistInfo) SetLengthFromBytes(rawBytes []byte) error { // Wrap rawBytes in a Bitlist to use existing methods. bl := bitfield.Bitlist(rawBytes) return l.SetLength(bl.Len()) } // Size returns the size in bytes for this bitlist. // Note that while serializing, 1 bit is added for the delimiter bit, // which results in ceil((length + 1) / 8) bytes. // Note that `(length / 8) + 1` is equivalent to `ceil((length + 1) / 8)`. // Example: length=0 -> size=1, length=7 -> size=1, length=8 -> size=2 // Reference: https://github.com/ethereum/consensus-specs/blob/master/ssz/simple-serialize.md#bitlistn-progressivebitlist func (l *bitlistInfo) Size() uint64 { if l == nil { return 0 } return (l.length / 8) + 1 }