Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/keystore/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const (
var c codec.Manager

func init() {
lc := linearcodec.NewCustomMaxLength(maxSliceLength)
lc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(maxSliceLength))
c = codec.NewManager(maxPackerSize)
if err := c.RegisterCodec(codecVersion, lc); err != nil {
panic(err)
Expand Down
74 changes: 55 additions & 19 deletions codec/linearcodec/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,35 +42,71 @@ type linearCodec struct {
typeToTypeID map[reflect.Type]uint32
}

// New returns a new, concurrency-safe codec; it allow to specify
// both tagNames and maxSlicelenght
func New(tagNames []string, maxSliceLen uint32) Codec {
// New returns a new, concurrency-safe codec.
// tagNames and maxSlicelength must be specified.
func New(opts ...Option) Codec {
o := &Options{}
o.applyOptions(opts)

hCodec := &linearCodec{
nextTypeID: 0,
nextTypeID: o.nextTypeID,
typeIDToType: map[uint32]reflect.Type{},
typeToTypeID: map[reflect.Type]uint32{},
}
hCodec.Codec = reflectcodec.New(hCodec, tagNames, maxSliceLen)
hCodec.Codec = reflectcodec.New(hCodec, o.tagNames, o.maxSliceLen)
return hCodec
}

// NewDefault is a convenience constructor; it returns a new codec with reasonable default values
func NewDefault() Codec {
return New([]string{reflectcodec.DefaultTagName}, defaultMaxSliceLength)
}

// NewCustomMaxLength is a convenience constructor; it returns a new codec with custom max length and default tags
func NewCustomMaxLength(maxSliceLen uint32) Codec {
return New([]string{reflectcodec.DefaultTagName}, maxSliceLen)
// NewDefault is a convenience constructor; it returns a new codec with reasonable default values.
func NewDefault(opts ...Option) Codec {
return New(append([]Option{WithTagName(reflectcodec.DefaultTagName), WithMaxSliceLen(defaultMaxSliceLength)}, opts...)...)
}

// Skip some number of type IDs
// DEPRECATED Skip some number of type IDs
func (c *linearCodec) SkipRegistrations(num int) {
c.lock.Lock()
c.nextTypeID += uint32(num)
c.lock.Unlock()
}

type Option func(*Options)

type Options struct {
tagNames []string
maxSliceLen uint32
nextTypeID uint32
}

func (o *Options) applyOptions(ops []Option) {
for _, op := range ops {
op(o)
}
}

func WithTagName(tagName string) Option {
return func(o *Options) {
o.tagNames = append(o.tagNames, tagName)
}
}

func WithTagNames(tagNames []string) Option {
return func(o *Options) {
o.tagNames = tagNames
}
}

func WithMaxSliceLen(maxSliceLen uint32) Option {
return func(o *Options) {
o.maxSliceLen = maxSliceLen
}
}

func WithNextTypeID(nextTypeID uint32) Option {
return func(o *Options) {
o.nextTypeID = nextTypeID
}
}

// RegisterType is used to register types that may be unmarshaled into an interface
// [val] is a value of the type being registered
func (c *linearCodec) RegisterType(val interface{}) error {
Expand All @@ -95,9 +131,8 @@ func (*linearCodec) PrefixSize(reflect.Type) int {

func (c *linearCodec) PackPrefix(p *wrappers.Packer, valueType reflect.Type) error {
c.lock.RLock()
defer c.lock.RUnlock()

typeID, ok := c.typeToTypeID[valueType] // Get the type ID of the value being marshaled
c.lock.RUnlock()
if !ok {
return fmt.Errorf("can't marshal unregistered type %q", valueType)
}
Expand All @@ -106,18 +141,19 @@ func (c *linearCodec) PackPrefix(p *wrappers.Packer, valueType reflect.Type) err
}

func (c *linearCodec) UnpackPrefix(p *wrappers.Packer, valueType reflect.Type) (reflect.Value, error) {
c.lock.RLock()
defer c.lock.RUnlock()

typeID := p.UnpackInt() // Get the type ID
if p.Err != nil {
return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: %w", p.Err)
}

// Get a type that implements the interface
c.lock.RLock()
implementingType, ok := c.typeIDToType[typeID]
c.lock.RUnlock()
if !ok {
return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: unknown type ID %d", typeID)
}

// Ensure type actually does implement the interface
if !implementingType.Implements(valueType) {
return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: %s %w %s",
Expand Down
2 changes: 1 addition & 1 deletion codec/linearcodec/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestVectors(t *testing.T) {

func TestMultipleTags(t *testing.T) {
for _, test := range codec.MultipleTagsTests {
c := New([]string{"tag1", "tag2"}, defaultMaxSliceLength)
c := New(WithTagName("tag1"), WithTagName("tag2"), WithMaxSliceLen(defaultMaxSliceLength))
test(c, t)
}
}
2 changes: 1 addition & 1 deletion database/linkeddb/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var (
)

func init() {
lc := linearcodec.NewCustomMaxLength(math.MaxUint32)
lc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxUint32))
c = codec.NewManager(math.MaxInt32)

if err := c.RegisterCodec(codecVersion, lc); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func NewIndexer(config Config) (Indexer, error) {

if err := indexer.codec.RegisterCodec(
codecVersion,
linearcodec.NewCustomMaxLength(math.MaxUint32),
linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxUint32)),
); err != nil {
return nil, fmt.Errorf("couldn't register codec: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions snow/engine/avalanche/vertex/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const (
var c codec.Manager

func init() {
lc := linearcodec.New([]string{reflectcodec.DefaultTagName + "V0"}, maxSize)
lc2 := linearcodec.New([]string{reflectcodec.DefaultTagName + "V1"}, maxSize)
lc := linearcodec.New(linearcodec.WithTagName(reflectcodec.DefaultTagName+"V0"), linearcodec.WithMaxSliceLen(maxSize))
lc2 := linearcodec.New(linearcodec.WithTagName(reflectcodec.DefaultTagName+"V1"), linearcodec.WithMaxSliceLen(maxSize))

c = codec.NewManager(maxSize)
// for backward compatibility, still register the initial codec version
Expand Down
2 changes: 1 addition & 1 deletion vms/avm/txs/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func NewCustomParser(
log logging.Logger,
fxs []fxs.Fx,
) (Parser, error) {
gc := linearcodec.New([]string{reflectcodec.DefaultTagName}, 1<<20)
gc := linearcodec.New(linearcodec.WithTagName(reflectcodec.DefaultTagName), linearcodec.WithMaxSliceLen(1<<20))
c := linearcodec.NewDefault()

gcm := codec.NewManager(math.MaxInt32)
Expand Down
2 changes: 1 addition & 1 deletion vms/components/keystore/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var (
func init() {
c := linearcodec.NewDefault()
Codec = codec.NewDefaultManager()
lc := linearcodec.NewCustomMaxLength(math.MaxUint32)
lc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxUint32))
LegacyCodec = codec.NewManager(math.MaxInt32)

errs := wrappers.Errs{}
Expand Down
2 changes: 1 addition & 1 deletion vms/components/message/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var c codec.Manager

func init() {
c = codec.NewManager(maxMessageSize)
lc := linearcodec.NewCustomMaxLength(maxSliceLen)
lc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(maxSliceLen))

errs := wrappers.Errs{}
errs.Add(
Expand Down
2 changes: 1 addition & 1 deletion vms/platformvm/blocks/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var (
func init() {
c := linearcodec.NewDefault()
Codec = codec.NewDefaultManager()
gc := linearcodec.NewCustomMaxLength(math.MaxInt32)
gc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxInt32))
GenesisCodec = codec.NewManager(math.MaxInt32)

errs := wrappers.Errs{}
Expand Down
12 changes: 5 additions & 7 deletions vms/platformvm/txs/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,16 @@ var (
)

func init() {
c := linearcodec.NewDefault()
// Order in which type are registered affect the byte representation
// generated by marshalling ops. To maintain codec type ordering,
// we skip positions for the blocks.
c := linearcodec.NewDefault(linearcodec.WithNextTypeID(5))
Codec = codec.NewDefaultManager()
gc := linearcodec.NewCustomMaxLength(math.MaxInt32)
gc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxInt32), linearcodec.WithNextTypeID(5))
GenesisCodec = codec.NewManager(math.MaxInt32)

errs := wrappers.Errs{}
for _, c := range []linearcodec.Codec{c, gc} {
// Order in which type are registered affect the byte representation
// generated by marshalling ops. To maintain codec type ordering,
// we skip positions for the blocks.
c.SkipRegistrations(5)

errs.Add(RegisterUnsignedTxsTypes(c))
}
errs.Add(
Expand Down
2 changes: 1 addition & 1 deletion vms/platformvm/warp/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var c codec.Manager

func init() {
c = codec.NewManager(math.MaxInt)
lc := linearcodec.NewCustomMaxLength(math.MaxInt32)
lc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxInt32))

errs := wrappers.Errs{}
errs.Add(
Expand Down
2 changes: 1 addition & 1 deletion vms/proposervm/block/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const codecVersion = 0
var c codec.Manager

func init() {
linearCodec := linearcodec.NewCustomMaxLength(math.MaxUint32)
linearCodec := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxUint32))
c = codec.NewManager(math.MaxInt)

errs := wrappers.Errs{}
Expand Down
2 changes: 1 addition & 1 deletion vms/proposervm/state/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const version = 0
var c codec.Manager

func init() {
lc := linearcodec.NewCustomMaxLength(math.MaxUint32)
lc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxUint32))
c = codec.NewManager(math.MaxInt32)

err := c.RegisterCodec(version, lc)
Expand Down
2 changes: 1 addition & 1 deletion vms/proposervm/summary/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var (
)

func init() {
lc := linearcodec.NewCustomMaxLength(math.MaxUint32)
lc := linearcodec.NewDefault(linearcodec.WithMaxSliceLen(math.MaxUint32))
c = codec.NewManager(math.MaxInt32)
if err := c.RegisterCodec(codecVersion, lc); err != nil {
panic(err)
Expand Down