From 4c054a8565dd262dc3802309b6dd7d7cb0382946 Mon Sep 17 00:00:00 2001 From: Federico Kunze <federico.kunze94@gmail.com> Date: Thu, 15 Oct 2020 11:16:20 +0200 Subject: [PATCH 1/3] client: add GetAccount and GetAccountWithHeight to AccountRetriever --- client/account_retriever.go | 23 ++++++- client/test_helpers.go | 67 +++++++++++++++++-- .../adr-020-protobuf-transaction-encoding.md | 2 + x/auth/types/account_retriever.go | 9 ++- 4 files changed, 91 insertions(+), 10 deletions(-) diff --git a/client/account_retriever.go b/client/account_retriever.go index e7f9fbaea41d..2d8c3f903d8e 100644 --- a/client/account_retriever.go +++ b/client/account_retriever.go @@ -1,11 +1,28 @@ package client -import "github.com/cosmos/cosmos-sdk/types" +import ( + "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Account defines a read-only version of the auth module's AccountI. +type Account interface { + GetAddress() sdk.AccAddress + GetPubKey() crypto.PubKey // can return nil. + GetAccountNumber() uint64 + GetSequence() uint64 + + // Ensure that account implements stringer + String() string +} // AccountRetriever defines the interfaces required by transactions to // ensure an account exists and to be able to query for account fields necessary // for signing. type AccountRetriever interface { - EnsureExists(clientCtx Context, addr types.AccAddress) error - GetAccountNumberSequence(clientCtx Context, addr types.AccAddress) (accNum uint64, accSeq uint64, err error) + GetAccount(clientCtx Context, addr sdk.AccAddress) (Account, error) + GetAccountWithHeight(clientCtx Context, addr sdk.AccAddress) (Account, int64, error) + EnsureExists(clientCtx Context, addr sdk.AccAddress) error + GetAccountNumberSequence(clientCtx Context, addr sdk.AccAddress) (accNum uint64, accSeq uint64, err error) } diff --git a/client/test_helpers.go b/client/test_helpers.go index 673519c5fac9..39a63565c3c9 100644 --- a/client/test_helpers.go +++ b/client/test_helpers.go @@ -3,19 +3,76 @@ package client import ( "fmt" + "github.com/tendermint/tendermint/crypto" + sdk "github.com/cosmos/cosmos-sdk/types" ) // TestAccountRetriever is an AccountRetriever that can be used in unit tests type TestAccountRetriever struct { - Accounts map[string]struct { - Address sdk.AccAddress - Num uint64 - Seq uint64 + Accounts map[string]TestAccount +} + +// TestAccount represents a client Account that can be used in unit tests +type TestAccount struct { + Address sdk.AccAddress + Num uint64 + Seq uint64 +} + +// GetAddress implements client Account.GetAddress +func (t TestAccount) GetAddress() sdk.AccAddress { + return t.Address +} + +// GetPubKey implements client Account.GetPubKey +func (t TestAccount) GetPubKey() crypto.PubKey { + return nil +} + +// GetAccountNumber implements client Account.GetAccountNumber +func (t TestAccount) GetAccountNumber() uint64 { + return t.Num +} + +// GetSequence implements client Account.GetSequence +func (t TestAccount) GetSequence() uint64 { + return t.Seq +} + +// String implements client Account.String +func (t TestAccount) String() string { + return fmt.Sprintf(`address: %s +pub_key: nil +account_number: %d +sequence: %d`, t.Address, t.Num, t.Seq, + ) +} + +var ( + _ AccountRetriever = TestAccountRetriever{} + _ Account = TestAccount{} +) + +// GetAccount implements AccountRetriever.GetAccount +func (t TestAccountRetriever) GetAccount(_ Context, addr sdk.AccAddress) (Account, error) { + acc, ok := t.Accounts[addr.String()] + if !ok { + return nil, fmt.Errorf("account %s not found", addr) } + + return acc, nil } -var _ AccountRetriever = TestAccountRetriever{} +// GetAccountWithHeight implements AccountRetriever.GetAccountWithHeight +func (t TestAccountRetriever) GetAccountWithHeight(clientCtx Context, addr sdk.AccAddress) (Account, int64, error) { + acc, err := t.GetAccount(clientCtx, addr) + if err != nil { + return nil, 0, err + } + + return acc, 0, nil +} // EnsureExists implements AccountRetriever.EnsureExists func (t TestAccountRetriever) EnsureExists(_ Context, addr sdk.AccAddress) error { diff --git a/docs/architecture/adr-020-protobuf-transaction-encoding.md b/docs/architecture/adr-020-protobuf-transaction-encoding.md index 3d1eb531a376..45d12933236d 100644 --- a/docs/architecture/adr-020-protobuf-transaction-encoding.md +++ b/docs/architecture/adr-020-protobuf-transaction-encoding.md @@ -315,6 +315,8 @@ and messages. ```go type AccountRetriever interface { + GetAccount(clientCtx Context, addr sdk.AccAddress) (client.Account, error) + GetAccountWithHeight(clientCtx Context, addr sdk.AccAddress) (client.Account, int64, error) EnsureExists(clientCtx client.Context, addr sdk.AccAddress) error GetAccountNumberSequence(clientCtx client.Context, addr sdk.AccAddress) (uint64, uint64, error) } diff --git a/x/auth/types/account_retriever.go b/x/auth/types/account_retriever.go index 2b8d24ac279c..f84c744188ff 100644 --- a/x/auth/types/account_retriever.go +++ b/x/auth/types/account_retriever.go @@ -13,13 +13,18 @@ import ( grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" ) +var ( + _ client.Account = AccountI(nil) + _ client.AccountRetriever = AccountRetriever{} +) + // AccountRetriever defines the properties of a type that can be used to // retrieve accounts. type AccountRetriever struct{} // GetAccount queries for an account given an address and a block height. An // error is returned if the query or decoding fails. -func (ar AccountRetriever) GetAccount(clientCtx client.Context, addr sdk.AccAddress) (AccountI, error) { +func (ar AccountRetriever) GetAccount(clientCtx client.Context, addr sdk.AccAddress) (client.Account, error) { account, _, err := ar.GetAccountWithHeight(clientCtx, addr) return account, err } @@ -28,7 +33,7 @@ func (ar AccountRetriever) GetAccount(clientCtx client.Context, addr sdk.AccAddr // height of the query with the account. An error is returned if the query // or decoding fails. //nolint:interfacer -func (ar AccountRetriever) GetAccountWithHeight(clientCtx client.Context, addr sdk.AccAddress) (AccountI, int64, error) { +func (ar AccountRetriever) GetAccountWithHeight(clientCtx client.Context, addr sdk.AccAddress) (client.Account, int64, error) { var header metadata.MD queryClient := NewQueryClient(clientCtx) From 961515ea5ad2206470fe563a6db51e0dbdd0f80d Mon Sep 17 00:00:00 2001 From: Federico Kunze <federico.kunze94@gmail.com> Date: Thu, 15 Oct 2020 11:21:02 +0200 Subject: [PATCH 2/3] update ADR --- docs/architecture/adr-020-protobuf-transaction-encoding.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/architecture/adr-020-protobuf-transaction-encoding.md b/docs/architecture/adr-020-protobuf-transaction-encoding.md index 45d12933236d..0e9a644a5918 100644 --- a/docs/architecture/adr-020-protobuf-transaction-encoding.md +++ b/docs/architecture/adr-020-protobuf-transaction-encoding.md @@ -11,6 +11,7 @@ - 2020 August 07: Use ADR 027 for serializing `SignDoc`. - 2020 August 19: Move sequence field from `SignDoc` to `SignerInfo`. - 2020 September 25: Remove `PublicKey` type in favor of `secp256k1.PubKey`, `ed25519.PubKey` and `multisig.LegacyAminoPubKey`. +- 2020 October 15: Add `GetAccount` and `GetAccountWithHeight` methods to the `AccountRetriever` interface. ## Status From c60d518784a426a9d7be71e1b847be6831aa76be Mon Sep 17 00:00:00 2001 From: Federico Kunze <federico.kunze94@gmail.com> Date: Thu, 15 Oct 2020 16:01:04 +0200 Subject: [PATCH 3/3] address comments from review --- client/account_retriever.go | 3 --- client/test_helpers.go | 23 +++++++---------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/client/account_retriever.go b/client/account_retriever.go index 2d8c3f903d8e..51c0a7fa9bcc 100644 --- a/client/account_retriever.go +++ b/client/account_retriever.go @@ -12,9 +12,6 @@ type Account interface { GetPubKey() crypto.PubKey // can return nil. GetAccountNumber() uint64 GetSequence() uint64 - - // Ensure that account implements stringer - String() string } // AccountRetriever defines the interfaces required by transactions to diff --git a/client/test_helpers.go b/client/test_helpers.go index 39a63565c3c9..1140298fda42 100644 --- a/client/test_helpers.go +++ b/client/test_helpers.go @@ -8,10 +8,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// TestAccountRetriever is an AccountRetriever that can be used in unit tests -type TestAccountRetriever struct { - Accounts map[string]TestAccount -} +var ( + _ AccountRetriever = TestAccountRetriever{} + _ Account = TestAccount{} +) // TestAccount represents a client Account that can be used in unit tests type TestAccount struct { @@ -40,20 +40,11 @@ func (t TestAccount) GetSequence() uint64 { return t.Seq } -// String implements client Account.String -func (t TestAccount) String() string { - return fmt.Sprintf(`address: %s -pub_key: nil -account_number: %d -sequence: %d`, t.Address, t.Num, t.Seq, - ) +// TestAccountRetriever is an AccountRetriever that can be used in unit tests +type TestAccountRetriever struct { + Accounts map[string]TestAccount } -var ( - _ AccountRetriever = TestAccountRetriever{} - _ Account = TestAccount{} -) - // GetAccount implements AccountRetriever.GetAccount func (t TestAccountRetriever) GetAccount(_ Context, addr sdk.AccAddress) (Account, error) { acc, ok := t.Accounts[addr.String()]