-
Notifications
You must be signed in to change notification settings - Fork 207
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
Fix epoch block marshaling #1688
Conversation
e4c1f9b
to
b1bdb23
Compare
Codecov Report
@@ Coverage Diff @@
## master #1688 +/- ##
==========================================
+ Coverage 56.03% 56.04% +0.01%
==========================================
Files 606 606
Lines 80271 80291 +20
==========================================
+ Hits 44980 45002 +22
- Misses 31756 31758 +2
+ Partials 3535 3531 -4
Continue to review full report at Codecov.
|
Its now just called Tracker
Epoch blocks previously were not json unmarshalable by the geth client, they now are.
b1bdb23
to
5393345
Compare
Coverage from tests in
|
core/types/block.go
Outdated
if err := json.Unmarshal(input, &dec); err != nil { | ||
return err | ||
} | ||
if dec.Bitmap != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should r.UnmarshalJSON()
do if the received bitmap
and signature
are nil, but r
holds some values for it? Should it:
- keep the values or
- overwrite the
r
values with the nil interpretation of it
I have a hunch that it should do 2, but I'm honestly asking.
Even so, this implementation seems that it does a mix. If bitmap is nil, it won't overwrite the value, but if signature is not, it would, while not returning any error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unmarshaler is the interface implemented by types that can unmarshal a JSON description of themselves. The input can be assumed to be a valid encoding of a JSON value. UnmarshalJSON must copy the JSON data if it wishes to retain the data after returning.
By convention, to approximate the behavior of Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
It is not clear what it should do, but I would veer towards something that in most cases would make (marshal(unmarshal(json)) be as idempotent as possible.
Or maybe I'm just overthinking this and it's not that important
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, its not that clear.
I think there's only one valid case for calling UnmarshalJson on non empty object, that would be to re-use a struct for unmarshaling to avoid re-allocating memory.
I think we should disallow code from setting some fields of a struct and expecting the rest to be set by unmarshaling, it seems like a fragile and confusing approach.
So to support that behavior, the unmarshal function would need to set all fields when executed. Interestingly though it looks like that implementation would violate the convention you quoted above, but I wrote a test on go playground to check this and it seems that Unmarshal will overwrite a struct with nil when decoding []byte("null") so it looks like its not a no-op.
https://play.golang.org/p/dHiWmj8X7KD
So based on that I think we can drop the nil checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so I actually raised an issue on the golang repo because this was not clear to me golang/go#48646, but for now I still think dropping the nil checks is the best course of action.
Coverage from tests in
|
Description
This is a continuation of the PR from @jpjamipark:
EpochSnarkData
unmarshaling was broken.RPCMarshalBlock
was marshaling both the fields ofEpochSnarkData
ashexutil.Bytes
.celo-blockchain/internal/ethapi/api.go
Lines 1071 to 1076 in 43ae190
@jpjamipark Had mentioned that:
I believe that it's actually not possible to use gencodec for this task because the manual conversion performed in
ethapi/api.go
when encoding thebig.Int
Bitmap field, means that we cannot use the field type override in gencodec, because you cannot mark a field of typebig.Int
to be serialized ashexutil.Bytes
.gencodec doc
Unless we change the marshaling in
internal/ethapi/api.go
I don't think we can use gencodec for this task and since, changing the marshaling ininternal/ethapi/api.go
to usehexutil.Big
actually changes the output bytes (see below) its probably not a good idea.So in this case we take the approach of adding a manually specified marshal and unmarhsal json methods on
EpochSnarkData
.Other changes
Added the ability to wait for blocks in
test.Tracker
, to support the test that waits for an epoch block.Tested
Added a new test to check that the marshaling/unmarshaling works on epoch blocks.
Related issues
Backwards compatibility
No.
This breaks backwards compatibility, because programs using the geth client to decode epoch blocks will now decode the block instead of returning an error.