Skip to content

Commit

Permalink
feat(store/v2): implement the feature to upgrade the store keys (#20453)
Browse files Browse the repository at this point in the history
Co-authored-by: Matt Kocubinski <mkocubinski@gmail.com>
  • Loading branch information
cool-develope and kocubinski authored Aug 5, 2024
1 parent 0ddf5c0 commit 6d4097b
Show file tree
Hide file tree
Showing 41 changed files with 1,219 additions and 193 deletions.
27 changes: 2 additions & 25 deletions core/store/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,8 @@ package store

// StoreUpgrades defines a series of transformations to apply the multistore db upon load
type StoreUpgrades struct {
Added []string `json:"added"`
Renamed []StoreRename `json:"renamed"`
Deleted []string `json:"deleted"`
}

// StoreRename defines a name change of a sub-store.
// All data previously under a PrefixStore with OldKey will be copied
// to a PrefixStore with NewKey, then deleted from OldKey store.
type StoreRename struct {
OldKey string `json:"old_key"`
NewKey string `json:"new_key"`
Added []string `json:"added"`
Deleted []string `json:"deleted"`
}

// IsAdded returns true if the given key should be added
Expand Down Expand Up @@ -40,17 +31,3 @@ func (s *StoreUpgrades) IsDeleted(key string) bool {
}
return false
}

