-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4de4d4d
commit c842911
Showing
212 changed files
with
20,914 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.SILENT: | ||
.EXPORT_ALL_VARIABLES: | ||
|
||
.PHONY: b | ||
b: | ||
rm -rf /tmp/e2e-test-landslide/nodes/ | ||
./scripts/build.sh /tmp/e2e-test-landslide/avalanchego/plugins/pjSL9ksard4YE96omaiTkGL5H6XX2W5VEo3ZgWC9S2P6gzs9A | ||
|
||
|
||
ba: | ||
BASEDIR=/tmp/e2e-test-landslide AVALANCHEGO_BUILD_PATH=/tmp/e2e-test-landslide/avalanchego ./scripts/install_avalanchego_release.sh | ||
.PHONY: ba | ||
|
||
.PHONY: w | ||
w: | ||
rm -rf /tmp/e2e-test-landslide/nodes/ | ||
./scripts/build_wasm.sh /tmp/e2e-test-landslide/avalanchego/plugins/pjSL9ksard4YE96omaiTkGL5H6XX2W5VEo3ZgWC9S2P6gzs9A |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package codec | ||
|
||
import ( | ||
"errors" | ||
|
||
"github.com/consideritdone/landslidevm/utils/wrappers" | ||
) | ||
|
||
var ( | ||
ErrUnsupportedType = errors.New("unsupported type") | ||
ErrMaxSliceLenExceeded = errors.New("max slice length exceeded") | ||
ErrDoesNotImplementInterface = errors.New("does not implement interface") | ||
ErrUnexportedField = errors.New("unexported field") | ||
ErrExtraSpace = errors.New("trailing buffer space") | ||
ErrMarshalZeroLength = errors.New("can't marshal zero length value") | ||
ErrUnmarshalZeroLength = errors.New("can't unmarshal zero length value") | ||
) | ||
|
||
// Codec marshals and unmarshals | ||
type Codec interface { | ||
MarshalInto(interface{}, *wrappers.Packer) error | ||
Unmarshal([]byte, interface{}) error | ||
|
||
// Returns the size, in bytes, of [value] when it's marshaled | ||
Size(value interface{}) (int, error) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package codec | ||
|
||
// GeneralCodec marshals and unmarshals structs including interfaces | ||
type GeneralCodec interface { | ||
Codec | ||
Registry | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package hierarchycodec | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"sync" | ||
|
||
"github.com/consideritdone/landslidevm/utils/bimap" | ||
|
||
"github.com/consideritdone/landslidevm/utils/wrappers" | ||
|
||
"github.com/consideritdone/landslidevm/codec" | ||
"github.com/consideritdone/landslidevm/codec/reflectcodec" | ||
) | ||
|
||
var ( | ||
_ Codec = (*hierarchyCodec)(nil) | ||
_ codec.Codec = (*hierarchyCodec)(nil) | ||
_ codec.Registry = (*hierarchyCodec)(nil) | ||
_ codec.GeneralCodec = (*hierarchyCodec)(nil) | ||
) | ||
|
||
// Codec marshals and unmarshals | ||
type Codec interface { | ||
codec.Registry | ||
codec.Codec | ||
SkipRegistrations(int) | ||
NextGroup() | ||
} | ||
|
||
type typeID struct { | ||
groupID uint16 | ||
typeID uint16 | ||
} | ||
|
||
// Codec handles marshaling and unmarshaling of structs | ||
type hierarchyCodec struct { | ||
codec.Codec | ||
|
||
lock sync.RWMutex | ||
currentGroupID uint16 | ||
nextTypeID uint16 | ||
registeredTypes *bimap.BiMap[typeID, reflect.Type] | ||
} | ||
|
||
// New returns a new, concurrency-safe codec | ||
func New(tagNames []string) Codec { | ||
hCodec := &hierarchyCodec{ | ||
currentGroupID: 0, | ||
nextTypeID: 0, | ||
registeredTypes: bimap.New[typeID, reflect.Type](), | ||
} | ||
hCodec.Codec = reflectcodec.New(hCodec, tagNames) | ||
return hCodec | ||
} | ||
|
||
// NewDefault returns a new codec with reasonable default values | ||
func NewDefault() Codec { | ||
return New([]string{reflectcodec.DefaultTagName}) | ||
} | ||
|
||
// SkipRegistrations some number of type IDs | ||
func (c *hierarchyCodec) SkipRegistrations(num int) { | ||
c.lock.Lock() | ||
c.nextTypeID += uint16(num) | ||
c.lock.Unlock() | ||
} | ||
|
||
// NextGroup moves to the next group registry | ||
func (c *hierarchyCodec) NextGroup() { | ||
c.lock.Lock() | ||
c.currentGroupID++ | ||
c.nextTypeID = 0 | ||
c.lock.Unlock() | ||
} | ||
|
||
// RegisterType is used to register types that may be unmarshaled into an interface | ||
// [val] is a value of the type being registered | ||
func (c *hierarchyCodec) RegisterType(val interface{}) error { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
valType := reflect.TypeOf(val) | ||
if c.registeredTypes.HasValue(valType) { | ||
return fmt.Errorf("%w: %v", codec.ErrDuplicateType, valType) | ||
} | ||
|
||
valTypeID := typeID{ | ||
groupID: c.currentGroupID, | ||
typeID: c.nextTypeID, | ||
} | ||
c.nextTypeID++ | ||
|
||
c.registeredTypes.Put(valTypeID, valType) | ||
return nil | ||
} | ||
|
||
func (*hierarchyCodec) PrefixSize(reflect.Type) int { | ||
// see PackPrefix implementation | ||
return wrappers.ShortLen + wrappers.ShortLen | ||
} | ||
|
||
func (c *hierarchyCodec) PackPrefix(p *wrappers.Packer, valueType reflect.Type) error { | ||
c.lock.RLock() | ||
defer c.lock.RUnlock() | ||
|
||
typeID, ok := c.registeredTypes.GetKey(valueType) // Get the type ID of the value being marshaled | ||
if !ok { | ||
return fmt.Errorf("can't marshal unregistered type %q", valueType) | ||
} | ||
// Pack type ID so we know what to unmarshal this into | ||
p.PackShort(typeID.groupID) | ||
p.PackShort(typeID.typeID) | ||
return p.Err | ||
} | ||
|
||
func (c *hierarchyCodec) UnpackPrefix(p *wrappers.Packer, valueType reflect.Type) (reflect.Value, error) { | ||
c.lock.RLock() | ||
defer c.lock.RUnlock() | ||
|
||
groupID := p.UnpackShort() // Get the group ID | ||
typeIDShort := p.UnpackShort() // Get the type ID | ||
if p.Err != nil { | ||
return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: %w", p.Err) | ||
} | ||
t := typeID{ | ||
groupID: groupID, | ||
typeID: typeIDShort, | ||
} | ||
// Get a type that implements the interface | ||
implementingType, ok := c.registeredTypes.GetValue(t) | ||
if !ok { | ||
return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: unknown type ID %+v", t) | ||
} | ||
// Ensure type actually does implement the interface | ||
if !implementingType.Implements(valueType) { | ||
return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: %s %w %s", | ||
implementingType, | ||
codec.ErrDoesNotImplementInterface, | ||
valueType, | ||
) | ||
} | ||
return reflect.New(implementingType).Elem(), nil // instance of the proper type | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package hierarchycodec | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/consideritdone/landslidevm/codec" | ||
) | ||
|
||
func TestVectors(t *testing.T) { | ||
for _, test := range codec.Tests { | ||
c := NewDefault() | ||
test(c, t) | ||
} | ||
} | ||
|
||
func TestMultipleTags(t *testing.T) { | ||
for _, test := range codec.MultipleTagsTests { | ||
c := New([]string{"tag1", "tag2"}) | ||
test(c, t) | ||
} | ||
} | ||
|
||
func FuzzStructUnmarshalHierarchyCodec(f *testing.F) { | ||
c := NewDefault() | ||
codec.FuzzStructUnmarshal(c, f) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package linearcodec | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"sync" | ||
|
||
"github.com/consideritdone/landslidevm/utils/bimap" | ||
|
||
"github.com/consideritdone/landslidevm/utils/wrappers" | ||
|
||
"github.com/consideritdone/landslidevm/codec" | ||
"github.com/consideritdone/landslidevm/codec/reflectcodec" | ||
) | ||
|
||
var ( | ||
_ Codec = (*linearCodec)(nil) | ||
_ codec.Codec = (*linearCodec)(nil) | ||
_ codec.Registry = (*linearCodec)(nil) | ||
_ codec.GeneralCodec = (*linearCodec)(nil) | ||
) | ||
|
||
// Codec marshals and unmarshals | ||
type Codec interface { | ||
codec.Registry | ||
codec.Codec | ||
SkipRegistrations(int) | ||
} | ||
|
||
// Codec handles marshaling and unmarshaling of structs | ||
type linearCodec struct { | ||
codec.Codec | ||
|
||
lock sync.RWMutex | ||
nextTypeID uint32 | ||
registeredTypes *bimap.BiMap[uint32, reflect.Type] | ||
} | ||
|
||
// New returns a new, concurrency-safe codec; it allow to specify tagNames. | ||
func New(tagNames []string) Codec { | ||
hCodec := &linearCodec{ | ||
nextTypeID: 0, | ||
registeredTypes: bimap.New[uint32, reflect.Type](), | ||
} | ||
hCodec.Codec = reflectcodec.New(hCodec, tagNames) | ||
return hCodec | ||
} | ||
|
||
// NewDefault is a convenience constructor; it returns a new codec with default | ||
// tagNames. | ||
func NewDefault() Codec { | ||
return New([]string{reflectcodec.DefaultTagName}) | ||
} | ||
|
||
// Skip some number of type IDs | ||
func (c *linearCodec) SkipRegistrations(num int) { | ||
c.lock.Lock() | ||
c.nextTypeID += uint32(num) | ||
c.lock.Unlock() | ||
} | ||
|
||
// 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 { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
valType := reflect.TypeOf(val) | ||
if c.registeredTypes.HasValue(valType) { | ||
return fmt.Errorf("%w: %v", codec.ErrDuplicateType, valType) | ||
} | ||
|
||
c.registeredTypes.Put(c.nextTypeID, valType) | ||
c.nextTypeID++ | ||
return nil | ||
} | ||
|
||
func (*linearCodec) PrefixSize(reflect.Type) int { | ||
// see PackPrefix implementation | ||
return wrappers.IntLen | ||
} | ||
|
||
func (c *linearCodec) PackPrefix(p *wrappers.Packer, valueType reflect.Type) error { | ||
c.lock.RLock() | ||
defer c.lock.RUnlock() | ||
|
||
typeID, ok := c.registeredTypes.GetKey(valueType) // Get the type ID of the value being marshaled | ||
if !ok { | ||
return fmt.Errorf("can't marshal unregistered type %q", valueType) | ||
} | ||
p.PackInt(typeID) // Pack type ID so we know what to unmarshal this into | ||
return p.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 | ||
implementingType, ok := c.registeredTypes.GetValue(typeID) | ||
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", | ||
implementingType, | ||
codec.ErrDoesNotImplementInterface, | ||
valueType, | ||
) | ||
} | ||
return reflect.New(implementingType).Elem(), nil // instance of the proper type | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package linearcodec | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/consideritdone/landslidevm/codec" | ||
) | ||
|
||
func TestVectors(t *testing.T) { | ||
for _, test := range codec.Tests { | ||
c := NewDefault() | ||
test(c, t) | ||
} | ||
} | ||
|
||
func TestMultipleTags(t *testing.T) { | ||
for _, test := range codec.MultipleTagsTests { | ||
c := New([]string{"tag1", "tag2"}) | ||
test(c, t) | ||
} | ||
} | ||
|
||
func FuzzStructUnmarshalLinearCodec(f *testing.F) { | ||
c := NewDefault() | ||
codec.FuzzStructUnmarshal(c, f) | ||
} |
Oops, something went wrong.