tendermint / go-amino

Protobuf3 with Interface support - Designed for blockchains (deterministic, upgradeable, fast, and compact)
Other
260 stars 84 forks source link

Nested type marshal #320

Closed SeavantUUz closed 4 years ago

SeavantUUz commented 4 years ago

I think it is weired, so I want to know why.

define two structure:

type Account struct {
    Id            string `json:"id" yaml:"id"`
    AccountNumber uint64 `json:"account_number,omitempty" yaml:"account_number"`
    Auths         []AccountAuth   `json:"auths" yaml:"auths"`
}

and

type ResultAccountWithHeight struct {
    Height string `json:"height"`
    Result Account `json:"result"`
}

then registered Account into cdc:

cdc.RegisterConcrete(&Account{}, "chain/Account", nil)

and marshal it:

account := Account{Id: "alice", AccountNumber: 34, Auths: auths}
resultAccount := ResultAccountWithHeight{Height: "52133", Result: account}
s1, _ := cdc.MarshalJSON(account)
s2, _ := cdc.MarshalJSON(resultAccount)

and result:

account:

{"type":"chain/Account","value":{"id":"alice","account_number":"34","auths":[{"name":"root","address":"xxxxxx"}]}}

resultAccount:

{"height":"52133","result":{"id":"alice","account_number":"34","auths":[{"name":"root","address":"xxxxxx"}]}}

And you see, after marshal account includes type/value infomation(aka. chain/Account). But when nested in other structure, the infomation loss.

I wander why that happend and is there a correct way for nested structure can keep it's type info ?

Thx.

SeavantUUz commented 4 years ago

After step by step debug, finally I realized that the type info is to help amino know how a interface can be converted to a concrete type(in nested) or the whole struct is registered to cdc(in outer).

So, if I created a Account interface and rename current Account struct, I can get what I excepted result.