fix: fetch account number/sequence when not in offline mode (#16075)

This commit is contained in:
Julien Robert 2023-05-10 12:45:53 +02:00 committed by GitHub
parent 25df90d0fc
commit bb2d859e3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 7 deletions

View File

@ -69,6 +69,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Improvements
* (client) [#16075](https://github.com/cosmos/cosmos-sdk/pull/16075) Partly revert [#15953](https://github.com/cosmos/cosmos-sdk/issues/15953) and `factory.Prepare` does nothing in offline mode.
* (server) [#16071](https://github.com/cosmos/cosmos-sdk/pull/16071) When `mempool.max-txs` is set to a negative value, use a no-op mempool (effectively disable the app mempool).
* (simapp) [#15958](https://github.com/cosmos/cosmos-sdk/pull/15958) Refactor SimApp for removing the global basic manager.
* (gov) [#15979](https://github.com/cosmos/cosmos-sdk/pull/15979) Improve gov error message when failing to convert v1 proposal to v1beta1.

View File

@ -28,7 +28,9 @@ var _ AccountRetriever = (*MockAccountRetriever)(nil)
// MockAccountRetriever defines a no-op basic AccountRetriever that can be used
// in mocked contexts. Tests or context that need more sophisticated testing
// state should implement their own mock AccountRetriever.
type MockAccountRetriever struct{}
type MockAccountRetriever struct {
ReturnAccNum, ReturnAccSeq uint64
}
func (mar MockAccountRetriever) GetAccount(_ Context, _ sdk.AccAddress) (Account, error) {
return nil, nil
@ -43,5 +45,5 @@ func (mar MockAccountRetriever) EnsureExists(_ Context, _ sdk.AccAddress) error
}
func (mar MockAccountRetriever) GetAccountNumberSequence(_ Context, _ sdk.AccAddress) (uint64, uint64, error) {
return 0, 0, nil
return mar.ReturnAccNum, mar.ReturnAccSeq, nil
}

View File

@ -460,9 +460,14 @@ func (f Factory) getSimPK() (cryptotypes.PubKey, error) {
// Prepare ensures the account defined by ctx.GetFromAddress() exists and
// if the account number and/or the account sequence number are zero (not set),
// they will be queried for and set on the provided Factory. A new Factory with
// the updated fields will be returned.
// they will be queried for and set on the provided Factory.
// A new Factory with the updated fields will be returned.
// Note: When in offline mode, the Prepare does nothing and returns the original factory.
func (f Factory) Prepare(clientCtx client.Context) (Factory, error) {
if clientCtx.Offline {
return f, nil
}
fc := f
from := clientCtx.GetFromAddress()
@ -471,14 +476,19 @@ func (f Factory) Prepare(clientCtx client.Context) (Factory, error) {
}
initNum, initSeq := fc.accountNumber, fc.sequence
if initNum == 0 && initSeq == 0 {
if initNum == 0 || initSeq == 0 {
num, seq, err := fc.accountRetriever.GetAccountNumberSequence(clientCtx, from)
if err != nil {
return fc, err
}
fc = fc.WithAccountNumber(num)
fc = fc.WithSequence(seq)
if initNum == 0 {
fc = fc.WithAccountNumber(num)
}
if initSeq == 0 {
fc = fc.WithSequence(seq)
}
}
return fc, nil

34
client/tx/factory_test.go Normal file
View File

@ -0,0 +1,34 @@
package tx_test
import (
"testing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/stretchr/testify/require"
)
func TestFactoryPrepate(t *testing.T) {
t.Parallel()
factory := tx.Factory{}
clientCtx := client.Context{}
output, err := factory.Prepare(clientCtx.WithOffline(true))
require.NoError(t, err)
require.Equal(t, output, factory)
factory = tx.Factory{}.WithAccountRetriever(client.MockAccountRetriever{ReturnAccNum: 10, ReturnAccSeq: 1}).WithAccountNumber(5)
output, err = factory.Prepare(clientCtx.WithFrom("foo"))
require.NoError(t, err)
require.NotEqual(t, output, factory)
require.Equal(t, output.AccountNumber(), uint64(5))
require.Equal(t, output.Sequence(), uint64(1))
factory = tx.Factory{}.WithAccountRetriever(client.MockAccountRetriever{ReturnAccNum: 10, ReturnAccSeq: 1})
output, err = factory.Prepare(clientCtx.WithFrom("foo"))
require.NoError(t, err)
require.NotEqual(t, output, factory)
require.Equal(t, output.AccountNumber(), uint64(10))
require.Equal(t, output.Sequence(), uint64(1))
}