// RenamedFrom returns the oldKey if it was renamed
// Returns "" if it was not renamed
func (s *StoreUpgrades) RenamedFrom(key string) string {
if s == nil {
return ""
}
for _, re := range s.Renamed {
if re.NewKey == key {
return re.OldKey
}
}
return ""
}
4 changes: 2 additions & 2 deletions runtime/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ replace (

require (
cosmossdk.io/api v0.7.5
cosmossdk.io/core v0.12.1-0.20231114100755-569e3ff6a0d7
cosmossdk.io/core v0.12.1-0.20240725072823-6a2d039e1212
cosmossdk.io/depinject v1.0.0
cosmossdk.io/log v1.3.1
cosmossdk.io/server/v2/appmanager v0.0.0-00010101000000-000000000000
Expand Down Expand Up @@ -44,7 +44,7 @@ require (
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cosmos/cosmos-db v1.0.2 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179 // indirect
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/dot v1.6.2 // indirect
Expand Down
4 changes: 2 additions & 2 deletions runtime/v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+R
github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec=
github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o=
github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I=
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179 h1:wmwDn7V3RodN9auB3FooSQxs46nHVE3u0mb87TJkZFE=
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw=
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e h1:5bxw1E0peLMrr8ZO9mYT0d9sxy0WgR1ZEWb92yjKnnk=
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw=
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down
4 changes: 2 additions & 2 deletions server/v2/cometbft/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ replace (
require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2
cosmossdk.io/api v0.7.5
cosmossdk.io/core v0.12.1-0.20231114100755-569e3ff6a0d7
cosmossdk.io/core v0.12.1-0.20240725072823-6a2d039e1212
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.3.1
cosmossdk.io/server/v2 v2.0.0-00010101000000-000000000000
Expand Down Expand Up @@ -74,7 +74,7 @@ require (
github.com/cosmos/cosmos-db v1.0.2 // indirect
github.com/cosmos/crypto v0.1.2 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179 // indirect
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
github.com/danieljoos/wincred v1.2.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions server/v2/cometbft/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiK
github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI=
github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o=
github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I=
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179 h1:wmwDn7V3RodN9auB3FooSQxs46nHVE3u0mb87TJkZFE=
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw=
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e h1:5bxw1E0peLMrr8ZO9mYT0d9sxy0WgR1ZEWb92yjKnnk=
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw=
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM=
Expand Down
6 changes: 3 additions & 3 deletions server/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ replace (

require (
cosmossdk.io/api v0.7.5
cosmossdk.io/core v0.12.1-0.20231114100755-569e3ff6a0d7
cosmossdk.io/core v0.12.1-0.20240725072823-6a2d039e1212
cosmossdk.io/core/testing v0.0.0-00010101000000-000000000000
cosmossdk.io/log v1.3.1
cosmossdk.io/server/v2/appmanager v0.0.0-00010101000000-000000000000
Expand Down Expand Up @@ -56,10 +56,10 @@ require (
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cosmos/cosmos-db v1.0.2 // indirect
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179 // indirect
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/dot v1.6.1 // indirect
github.com/emicklei/dot v1.6.2 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions server/v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o=
github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I=
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179 h1:wmwDn7V3RodN9auB3FooSQxs46nHVE3u0mb87TJkZFE=
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw=
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e h1:5bxw1E0peLMrr8ZO9mYT0d9sxy0WgR1ZEWb92yjKnnk=
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw=
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
Expand All @@ -69,8 +69,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/dot v1.6.1 h1:ujpDlBkkwgWUY+qPId5IwapRW/xEoligRSYjioR6DFI=
github.com/emicklei/dot v1.6.1/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A=
github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
Expand Down
4 changes: 2 additions & 2 deletions simapp/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.22.2
require (
cosmossdk.io/api v0.7.5
cosmossdk.io/client/v2 v2.0.0-00010101000000-000000000000
cosmossdk.io/core v0.12.1-0.20231114100755-569e3ff6a0d7
cosmossdk.io/core v0.12.1-0.20240725072823-6a2d039e1212
cosmossdk.io/depinject v1.0.0
cosmossdk.io/log v1.3.1
cosmossdk.io/math v1.3.0
Expand Down Expand Up @@ -93,7 +93,7 @@ require (
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/gogoproto v1.5.0 // indirect
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179 // indirect
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
github.com/creachadair/atomicfile v0.3.4 // indirect
Expand Down
4 changes: 2 additions & 2 deletions simapp/v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o=
github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I=
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179 h1:wmwDn7V3RodN9auB3FooSQxs46nHVE3u0mb87TJkZFE=
github.com/cosmos/iavl v1.2.1-0.20240725141113-7adc688cf179/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw=
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e h1:5bxw1E0peLMrr8ZO9mYT0d9sxy0WgR1ZEWb92yjKnnk=
github.com/cosmos/iavl v1.2.1-0.20240731145221-594b181f427e/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw=
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo=
Expand Down
52 changes: 42 additions & 10 deletions store/v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@ The `store` package contains the implementation of store/v2, which is the SDK's
abstraction around managing historical and committed state. See [ADR-065](../docs/architecture/adr-065-store-v2.md)
and [Store v2 Design](https://docs.google.com/document/d/1l6uXIjTPHOOWM5N4sUUmUfCZvePoa5SNfIEtmgvgQSU/edit#heading=h.nz8dqy6wa4g1) for a high-level overview of the design and rationale.

## Migration

<!-- TODO -->

## Pruning

The `root.Store` is NOT responsible for pruning. Rather, pruning is the responsibility
of the underlying SS and SC layers. This means pruning can be implementation specific,
such as being synchronous or asynchronous.

## Usage

The `store` package contains a `root.Store` type which is intended to act as an
Expand All @@ -29,3 +19,45 @@ from the perspective of `root.Store`, there is no notion of multi or single tree
rather these are implementation details of SS and SC. For SS, we utilize store keys
to namespace raw key/value pairs. For SC, we utilize an abstraction, `commitment.CommitStore`,
to map store keys to a commitment trees.

## Upgrades

The `LoadVersionAndUpgrade` API of the `root.store` allows for adding or removing
store keys. This is useful for upgrading the chain with new modules or removing
old ones. The `Rename` feature is not supported in store/v2.

```mermaid
sequenceDiagram
participant S as Store
participant SS as StateStorage
participant SC as StateCommitment
alt SC is a UpgradeableStore
S->>SC: LoadVersionAndUpgrade
SC->>SC: Mount new store keys
SC->>SC: Prune removed store keys
end
SC->>S: LoadVersion Result
alt SS is a UpgradableDatabase
S->>SS: PruneStoreKeys
end
```

`Prune store keys` does not remove the data from the SC and SS instantly. It only
marks the store keys as pruned. The actual data removal is done by the pruning
process of the underlying SS and SC.

## Migration

<!-- TODO -->

## Pruning

The `root.Store` is NOT responsible for pruning. Rather, pruning is the responsibility
of the underlying SS and SC layers. This means pruning can be implementation specific,
such as being synchronous or asynchronous.



## Test Coverage

The test coverage of the following logical components should be over 60%:
5 changes: 3 additions & 2 deletions store/v2/commitment/iavl/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ func (t *IavlTree) Get(version uint64, key []byte) ([]byte, error) {
}

// GetLatestVersion returns the latest version of the tree.
func (t *IavlTree) GetLatestVersion() uint64 {
return uint64(t.tree.Version())
func (t *IavlTree) GetLatestVersion() (uint64, error) {
v, err := t.tree.GetLatestVersion()
return uint64(v), err
}

// SetInitialVersion sets the initial version of the database.
Expand Down
31 changes: 23 additions & 8 deletions store/v2/commitment/iavl/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@ import (

func TestCommitterSuite(t *testing.T) {
s := &commitment.CommitStoreTestSuite{
NewStore: func(db corestore.KVStoreWithBatch, storeKeys []string, logger corelog.Logger) (*commitment.CommitStore, error) {
NewStore: func(db corestore.KVStoreWithBatch, storeKeys, oldStoreKeys []string, logger corelog.Logger) (*commitment.CommitStore, error) {
multiTrees := make(map[string]commitment.Tree)
cfg := DefaultConfig()
for _, storeKey := range storeKeys {
mountTreeFn := func(storeKey string) (commitment.Tree, error) {
prefixDB := dbm.NewPrefixDB(db, []byte(storeKey))
multiTrees[storeKey] = NewIavlTree(prefixDB, logger, cfg)
return NewIavlTree(prefixDB, logger, cfg), nil
}
for _, storeKey := range storeKeys {
multiTrees[storeKey], _ = mountTreeFn(storeKey)
}
return commitment.NewCommitStore(multiTrees, db, logger)
oldTrees := make(map[string]commitment.Tree)
for _, storeKey := range oldStoreKeys {
oldTrees[storeKey], _ = mountTreeFn(storeKey)
}

return commitment.NewCommitStore(multiTrees, oldTrees, db, logger)
},
}

Expand All @@ -41,7 +49,8 @@ func TestIavlTree(t *testing.T) {
tree := generateTree()
require.NotNil(t, tree)

initVersion := tree.GetLatestVersion()
initVersion, err := tree.GetLatestVersion()
require.NoError(t, err)
require.Equal(t, uint64(0), initVersion)

// write a batch of version 1
Expand All @@ -51,14 +60,18 @@ func TestIavlTree(t *testing.T) {

workingHash := tree.WorkingHash()
require.NotNil(t, workingHash)
require.Equal(t, uint64(0), tree.GetLatestVersion())
v, err := tree.GetLatestVersion()
require.NoError(t, err)
require.Equal(t, uint64(0), v)

// commit the batch
commitHash, version, err := tree.Commit()
require.NoError(t, err)
require.Equal(t, version, uint64(1))
require.Equal(t, workingHash, commitHash)
require.Equal(t, uint64(1), tree.GetLatestVersion())
v, err = tree.GetLatestVersion()
require.NoError(t, err)
require.Equal(t, uint64(1), v)

// ensure we can get expected values
bz, err := tree.Get(1, []byte("key1"))
Expand Down Expand Up @@ -100,7 +113,9 @@ func TestIavlTree(t *testing.T) {
// prune version 1
err = tree.Prune(1)
require.NoError(t, err)
require.Equal(t, uint64(3), tree.GetLatestVersion())
v, err = tree.GetLatestVersion()
require.NoError(t, err)
require.Equal(t, uint64(3), v)
// async pruning check
checkErr := func() bool {
if _, err := tree.tree.LoadVersion(1); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions store/v2/commitment/mem/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func (t *Tree) Remove(key []byte) error {
return t.MemDB.Delete(key)
}

func (t *Tree) GetLatestVersion() uint64 {
return 0
func (t *Tree) GetLatestVersion() (uint64, error) {
return 0, nil
}

func (t *Tree) Hash() []byte {
Expand Down
Loading

0 comments on commit 6d4097b

Please sign in to comment.