Skip to content

Commit a3f1cf2

Browse files
committed
feat!: adapt iavlx to store
1 parent a50376f commit a3f1cf2

File tree

8 files changed

+943
-231
lines changed

8 files changed

+943
-231
lines changed

iavl/commit_multi_tree.go

Lines changed: 300 additions & 82 deletions
Large diffs are not rendered by default.

iavl/commit_tree.go

Lines changed: 186 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ package iavlx
22

33
import (
44
"fmt"
5-
"log/slog"
5+
"io"
66
"sync"
77
"sync/atomic"
8+
9+
"cosmossdk.io/log"
10+
pruningtypes "cosmossdk.io/store/pruning/types"
11+
storetypes "cosmossdk.io/store/types"
812
)
913

1014
type CommitTree struct {
@@ -25,10 +29,186 @@ type CommitTree struct {
2529

2630
pendingOrphans [][]NodeID
2731

28-
logger *slog.Logger
32+
logger log.Logger
33+
34+
commitCtx *commitContext
35+
lastCommitId storetypes.CommitID
36+
workingCommitId storetypes.CommitID
37+
}
38+
39+
func (c *CommitTree) Root() *NodePointer {
40+
return c.root
41+
}
42+
43+
func (c *CommitTree) ApplyChanges(origRoot, newRoot *NodePointer, updateBatch KVUpdateBatch) error {
44+
// TODO check channel errors
45+
c.writeMutex.Lock()
46+
defer c.writeMutex.Unlock()
47+
48+
if updateBatch.Version != c.stagedVersion() {
49+
return fmt.Errorf("tree version %d does not match staged version %d", updateBatch.Version, c.stagedVersion())
50+
}
51+
if origRoot != c.root {
52+
// TODO find a way to apply the changes incrementally when roots don't match
53+
return fmt.Errorf("tree original root does not match current root")
54+
}
55+
c.root = newRoot
56+
c.pendingOrphans = append(c.pendingOrphans, updateBatch.Orphans...)
57+
58+
if c.writeWal {
59+
c.walChan <- updateBatch.Updates
60+
}
61+
62+
// TODO prevent further writes to the branch tree
63+
64+
return nil
65+
}
66+
67+
func (c *CommitTree) Commit() storetypes.CommitID {
68+
commitId, err := c.commit()
69+
if err != nil {
70+
panic(fmt.Sprintf("failed to commit: %v", err))
71+
}
72+
return commitId
73+
}
74+
75+
func (c *CommitTree) commit() (storetypes.CommitID, error) {
76+
c.WorkingHash()
77+
commitId := c.workingCommitId
78+
79+
stagedVersion := c.stagedVersion()
80+
if c.writeWal {
81+
// wait for WAL write to complete
82+
err := <-c.walDone
83+
if err != nil {
84+
return storetypes.CommitID{}, err
85+
}
86+
87+
err = c.store.WriteWALCommit(stagedVersion)
88+
if err != nil {
89+
return storetypes.CommitID{}, err
90+
}
91+
92+
c.reinitWalProc()
93+
}
94+
95+
err := c.store.SaveRoot(stagedVersion, c.root, c.commitCtx.leafNodeIdx, c.commitCtx.branchNodeIdx)
96+
if err != nil {
97+
return storetypes.CommitID{}, err
98+
}
99+
100+
c.store.MarkOrphans(stagedVersion, c.pendingOrphans)
101+
c.pendingOrphans = nil
102+
103+
// start eviction if needed
104+
c.startEvict(c.store.SavedVersion())
105+
106+
// cache the committed tree as the latest version
107+
c.latest.Store(c.root)
108+
c.version++
109+
c.lastCommitId = commitId
110+
c.commitCtx = nil
111+
112+
return commitId, nil
113+
}
114+
115+
func (c *CommitTree) LastCommitID() storetypes.CommitID {
116+
//TODO implement me
117+
panic("implement me")
118+
}
119+
120+
func (c *CommitTree) WorkingHash() []byte {
121+
if c.commitCtx != nil {
122+
return c.workingCommitId.Hash
123+
}
124+
125+
c.writeMutex.Lock()
126+
defer c.writeMutex.Unlock()
127+
128+
if c.writeWal {
129+
close(c.walChan)
130+
}
131+
132+
var hash []byte
133+
savedVersion := c.store.SavedVersion()
134+
stagedVersion := c.stagedVersion()
135+
c.commitCtx = &commitContext{
136+
version: stagedVersion,
137+
savedVersion: savedVersion,
138+
}
139+
if c.root == nil {
140+
hash = emptyHash
141+
} else {
142+
// compute hash and assign node IDs
143+
var err error
144+
hash, err = commitTraverse(c.commitCtx, c.root, 0)
145+
if err != nil {
146+
panic(fmt.Sprintf("failed to compute working hash: %v", err))
147+
}
148+
}
149+
150+
c.workingCommitId = storetypes.CommitID{
151+
Version: int64(stagedVersion),
152+
Hash: hash,
153+
}
154+
return hash
155+
}
156+
157+
func (c *CommitTree) SetPruning(pruningtypes.PruningOptions) {
158+
//TODO implement me
159+
panic("implement me")
160+
}
161+
162+
func (c *CommitTree) GetPruning() pruningtypes.PruningOptions {
163+
//TODO implement me
164+
panic("implement me")
165+
}
166+
167+
func (c *CommitTree) GetStoreType() storetypes.StoreType {
168+
//TODO implement me
169+
panic("implement me")
29170
}
30171

31-
func NewCommitTree(dir string, opts Options, logger *slog.Logger) (*CommitTree, error) {
172+
func (c *CommitTree) CacheWrap() storetypes.CacheWrap {
173+
return NewTree(c, c.stagedVersion(), c.zeroCopy)
174+
}
175+
176+
func (c *CommitTree) CacheWrapWithTrace(w io.Writer, tc storetypes.TraceContext) storetypes.CacheWrap {
177+
// TODO support tracing
178+
return c.CacheWrap()
179+
}
180+
181+
func (c *CommitTree) Get(key []byte) []byte {
182+
//TODO implement me
183+
panic("implement me")
184+
}
185+
186+
func (c *CommitTree) Has(key []byte) bool {
187+
//TODO implement me
188+
panic("implement me")
189+
}
190+
191+
func (c *CommitTree) Set(key, value []byte) {
192+
//TODO implement me
193+
panic("implement me")
194+
}
195+
196+
func (c *CommitTree) Delete(key []byte) {
197+
//TODO implement me
198+
panic("implement me")
199+
}
200+
201+
func (c *CommitTree) Iterator(start, end []byte) storetypes.Iterator {
202+
//TODO implement me
203+
panic("implement me")
204+
}
205+
206+
func (c *CommitTree) ReverseIterator(start, end []byte) storetypes.Iterator {
207+
//TODO implement me
208+
panic("implement me")
209+
}
210+
211+
func NewCommitTree(dir string, opts Options, logger log.Logger) (*CommitTree, error) {
32212
ts, err := NewTreeStore(dir, opts, logger)
33213
if err != nil {
34214
return nil, fmt.Errorf("failed to create tree store: %w", err)
@@ -74,35 +254,6 @@ func (c *CommitTree) reinitWalProc() {
74254
}()
75255
}
76256

77-
func (c *CommitTree) Branch() *Tree {
78-
return NewTree(c.root, NewKVUpdateBatch(c.stagedVersion()), c.zeroCopy)
79-
}
80-
81-
func (c *CommitTree) Apply(tree *Tree) error {
82-
// TODO check channel errors
83-
c.writeMutex.Lock()
84-
defer c.writeMutex.Unlock()
85-
86-
if tree.updateBatch.Version != c.stagedVersion() {
87-
return fmt.Errorf("tree version %d does not match staged version %d", tree.updateBatch.Version, c.stagedVersion())
88-
}
89-
if tree.origRoot != c.root {
90-
// TODO find a way to apply the changes incrementally when roots don't match
91-
return fmt.Errorf("tree original root does not match current root")
92-
}
93-
c.root = tree.root
94-
batch := tree.updateBatch
95-
c.pendingOrphans = append(c.pendingOrphans, batch.Orphans...)
96-
97-
if c.writeWal {
98-
c.walChan <- batch.Updates
99-
}
100-
101-
// TODO prevent further writes to the branch tree
102-
103-
return nil
104-
}
105-
106257
func (c *CommitTree) startEvict(evictVersion uint32) {
107258
if c.evictorRunning {
108259
// eviction in progress
@@ -130,65 +281,6 @@ func (c *CommitTree) startEvict(evictVersion uint32) {
130281
}()
131282
}
132283

133-
func (c *CommitTree) Commit() ([]byte, error) {
134-
c.writeMutex.Lock()
135-
defer c.writeMutex.Unlock()
136-
137-
if c.writeWal {
138-
close(c.walChan)
139-
}
140-
141-
var hash []byte
142-
savedVersion := c.store.SavedVersion()
143-
stagedVersion := c.stagedVersion()
144-
commitCtx := &commitContext{
145-
version: stagedVersion,
146-
savedVersion: savedVersion,
147-
}
148-
if c.root == nil {
149-
hash = emptyHash
150-
} else {
151-
// compute hash and assign node IDs
152-
var err error
153-
hash, err = commitTraverse(commitCtx, c.root, 0)
154-
if err != nil {
155-
return nil, err
156-
}
157-
}
158-
159-
if c.writeWal {
160-
// wait for WAL write to complete
161-
err := <-c.walDone
162-
if err != nil {
163-
return nil, err
164-
}
165-
166-
err = c.store.WriteWALCommit(stagedVersion)
167-
if err != nil {
168-
return nil, err
169-
}
170-
171-
c.reinitWalProc()
172-
}
173-
174-
err := c.store.SaveRoot(stagedVersion, c.root, commitCtx.leafNodeIdx, commitCtx.branchNodeIdx)
175-
if err != nil {
176-
return nil, err
177-
}
178-
179-
c.store.MarkOrphans(stagedVersion, c.pendingOrphans)
180-
c.pendingOrphans = nil
181-
182-
// start eviction if needed
183-
c.startEvict(savedVersion)
184-
185-
// cache the committed tree as the latest version
186-
c.latest.Store(c.root)
187-
c.version++
188-
189-
return hash, nil
190-
}
191-
192284
func (c *CommitTree) Close() error {
193285
if c.walChan != nil {
194286
close(c.walChan)
@@ -268,3 +360,6 @@ func evictTraverse(np *NodePointer, depth, evictionDepth uint8, evictVersion uin
268360
count += evictTraverse(memNode.right, depth+1, evictionDepth, evictVersion)
269361
return
270362
}
363+
364+
var _ storetypes.CommitKVStore = &CommitTree{}
365+
var _ parentTree = &CommitTree{}

iavl/go.mod

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
cosmossdk.io/api v0.9.2
77
cosmossdk.io/core v1.0.0
88
cosmossdk.io/log v1.6.1
9+
cosmossdk.io/store v1.1.2
910
github.com/alitto/pond/v2 v2.5.0
1011
github.com/cosmos/iavl v1.3.5
1112
github.com/edsrzf/mmap-go v1.2.0
@@ -16,25 +17,59 @@ require (
1617
)
1718

1819
require (
20+
cosmossdk.io/errors v1.0.2 // indirect
21+
cosmossdk.io/math v1.5.1 // indirect
22+
github.com/DataDog/zstd v1.5.6 // indirect
23+
github.com/beorn7/perks v1.0.1 // indirect
1924
github.com/bytedance/sonic v1.14.0 // indirect
2025
github.com/bytedance/sonic/loader v0.3.0 // indirect
26+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2127
github.com/cloudwego/base64x v0.1.5 // indirect
28+
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
29+
github.com/cockroachdb/errors v1.11.3 // indirect
30+
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
31+
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
32+
github.com/cockroachdb/pebble v1.1.2 // indirect
33+
github.com/cockroachdb/redact v1.1.5 // indirect
34+
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
35+
github.com/cometbft/cometbft v0.38.17 // indirect
36+
github.com/cosmos/cosmos-db v1.1.1 // indirect
2237
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
2338
github.com/cosmos/gogoproto v1.7.0 // indirect
24-
github.com/cosmos/ics23/go v0.10.0 // indirect
25-
github.com/davecgh/go-spew v1.1.1 // indirect
39+
github.com/cosmos/ics23/go v0.11.0 // indirect
40+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
41+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
2642
github.com/emicklei/dot v1.6.2 // indirect
43+
github.com/getsentry/sentry-go v0.27.0 // indirect
2744
github.com/gogo/protobuf v1.3.2 // indirect
45+
github.com/golang/protobuf v1.5.4 // indirect
2846
github.com/golang/snappy v0.0.4 // indirect
29-
github.com/google/btree v1.1.2 // indirect
47+
github.com/google/btree v1.1.3 // indirect
3048
github.com/google/go-cmp v0.7.0 // indirect
49+
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
50+
github.com/hashicorp/go-metrics v0.5.4 // indirect
51+
github.com/hashicorp/golang-lru v1.0.2 // indirect
52+
github.com/klauspost/compress v1.17.9 // indirect
3153
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
54+
github.com/kr/pretty v0.3.1 // indirect
55+
github.com/kr/text v0.2.0 // indirect
56+
github.com/linxGnu/grocksdb v1.8.14 // indirect
3257
github.com/mattn/go-colorable v0.1.14 // indirect
3358
github.com/mattn/go-isatty v0.0.20 // indirect
59+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
60+
github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae // indirect
61+
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
3462
github.com/pkg/errors v0.9.1 // indirect
35-
github.com/pmezard/go-difflib v1.0.0 // indirect
63+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
64+
github.com/prometheus/client_golang v1.20.5 // indirect
65+
github.com/prometheus/client_model v0.6.1 // indirect
66+
github.com/prometheus/common v0.62.0 // indirect
67+
github.com/prometheus/procfs v0.15.1 // indirect
68+
github.com/rogpeppe/go-internal v1.14.1 // indirect
3669
github.com/rs/zerolog v1.34.0 // indirect
37-
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
70+
github.com/sasha-s/go-deadlock v0.3.5 // indirect
71+
github.com/spf13/cast v1.7.1 // indirect
72+
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
3873
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
3974
golang.org/x/arch v0.17.0 // indirect
4075
golang.org/x/crypto v0.37.0 // indirect

0 commit comments

Comments
 (0)