fix(auth): support legacy global AccountNumber when query historical state (#23743)

Co-authored-by: HuangYi <huang@crypto.com>
This commit is contained in:
mmsqe 2025-02-26 07:23:05 +08:00 committed by GitHub
parent 537ff477d5
commit fa82101b0e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 68 additions and 7 deletions

View File

@ -52,6 +52,8 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
### Bug Fixes
* (x/auth) [#23741](https://github.com/cosmos/cosmos-sdk/pull/23741) Support legacy global AccountNumber.
### Removed
* (tools/hub) [#23562](https://github.com/cosmos/cosmos-sdk/pull/23562) Remove `tools/hubl`. A similar tool will be maintained in [ignite](https://www.github.com/ignite/cli).

View File

@ -9,6 +9,7 @@ import (
"fmt"
gogoproto "github.com/cosmos/gogoproto/proto"
gogotypes "github.com/cosmos/gogoproto/types"
_ "cosmossdk.io/api/cosmos/accounts/defaults/base/v1" // import for side-effects
"cosmossdk.io/collections"
@ -22,6 +23,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
@ -122,14 +124,39 @@ func (k Keeper) IsAccountsModuleAccount(
return hasAcc
}
func (k Keeper) GetAccountNumberLegacy(ctx context.Context) (uint64, error) {
store := k.KVStoreService.OpenKVStore(ctx)
b, err := store.Get(authtypes.LegacyGlobalAccountNumberKey)
if err != nil {
return 0, fmt.Errorf("failed to get legacy account number: %w", err)
}
v := new(gogotypes.UInt64Value)
if err := v.Unmarshal(b); err != nil {
return 0, fmt.Errorf("failed to unmarshal legacy account number: %w", err)
}
return v.Value, nil
}
func (k Keeper) NextAccountNumber(
ctx context.Context,
) (accNum uint64, err error) {
accNum, err = k.AccountNumber.Next(ctx)
accNum, err = collections.Item[uint64](k.AccountNumber).Get(ctx)
if err != nil && errors.Is(err, collections.ErrNotFound) {
// This change makes the method works in historical states.
// Although the behavior is not identical, but semantically compatible.
//
// For the state machine, it also does the migration lazily.
accNum, err = k.GetAccountNumberLegacy(ctx)
}
if err != nil {
return 0, err
}
if err := k.AccountNumber.Set(ctx, accNum+1); err != nil {
return 0, err
}
return accNum, nil
}

View File

@ -9,6 +9,8 @@ import (
"cosmossdk.io/collections"
"cosmossdk.io/x/accounts/accountstd"
"cosmossdk.io/x/accounts/internal/implementation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func TestKeeper_Init(t *testing.T) {
@ -90,3 +92,28 @@ func TestKeeper_Query(t *testing.T) {
require.True(t, implementation.Equal(&types.Int64Value{Value: 1000}, resp))
})
}
func TestKeeper_NextAccountNumber(t *testing.T) {
m, ctx := newKeeper(t, accountstd.AddAccount("test", NewTestAccount))
store := m.KVStoreService.OpenKVStore(ctx)
num := uint64(10)
val := &types.UInt64Value{
Value: num,
}
data, err := val.Marshal()
require.NoError(t, err)
err = store.Set(authtypes.LegacyGlobalAccountNumberKey, data)
require.NoError(t, err)
n, err := m.NextAccountNumber(ctx)
require.NoError(t, err)
require.Equal(t, num, n)
num = uint64(0)
err = m.AccountNumber.Set(ctx, num)
require.NoError(t, err)
n, err = m.NextAccountNumber(ctx)
require.NoError(t, err)
require.Equal(t, num, n)
}

View File

@ -7,13 +7,13 @@ import (
"cosmossdk.io/collections"
storetypes "cosmossdk.io/core/store"
)
var LegacyGlobalAccountNumberKey = []byte("globalAccountNumber")
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func Migrate(ctx context.Context, storeService storetypes.KVStoreService, sequence collections.Sequence) error {
store := storeService.OpenKVStore(ctx)
b, err := store.Get(LegacyGlobalAccountNumberKey)
b, err := store.Get(authtypes.LegacyGlobalAccountNumberKey)
if err != nil {
return err
}
@ -37,7 +37,7 @@ func Migrate(ctx context.Context, storeService storetypes.KVStoreService, sequen
}
// remove the value from the old prefix.
err = store.Delete(LegacyGlobalAccountNumberKey)
err = store.Delete(authtypes.LegacyGlobalAccountNumberKey)
if err != nil {
return err
}

View File

@ -7,7 +7,9 @@ import (
"github.com/stretchr/testify/require"
"cosmossdk.io/collections"
"cosmossdk.io/core/testing"
coretesting "cosmossdk.io/core/testing"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func TestMigrate(t *testing.T) {
@ -22,7 +24,7 @@ func TestMigrate(t *testing.T) {
legacySeqBytes, err := (&types.UInt64Value{Value: wantValue}).Marshal()
require.NoError(t, err)
err = kv.OpenKVStore(ctx).Set(LegacyGlobalAccountNumberKey, legacySeqBytes)
err = kv.OpenKVStore(ctx).Set(authtypes.LegacyGlobalAccountNumberKey, legacySeqBytes)
require.NoError(t, err)
err = Migrate(ctx, kv, seq)

View File

@ -28,4 +28,7 @@ var (
// AccountNumberStoreKeyPrefix prefix for account-by-id store
AccountNumberStoreKeyPrefix = collections.NewPrefix("accountNumber")
// legacy param key for global account number
LegacyGlobalAccountNumberKey = []byte("globalAccountNumber")
)