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

util: JSONify uint160 using LE instead of BE #785

Merged
merged 2 commits into from
Mar 24, 2020

Conversation

AnnaShaleva
Copy link
Member

closes #769

@AnnaShaleva AnnaShaleva added this to the v0.74.1 milestone Mar 23, 2020
@AnnaShaleva AnnaShaleva self-assigned this Mar 23, 2020
@codecov
Copy link

codecov bot commented Mar 23, 2020

Codecov Report

Merging #785 into master will decrease coverage by 0.00%.
The diff coverage is 80.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #785      +/-   ##
==========================================
- Coverage   64.34%   64.34%   -0.01%     
==========================================
  Files         141      141              
  Lines       12934    12916      -18     
==========================================
- Hits         8323     8311      -12     
+ Misses       4208     4203       -5     
+ Partials      403      402       -1     
Impacted Files Coverage Δ
pkg/rpc/response/result/account_state.go 0.00% <0.00%> (ø)
pkg/rpc/response/result/asset_state.go 0.00% <ø> (ø)
pkg/rpc/response/result/contract_state.go 0.00% <0.00%> (ø)
pkg/smartcontract/parameter.go 75.79% <100.00%> (+0.19%) ⬆️
pkg/util/uint160.go 100.00% <100.00%> (ø)
pkg/wallet/token.go 100.00% <100.00%> (+8.33%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b37c593...2187346. Read the comment docs.

Available: a.Available,
Precision: a.Precision,
FeeMode: a.FeeMode,
FeeAddress: a.FeeAddress.Reverse(), // FeeAddress should be marshaled in BE but default marshaler uses LE.
Copy link
Member

Choose a reason for hiding this comment

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

Are you sure about that?

Copy link
Member

Choose a reason for hiding this comment

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

It looks to me that it's always zero and there are no examples that could prove it being LE or BE in real life. Thus, I'd suggest using the default (which is LE) and not adding yet another wrapper.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, I'm not sure because official RPC API (https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/getassetstate.html) does not suppose serialization of fields FeeAddress and FeeMode (see also https://github.com/neo-project/neo/blob/master-2.x/neo/Ledger/AssetState.cs#L151).
In neo-go these fields are serialized, particularly, FeeAddress was serialized in BE, so I decided to leave it as it was before.

Copy link
Member Author

@AnnaShaleva AnnaShaleva Mar 23, 2020

Choose a reason for hiding this comment

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

Also fields ID and AssetType of AssetState JSONify as assetID and assetType respectively, but in C# API it should be just id and type. Should I fix it?

Copy link
Member Author

Choose a reason for hiding this comment

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

It looks to me that it's always zero and there are no examples that could prove it being LE or BE in real life. Thus, I'd suggest using the default (which is LE) and not adding yet another wrapper.

Fixed

Copy link
Member

Choose a reason for hiding this comment

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

official RPC API does not suppose serialization of fields FeeAddress and FeeMode

We can drop them from the answer then.

Should I fix it?

Yep, we should be 100% compatible in our outputs.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@@ -38,7 +38,7 @@ func NewToken(tokenHash util.Uint160, name, symbol string, decimals int64) *Toke
func (t *Token) MarshalJSON() ([]byte, error) {
m := &tokenAux{
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we don't need this struct at all now?

Copy link
Member Author

Choose a reason for hiding this comment

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

We use this struct in UnmarshalJSON too because it does not contains Address and we have to fill this field. Unmarshalling into &tokenAux lets us avoid recursion, so perhaps we still need it?

Copy link
Member

Choose a reason for hiding this comment

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

json:"-"? And maybe this structure shouldn't have an Address field, but rather an Address() method (and maybe address field as a cache, though I doubt it's worth it, this structure is never in the hot path).

Copy link
Member Author

Choose a reason for hiding this comment

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

Done (added Address() method)

@@ -36,7 +36,7 @@ func (it *Item) AddSignature(pub *keys.PublicKey, sig []byte) {
// MarshalJSON implements json.Marshaler interface.
func (it Item) MarshalJSON() ([]byte, error) {
ci := itemAux{
Script: it.Script,
Script: it.Script.Reverse(), // script should be marshaled in BE but default marshaler uses LE.
Copy link
Member

Choose a reason for hiding this comment

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

It'd be nice to check this against some C# examples.

Copy link
Member Author

Choose a reason for hiding this comment

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

They store Script as []byte in LE, so fixed

@@ -197,7 +199,7 @@ func (p *Parameter) UnmarshalJSON(data []byte) (err error) {
if err = json.Unmarshal(r.Value, &h); err != nil {
return
}
p.Value = h
p.Value = h.Reverse() // Hash160 should be marshaled in BE but default marshaler uses LE.
Copy link
Member

Choose a reason for hiding this comment

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

Not sure about this also.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

But our internal storage is BE and theirs is LE IIRC, so reversing here gives you LE.

@AnnaShaleva AnnaShaleva force-pushed the feature/uint160_marshalling branch 5 times, most recently from 79f0170 to cac366f Compare March 23, 2020 12:57
@@ -123,11 +123,11 @@ func (u *Uint160) UnmarshalJSON(data []byte) (err error) {
return err
}
js = strings.TrimPrefix(js, "0x")
*u, err = Uint160DecodeStringBE(js)
*u, err = Uint160DecodeStringLE(js)
Copy link
Member Author

Choose a reason for hiding this comment

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

@roman-khimov Which one should we use here?

Copy link
Member

Choose a reason for hiding this comment

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

LE, that's the whole point of #769.

FeeMode uint8 `json:"fee"`
FeeAddress util.Uint160 `json:"address"`
FeeMode uint8 `json:"-"`
FeeAddress util.Uint160 `json:"-"`
Copy link
Member

Choose a reason for hiding this comment

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

Why not just drop them?

Copy link
Member

Choose a reason for hiding this comment

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

And make a separate commit, because it's a separate change.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Modified result.AssetState:
	- removed `FeeMode` and `FeeAddress` fields
	- fixed json name of `ID` and `AssetType` fields
to be consistent with C# RPC server
@roman-khimov roman-khimov merged commit 751e79d into master Mar 24, 2020
@roman-khimov roman-khimov deleted the feature/uint160_marshalling branch March 24, 2020 09:41
AnnaShaleva added a commit that referenced this pull request Apr 1, 2020
There's a bug after #785: smartcontract.Parameter of type hash160 should
be marshalled in LE (as default marshaller for uint160 does) instead of
BE, so fixed.
AnnaShaleva added a commit that referenced this pull request Apr 1, 2020
There's a bug after #785: smartcontract.Parameter of type hash160 should
be marshalled in LE (as default marshaller for uint160 does) instead of
BE, so fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Contract hash (Uint160) JSONification problem
2 participants