diff --git a/CHANGELOG.md b/CHANGELOG.md index 991139534087..c21780ebd166 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (baseapp) [#2](https://github.com/01builders/cosmos-sdk/pull/2) Re-add query router for custom abci queries. * (x/auth/vesting) [#3](https://github.com/01builders/cosmos-sdk/pull/3) Add start time for continuous vesting accounts. * (testing) [#5](https://github.com/01builders/cosmos-sdk/pull/5) Add `MakeTestEncodingConfigWithOpts` to pass `testutil.CodecOptions` when creating `TestEncodingConfig`. +* (x/auth) [#6](https://github.com/01builders/cosmos-sdk/pull/6) Support legacy global AccountNumber. ## [v0.50.11](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.11) - 2024-12-16 diff --git a/x/auth/keeper/keeper.go b/x/auth/keeper/keeper.go index 393ed99907d3..1e1ffa7dfc36 100644 --- a/x/auth/keeper/keeper.go +++ b/x/auth/keeper/keeper.go @@ -17,6 +17,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/types" + gogotypes "github.com/cosmos/gogoproto/types" ) // AccountKeeperI is the interface contract that x/auth's keeper implements. @@ -179,13 +180,45 @@ func (ak AccountKeeper) GetSequence(ctx context.Context, addr sdk.AccAddress) (u return acc.GetSequence(), nil } +func (ak AccountKeeper) NextAccountNumberLegacy(ctx context.Context) (uint64, error) { + store := ak.storeService.OpenKVStore(ctx) + b, err := store.Get(types.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) + } + if err := ak.AccountNumber.Set(ctx, v.Value+1); err != nil { + return 0, fmt.Errorf("failed to set account number: %w", err) + } + + return v.Value, nil +} + // NextAccountNumber returns and increments the global account number counter. // If the global account number is not set, it initializes it with value 0. func (ak AccountKeeper) NextAccountNumber(ctx context.Context) uint64 { - n, err := ak.AccountNumber.Next(ctx) + n, err := collections.Item[uint64](ak.AccountNumber).Get(ctx) + if err == nil { + if err := ak.AccountNumber.Set(ctx, n+1); err != nil { + panic(err) + } + return n + } + + if errors.Is(err, collections.ErrNotFound) { + // this won't happen in the tip of production network, + // but can happen when query historical states, + // fallback to old key for backward-compatibility. + n, err = ak.NextAccountNumberLegacy(ctx) + } + if err != nil { panic(err) } + return n } diff --git a/x/auth/migrations/v5/migrate.go b/x/auth/migrations/v5/migrate.go index 44fcf970c359..d0d4ee981b8a 100644 --- a/x/auth/migrations/v5/migrate.go +++ b/x/auth/migrations/v5/migrate.go @@ -7,13 +7,12 @@ import ( "cosmossdk.io/collections" storetypes "cosmossdk.io/core/store" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) -var LegacyGlobalAccountNumberKey = []byte("globalAccountNumber") - 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 +36,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 } diff --git a/x/auth/migrations/v5/migrate_test.go b/x/auth/migrations/v5/migrate_test.go index c0c7113fb580..3c1ee663e385 100644 --- a/x/auth/migrations/v5/migrate_test.go +++ b/x/auth/migrations/v5/migrate_test.go @@ -8,6 +8,7 @@ import ( "cosmossdk.io/collections" "cosmossdk.io/collections/colltest" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func TestMigrate(t *testing.T) { @@ -21,7 +22,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) diff --git a/x/auth/types/keys.go b/x/auth/types/keys.go index fb3295511f23..cd3af0ad0b3e 100644 --- a/x/auth/types/keys.go +++ b/x/auth/types/keys.go @@ -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") )