-
Notifications
You must be signed in to change notification settings - Fork 78
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
Write empty (non-nil) struct pointers, unless (is list element and empty_elements isn't set) #206
Conversation
Are the issues in tendermint noticeable in failing tests? Just asking because I'm using the latest pre-release of amino in this tendermint PR: |
- compare to proto3 behaviour - test for pointers to empty struct and nil pointer Signed-off-by: Liamsi <[email protected]>
- use []byte{} not []byte(nil) Signed-off-by: Liamsi <[email protected]>
@liamsi Modified the fuzz tests to also include empty structs. There's one test case that still fails... we should also run the other fuzz tests to test decoding. |
This reverts commit e90abf1
…writeemptyptr_tests
f8b2561
to
6db2352
Compare
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.
Looks good to me. We could improve one error message in being more precise and we could make the "nil struct pointers not supporeted"-error a const. error. such that the caller can handle the case if desired. We can think of this in follow up PRs.
We still need to test it against tendermint, though.
binary-encode.go
Outdated
// Proto3's Golang client does. | ||
// This also makes it easier to upgrade to Amino2 | ||
// which would enable the encoding of nil structs. | ||
return errors.New("Amino1 doesn't support nil struct pointers") |
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.
I propose this to be a sentinel error / constant. This would give the caller some control over the behaviour, too.
Also, I think the error message should be "Amino1 doesn't support nil struct pointers in lists"
Ok, this changed in later commit. Maybe, "nil struct pointers in lists are not supported when empty_elements field tag is set". The sentinel error might still be useful, though. We can merge this as it is and think about other cases where this makes sense too (see #191)
// * next ByteLength bytes are 0x00, and | ||
// * - erv is not a struct pointer, or | ||
// - field option doesn't have EmptyElements set | ||
// (the condition below uses demorgan's law) |
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.
nit: Demorgan's
tested against tendermint (develop). There will be a failing regression test. One has to apply the following changes for the test to pass: Index: types/proto3_test.go
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- types/proto3_test.go (revision 6e3c5e803322d7ae08dbbe6f885899c6204beed5)
+++ types/proto3_test.go (date 1533489963000)
@@ -67,11 +67,6 @@
Height: 150,
Time: &proto3.Timestamp{Seconds: seconds, Nanos: nanos},
NumTxs: 7,
- // This is not fully skipped in amino (yet) although it is empty:
- LastBlockID: &proto3.BlockID{
- PartsHeader: &proto3.PartSetHeader{
- },
- },
TotalTxs: 100,
LastCommitHash: []byte("commit hash"),
DataHash: []byte("data hash"), |
We should document that we differ from protobuf here but that we can enforce protobuf compatible behaviour by adding the Also, I'm wondering if this shouldn't be the default behaviour and the tag would explicitly signal that we deviate from proto3 instead (and add the tag into tendermint types to where necessary). But I do not think it is reasonable to block this PR on this decision / discussion. Thanks @jaekwon. Merging now. And will prep a release afterwards. |
* DecodeInt{8, 16} negative limit checks + tests (#125) Updates #120 Also adds a test for Byteslice encoding and decoding roundtripping and part slicing then rejoining. * fix circleci2.0 * some metalinter issues * skip over default values when encoding time (#178) * do not encode empty structs, unless `amino:"write_empty"` is set (#179) * skip over empty structs by default * slightly more info on panics * Fix zero time decoding (#190) - fix decoding of skipped fields in time, or completely skipped time - necessary because sec=0 and ns=0 do not result in time.Time{} and vice versa * Prepare release 0.11.0 (#193) * Fix time decoding & encoding of arrays and structs - top-level entry functions called with BinFieldNum:1 to properly encode e.g. arrays of structs (see non-time related test) - add defaultValue method, different from #196 it deals with multiply nested pointers * Removed dependency on tmlibs/common * Always write empty if struct field is pointer * add tests for #206 - test for pointers to empty struct and nil pointer * fix proto3 compatibility for empty structs * Add EmptyStruct to fuzz tests * Revert "fix proto3 compatibility for empty structs" * Do not allow encoding of nil struct pointers in a slice/array * By default, 0-length list elements are decoded as nil
Currently we don't write empty structs even if it's a non-nil pointer to an empty struct.
This loses information about nil vs empty structs, when say the field value is a non-nil pointer to an empty struct.
This causes all kinds of issues with Tendermint, and probably isn't the behavior that we want, and it isn't the same as goproto3 behavior either.
This PR tries to fix this.
Still to do: