|
1 | 1 | package types
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
4 | 5 | "encoding/json"
|
5 | 6 | "errors"
|
6 | 7 | "fmt"
|
| 8 | + "strconv" |
7 | 9 | "strings"
|
8 | 10 |
|
| 11 | + "github.com/gogo/protobuf/jsonpb" |
9 | 12 | "github.com/gogo/protobuf/proto"
|
10 | 13 | "github.com/line/ostracon/crypto"
|
11 | 14 | "gopkg.in/yaml.v2"
|
|
31 | 34 | ModuleAccountSig = []byte("macc")
|
32 | 35 |
|
33 | 36 | PubKeyTypeSecp256k1 = byte(1)
|
34 |
| - PubKeyTypeEd25519 = byte(2) |
35 |
| - PubKeyTypeMultisig = byte(3) |
| 37 | + PubKeyTypeSecp256R1 = byte(2) |
| 38 | + PubKeyTypeEd25519 = byte(3) |
| 39 | + PubKeyTypeMultisig = byte(4) |
36 | 40 | )
|
37 | 41 |
|
38 | 42 | // NewBaseAccount creates a new BaseAccount object
|
@@ -359,7 +363,38 @@ type AccountI interface {
|
359 | 363 | MarshalX() ([]byte, error)
|
360 | 364 | }
|
361 | 365 |
|
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 | +} |
363 | 398 |
|
364 | 399 | // ModuleAccountI defines an account interface for modules that hold tokens in
|
365 | 400 | // an escrow.
|
@@ -392,3 +427,135 @@ type GenesisAccount interface {
|
392 | 427 |
|
393 | 428 | Validate() error
|
394 | 429 | }
|
| 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 | +} |
0 commit comments