Skip to content

Commit 9b70a6d

Browse files
authored
fix: genesis auth account format (#517)
* restore format of genesis auth * add type * add changelog * fix wasm gas verification check * fix TestBaseApp_BlockGas * fix marshal/unmarshal pubkey * restore MarshalJSONPB, UnmarshalJSONPB * add unittest for MarshalJSONPB of vestingAccount * add unittest for MarshalJSONPB of moduleAccount * fix BaseVestingAccount UnmarshalJSONPB func * refactor: change multi if to else if, Nil to NoError
1 parent ab3dfa8 commit 9b70a6d

File tree

10 files changed

+466
-12
lines changed

10 files changed

+466
-12
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
5050
* (x/wasm) [\#453](https://github.com/line/lbm-sdk/pull/453) modify wasm grpc query api path
5151
* (client) [\#476](https://github.com/line/lbm-sdk/pull/476) change the default value of the client output format in the config
5252
* (server/grpc) [\#516](https://github.com/line/lbm-sdk/pull/516) restore build norace flag
53+
* (genesis) [\#517](https://github.com/line/lbm-sdk/pull/517) fix genesis auth account format(cosmos-sdk style -> lbm-sdk style)
5354

5455
### Breaking Changes
5556

baseapp/block_gas_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func TestBaseApp_BlockGas(t *testing.T) {
124124
require.Equal(t, []byte("ok"), okValue)
125125
}
126126
// check block gas is always consumed
127-
baseGas := uint64(36950) // baseGas is the gas consumed before tx msg
127+
baseGas := uint64(35000) // baseGas is the gas consumed before tx msg
128128
expGasConsumed := addUint64Saturating(tc.gasToConsume, baseGas)
129129
if expGasConsumed > txtypes.MaxGasWanted {
130130
// capped by gasLimit

x/auth/keeper/keeper.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,13 @@ func (ak AccountKeeper) decodeAccount(bz []byte) types.AccountI {
226226

227227
// MarshalAccount protobuf serializes an Account interface
228228
func (ak AccountKeeper) MarshalAccount(accountI types.AccountI) ([]byte, error) { // nolint:interfacer
229-
return ak.cdc.MarshalInterface(accountI)
229+
return types.MarshalAccountX(ak.cdc, accountI)
230230
}
231231

232232
// UnmarshalAccount returns an Account interface from raw encoded account
233233
// bytes of a Proto-based Account type
234234
func (ak AccountKeeper) UnmarshalAccount(bz []byte) (types.AccountI, error) {
235-
var acc types.AccountI
236-
return acc, ak.cdc.UnmarshalInterface(bz, &acc)
235+
return types.UnmarshalAccountX(ak.cdc, bz)
237236
}
238237

239238
// GetCodec return codec.Codec object used by the keeper

x/auth/types/account.go

+170-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package types
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"errors"
67
"fmt"
8+
"strconv"
79
"strings"
810

11+
"github.com/gogo/protobuf/jsonpb"
912
"github.com/gogo/protobuf/proto"
1013
"github.com/line/ostracon/crypto"
1114
"gopkg.in/yaml.v2"
@@ -31,8 +34,9 @@ var (
3134
ModuleAccountSig = []byte("macc")
3235

3336
PubKeyTypeSecp256k1 = byte(1)
34-
PubKeyTypeEd25519 = byte(2)
35-
PubKeyTypeMultisig = byte(3)
37+
PubKeyTypeSecp256R1 = byte(2)
38+
PubKeyTypeEd25519 = byte(3)
39+
PubKeyTypeMultisig = byte(4)
3640
)
3741

3842
// NewBaseAccount creates a new BaseAccount object
@@ -359,7 +363,38 @@ type AccountI interface {
359363
MarshalX() ([]byte, error)
360364
}
361365

362-
// TODO(dudong2): remove MarshalAccountX, UnmarshalAccountX(because codec.BinaryMarshaler is removed -> build failed) - ref. https://github.com/line/lbm-sdk/pull/320
366+
func MarshalAccountX(cdc codec.BinaryCodec, acc AccountI) ([]byte, error) {
367+
if bacc, ok := acc.(*BaseAccount); ok && bacc.MultisigPubKey == nil {
368+
return acc.MarshalX()
369+
} else if macc, ok := acc.(*ModuleAccount); ok && macc.MultisigPubKey == nil {
370+
return acc.MarshalX()
371+
} else {
372+
return cdc.MarshalInterface(acc)
373+
}
374+
}
375+
376+
func UnmarshalAccountX(cdc codec.BinaryCodec, bz []byte) (AccountI, error) {
377+
sigLen := len(BaseAccountSig)
378+
if len(bz) < sigLen {
379+
return nil, fmt.Errorf("invalid data")
380+
}
381+
if bytes.Equal(bz[:sigLen], BaseAccountSig) {
382+
acc := &BaseAccount{}
383+
if err := acc.Unmarshal(bz[sigLen:]); err != nil {
384+
return nil, err
385+
}
386+
return acc, nil
387+
} else if bytes.Equal(bz[:sigLen], ModuleAccountSig) {
388+
acc := &ModuleAccount{}
389+
if err := acc.Unmarshal(bz[sigLen:]); err != nil {
390+
return nil, err
391+
}
392+
return acc, nil
393+
} else {
394+
var acc AccountI
395+
return acc, cdc.UnmarshalInterface(bz, &acc)
396+
}
397+
}
363398

364399
// ModuleAccountI defines an account interface for modules that hold tokens in
365400
// an escrow.
@@ -392,3 +427,135 @@ type GenesisAccount interface {
392427

393428
Validate() error
394429
}
430+
431+
// custom json marshaler for BaseAccount & ModuleAccount
432+
433+
type PubKeyJSON struct {
434+
Type byte `json:"type"`
435+
Key []byte `json:"key"`
436+
}
437+
438+
type BaseAccountJSON struct {
439+
Address string `json:"address"`
440+
PubKey PubKeyJSON `json:"pub_key"`
441+
AccountNumber uint64 `json:"account_number"`
442+
Sequence string `json:"sequence"`
443+
}
444+
445+
func (acc BaseAccount) MarshalJSONPB(m *jsonpb.Marshaler) ([]byte, error) {
446+
var bi BaseAccountJSON
447+
448+
bi.Address = acc.GetAddress().String()
449+
bi.AccountNumber = acc.GetAccountNumber()
450+
bi.Sequence = strconv.FormatUint(acc.Sequence, 10)
451+
var bz []byte
452+
var err error
453+
if acc.Secp256K1PubKey != nil {
454+
bi.PubKey.Type = PubKeyTypeSecp256k1
455+
bz, err = acc.Secp256K1PubKey.Marshal()
456+
} else if acc.Secp256R1PubKey != nil {
457+
bi.PubKey.Type = PubKeyTypeSecp256R1
458+
bz, err = acc.Secp256R1PubKey.Marshal()
459+
} else if acc.Ed25519PubKey != nil {
460+
bi.PubKey.Type = PubKeyTypeEd25519
461+
bz, err = acc.Ed25519PubKey.Marshal()
462+
} else if acc.MultisigPubKey != nil {
463+
bi.PubKey.Type = PubKeyTypeMultisig
464+
bz, err = acc.MultisigPubKey.Marshal()
465+
}
466+
if err != nil {
467+
return nil, err
468+
}
469+
bi.PubKey.Key = bz
470+
return json.Marshal(bi)
471+
}
472+
473+
func (acc *BaseAccount) UnmarshalJSONPB(m *jsonpb.Unmarshaler, bz []byte) error {
474+
var bi BaseAccountJSON
475+
476+
err := json.Unmarshal(bz, &bi)
477+
if err != nil {
478+
return err
479+
}
480+
/* TODO: do we need to validate address format here
481+
err = sdk.ValidateAccAddress(bi.Address)
482+
if err != nil {
483+
return err
484+
}
485+
*/
486+
487+
acc.Address = bi.Address
488+
acc.AccountNumber = bi.AccountNumber
489+
acc.Sequence, err = strconv.ParseUint(bi.Sequence, 10, 64)
490+
if err != nil {
491+
return err
492+
}
493+
494+
switch bi.PubKey.Type {
495+
case PubKeyTypeEd25519:
496+
pk := new(ed25519.PubKey)
497+
if err := pk.Unmarshal(bi.PubKey.Key); err != nil {
498+
return err
499+
}
500+
acc.SetPubKey(pk)
501+
case PubKeyTypeSecp256k1:
502+
pk := new(secp256k1.PubKey)
503+
if err := pk.Unmarshal(bi.PubKey.Key); err != nil {
504+
return err
505+
}
506+
acc.SetPubKey(pk)
507+
case PubKeyTypeSecp256R1:
508+
pk := new(secp256r1.PubKey)
509+
if err := pk.Unmarshal(bi.PubKey.Key); err != nil {
510+
return err
511+
}
512+
acc.SetPubKey(pk)
513+
case PubKeyTypeMultisig:
514+
pk := new(multisig.LegacyAminoPubKey)
515+
if err := pk.Unmarshal(bi.PubKey.Key); err != nil {
516+
return err
517+
}
518+
acc.SetPubKey(pk)
519+
}
520+
return nil
521+
}
522+
523+
type ModuleAccountJSON struct {
524+
BaseAccount json.RawMessage `json:"base_account"`
525+
Name string `json:"name"`
526+
Permissions []string `json:"permissions"`
527+
}
528+
529+
func (ma ModuleAccount) MarshalJSONPB(m *jsonpb.Marshaler) ([]byte, error) {
530+
var mi ModuleAccountJSON
531+
532+
bz, err := ma.BaseAccount.MarshalJSONPB(m)
533+
if err != nil {
534+
return nil, err
535+
}
536+
mi.BaseAccount = bz
537+
mi.Name = ma.Name
538+
mi.Permissions = ma.Permissions
539+
540+
return json.Marshal(mi)
541+
}
542+
543+
func (ma *ModuleAccount) UnmarshalJSONPB(m *jsonpb.Unmarshaler, bz []byte) error {
544+
var mi ModuleAccountJSON
545+
546+
err := json.Unmarshal(bz, &mi)
547+
if err != nil {
548+
return err
549+
}
550+
551+
ma.Name = mi.Name
552+
ma.Permissions = mi.Permissions
553+
554+
ba := new(BaseAccount)
555+
if err := m.Unmarshal(strings.NewReader(string(mi.BaseAccount)), ba); err != nil {
556+
return err
557+
}
558+
ma.BaseAccount = ba
559+
560+
return nil
561+
}

x/auth/types/account_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"testing"
88

9+
"github.com/gogo/protobuf/jsonpb"
910
"github.com/stretchr/testify/require"
1011
yaml "gopkg.in/yaml.v2"
1112

@@ -214,6 +215,28 @@ func TestModuleAccountJSON(t *testing.T) {
214215
require.Equal(t, acc.String(), a.String())
215216
}
216217

218+
func TestModuleAccountJSONPB(t *testing.T) {
219+
pubkey := secp256k1.GenPrivKey().PubKey()
220+
addr := sdk.BytesToAccAddress(pubkey.Address())
221+
baseAcc := types.NewBaseAccount(addr, nil, 10, 50)
222+
acc := types.NewModuleAccount(baseAcc, "test", types.Burner)
223+
224+
jm := jsonpb.Marshaler{}
225+
bz, err := acc.MarshalJSONPB(&jm)
226+
require.NoError(t, err)
227+
228+
jum := jsonpb.Unmarshaler{}
229+
addr2 := sdk.AccAddress("")
230+
baseAcc2 := types.NewBaseAccount(addr2, nil, 0, 0)
231+
acc2 := types.NewModuleAccount(baseAcc2, "")
232+
err = acc2.UnmarshalJSONPB(&jum, bz)
233+
require.NoError(t, err)
234+
235+
// error on bad bytes
236+
err = acc2.UnmarshalJSONPB(&jum, bz[:len(bz)/2])
237+
require.Error(t, err)
238+
}
239+
217240
func TestGenesisAccountsContains(t *testing.T) {
218241
pubkey := secp256k1.GenPrivKey().PubKey()
219242
addr := sdk.BytesToAccAddress(pubkey.Address())

0 commit comments

Comments
 (0)