Skip to content

Commit 926000f

Browse files
yihuangmmsqe
andauthored
Problem: memiavl minQueryState logic is unnesserary (#1064)
* Problem: memiavl minQueryState logic is unnesserary Solution: - simplify the logic, make snapshot-keep-recent defaults to 1, which is enough for ibc relayers to work. * Update CHANGELOG.md Signed-off-by: yihuang <huang@crypto.com> * simpliy ApplyChangeSet * Update memiavl/multitree.go Co-authored-by: mmsqe <mavis@crypto.com> Signed-off-by: yihuang <huang@crypto.com> * fix --------- Signed-off-by: yihuang <huang@crypto.com> Co-authored-by: mmsqe <mavis@crypto.com>
1 parent f774da9 commit 926000f

File tree

6 files changed

+29
-64
lines changed

6 files changed

+29
-64
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
- [#1034](https://github.com/crypto-org-chain/cronos/pull/1034) Support memiavl snapshot strategy configuration.
4747
- [#1035](https://github.com/crypto-org-chain/cronos/pull/1035) Support caching in memiavl directly, ignore inter-block cache silently.
4848
- [#1050](https://github.com/crypto-org-chain/cronos/pull/1050) nativebyteorder mode will check endianness on startup, binaries are built with nativebyteorder by default.
49+
- [#1064](https://github.com/crypto-org-chain/cronos/pull/1064) Simplify memiavl snapshot switching.
4950

5051
*April 13, 2023*
5152

app/config/config.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ type MemIAVLConfig struct {
2222
// AsyncCommitBuffer defines the size of asynchronous commit queue, this greatly improve block catching-up
2323
// performance, -1 means synchronous commit.
2424
AsyncCommitBuffer int `mapstructure:"async-commit-buffer"`
25-
// SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are taken.
25+
// SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are
26+
// taken, defaults to 1 to make sure ibc relayers work.
2627
SnapshotKeepRecent uint32 `mapstructure:"snapshot-keep-recent"`
2728
// SnapshotInterval defines the block interval the memiavl snapshot is taken, default to 1000.
2829
SnapshotInterval uint32 `mapstructure:"snapshot-interval"`
@@ -32,8 +33,9 @@ type MemIAVLConfig struct {
3233

3334
func DefaultMemIAVLConfig() MemIAVLConfig {
3435
return MemIAVLConfig{
35-
CacheSize: DefaultCacheSize,
36-
SnapshotInterval: memiavl.DefaultSnapshotInterval,
37-
ZeroCopy: true,
36+
CacheSize: DefaultCacheSize,
37+
SnapshotInterval: memiavl.DefaultSnapshotInterval,
38+
ZeroCopy: true,
39+
SnapshotKeepRecent: 1,
3840
}
3941
}

app/config/toml.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ zero-copy = {{ .MemIAVL.ZeroCopy }}
1919
# performance, -1 means synchronous commit.
2020
async-commit-buffer = {{ .MemIAVL.AsyncCommitBuffer }}
2121
22-
# SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are taken.
22+
# SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are
23+
# taken, defaults to 1 to make sure ibc relayers work.
2324
snapshot-keep-recent = {{ .MemIAVL.SnapshotKeepRecent }}
2425
2526
# SnapshotInterval defines the block interval the memiavl snapshot is taken, default to 1000.

app/memiavl.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ func SetupMemIAVL(logger log.Logger, homePath string, appOpts servertypes.AppOpt
3333
ZeroCopy: cast.ToBool(appOpts.Get(FlagZeroCopy)),
3434
SnapshotKeepRecent: cast.ToUint32(appOpts.Get(FlagSnapshotKeepRecent)),
3535
SnapshotInterval: cast.ToUint32(appOpts.Get(FlagSnapshotInterval)),
36-
// make sure a few queryable states even with pruning="nothing", needed for ibc relayer to work.
37-
MinQueryStates: 3,
38-
CacheSize: cast.ToInt(appOpts.Get(FlagCacheSize)),
36+
CacheSize: cast.ToInt(appOpts.Get(FlagCacheSize)),
3937
})
4038
baseAppOptions = append([]func(*baseapp.BaseApp){setCMS(cms)}, baseAppOptions...)
4139
}

memiavl/db.go

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ type DB struct {
4545
snapshotInterval uint32
4646
// make sure only one snapshot rewrite is running
4747
pruneSnapshotLock sync.Mutex
48-
// might need to wait for a few blocks before actual snapshot switching.
49-
minQueryStates int
50-
pendingForSwitch *MultiTree
5148

5249
// invariant: the LastIndex always match the current version of MultiTree
5350
wal *wal.Log
@@ -83,8 +80,6 @@ type Options struct {
8380
AsyncCommitBuffer int
8481
// ZeroCopy if true, the get and iterator methods could return a slice pointing to mmaped blob files.
8582
ZeroCopy bool
86-
// for ibc relayer to work, we need to make sure at least a few queryable states exists even with pruning="nothing" setting.
87-
MinQueryStates int
8883
// CacheSize defines the cache's max entry size for each memiavl store.
8984
CacheSize int
9085
}
@@ -147,7 +142,6 @@ func Load(dir string, opts Options) (*DB, error) {
147142
walChanSize: opts.AsyncCommitBuffer,
148143
snapshotKeepRecent: opts.SnapshotKeepRecent,
149144
snapshotInterval: opts.SnapshotInterval,
150-
minQueryStates: opts.MinQueryStates,
151145
}
152146

153147
if db.logger == nil {
@@ -236,32 +230,21 @@ func (db *DB) checkBackgroundSnapshotRewrite() error {
236230
return fmt.Errorf("background snapshot rewriting failed: %w", result.err)
237231
}
238232

239-
db.pendingForSwitch = result.mtree
240-
default:
241-
}
242-
243-
if db.pendingForSwitch == nil {
244-
return nil
245-
}
246-
247-
// catchup the remaining wal
248-
if err := db.pendingForSwitch.CatchupWAL(db.wal, 0); err != nil {
249-
return fmt.Errorf("catchup failed: %w", err)
250-
}
233+
// catchup the remaining wal
234+
if err := result.mtree.CatchupWAL(db.wal, 0); err != nil {
235+
return fmt.Errorf("catchup failed: %w", err)
236+
}
251237

252-
// make sure there are at least a few queryable states after switch
253-
if db.pendingForSwitch.Version() < db.pendingForSwitch.SnapshotVersion()+int64(db.minQueryStates) {
254-
return nil
255-
}
238+
// do the switch
239+
if err := db.reloadMultiTree(result.mtree); err != nil {
240+
return fmt.Errorf("switch multitree failed: %w", err)
241+
}
242+
db.logger.Info("switched to new snapshot", "version", db.MultiTree.Version())
256243

257-
// do the switch
258-
if err := db.reloadMultiTree(db.pendingForSwitch); err != nil {
259-
return fmt.Errorf("switch multitree failed: %w", err)
244+
db.pruneSnapshots()
245+
default:
260246
}
261-
db.logger.Info("switched to new snapshot", "version", db.MultiTree.Version())
262247

263-
db.pendingForSwitch = nil
264-
db.pruneSnapshots()
265248
return nil
266249
}
267250

memiavl/multitree.go

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"cosmossdk.io/errors"
1313

1414
storetypes "github.com/cosmos/cosmos-sdk/store/types"
15-
"github.com/cosmos/iavl"
1615
"github.com/tidwall/wal"
1716
"golang.org/x/exp/slices"
1817
"golang.org/x/sync/errgroup"
@@ -253,47 +252,28 @@ func (t *MultiTree) ApplyUpgrades(upgrades []*TreeNameUpgrade) error {
253252
func (t *MultiTree) ApplyChangeSet(changeSets []*NamedChangeSet, updateCommitInfo bool) ([]byte, int64, error) {
254253
version := nextVersion(t.lastCommitInfo.Version, t.initialVersion)
255254

256-
var (
257-
infos []storetypes.StoreInfo
258-
csIndex int
259-
)
260-
for _, entry := range t.trees {
261-
var changeSet iavl.ChangeSet
255+
for _, cs := range changeSets {
256+
tree := t.trees[t.treesByName[cs.Name]].tree
262257

263-
if csIndex < len(changeSets) && entry.name == changeSets[csIndex].Name {
264-
changeSet = changeSets[csIndex].Changeset
265-
csIndex++
266-
}
267-
hash, v, err := entry.tree.ApplyChangeSet(changeSet, updateCommitInfo)
258+
_, v, err := tree.ApplyChangeSet(cs.Changeset, updateCommitInfo)
268259
if err != nil {
269260
return nil, 0, err
270261
}
271262
if v != version {
272263
return nil, 0, fmt.Errorf("multi tree version don't match(%d != %d)", v, version)
273264
}
274-
if updateCommitInfo {
275-
infos = append(infos, storetypes.StoreInfo{
276-
Name: entry.name,
277-
CommitId: storetypes.CommitID{
278-
Version: v,
279-
Hash: hash,
280-
},
281-
})
282-
}
283-
}
284-
285-
if csIndex != len(changeSets) {
286-
return nil, 0, fmt.Errorf("non-exhaustive change sets")
287265
}
288266

289267
t.lastCommitInfo.Version = version
290-
t.lastCommitInfo.StoreInfos = infos
291268

292269
var hash []byte
293270
if updateCommitInfo {
294-
hash = t.lastCommitInfo.Hash()
271+
hash = t.UpdateCommitInfo()
272+
} else {
273+
t.lastCommitInfo.StoreInfos = []storetypes.StoreInfo{}
295274
}
296-
return hash, t.lastCommitInfo.Version, nil
275+
276+
return hash, version, nil
297277
}
298278

299279
// UpdateCommitInfo update lastCommitInfo based on current status of trees.

0 commit comments

Comments
 (0)