Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pkg/scale): encoding and decoding of maps in scale #2894

Merged
merged 11 commits into from
Oct 21, 2022
Next Next commit
scale encoding support for map
kishansagathiya committed Sep 30, 2022
commit a7fc7b04c38ba0bc19aa1afe70ee5150760b6524
31 changes: 31 additions & 0 deletions pkg/scale/encode.go
Original file line number Diff line number Diff line change
@@ -106,6 +106,8 @@ func (es *encodeState) marshal(in interface{}) (err error) {
err = es.encodeArray(in)
case reflect.Slice:
err = es.encodeSlice(in)
case reflect.Map:
err = es.encodeMap(in)
default:
err = fmt.Errorf("unsupported type: %T", in)
}
@@ -223,6 +225,35 @@ func (es *encodeState) encodeArray(in interface{}) (err error) {
return
}

func (es *encodeState) encodeMap(in interface{}) (err error) {
v := reflect.ValueOf(in)
err = es.encodeLength(v.Len())
if err != nil {
return
}

for i := v.MapRange(); i.Next(); {
fmt.Println(i.Key(), "\t:", i.Value())

key := i.Key()
err = es.marshal(key.Interface())
if err != nil {
return
}

mapValue := i.Value()
if !mapValue.CanInterface() {
continue
}
Comment on lines +251 to +253
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we return an error in that case, to avoid silently discarding a map value when encoding?

@timwu20

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Def wait for Tims answer, but this happens at other places in this file as well (i.e. structs)

Copy link
Contributor

@timwu20 timwu20 Oct 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CanInterface is essentially determining if this is a public attribute of a struct or public method. I think it should be fine in this case. This will almost always return true in the case we're trying to decode into a map value. I wonder what cases this would return false though, maybe we can provide a test case.

@kishansagathiya please don't merge the PR with unresolved conversations. My bad for not getting to this earlier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realised about this comment few moments after merging it. Wasn't deliberate.


err = es.marshal(mapValue.Interface())
if err != nil {
return
}
}
return
}

// encodeBigInt performs the same encoding as encodeInteger, except on a big.Int.
// if 2^30 <= n < 2^536 write
// [lower 2 bits of first byte = 11] [upper 6 bits of first byte = # of bytes following less 4]