Skip to content

Commit 89728fc

Browse files
committed
fix get
1 parent eab7c04 commit 89728fc

File tree

4 files changed

+45
-16
lines changed

4 files changed

+45
-16
lines changed

iavl/cli.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
decode_fast_node, diff_iterators, encode_stdint,
1414
fast_node_key, get_node, get_root_node,
1515
iavl_latest_version, iter_fast_nodes, iter_iavl_tree,
16-
load_commit_infos, root_key, store_prefix)
16+
legacy_root_key, load_commit_infos, node_key, root_key,
17+
store_prefix)
1718

1819

1920
@click.group
@@ -43,7 +44,9 @@ def root_hash(db, store: List[str], version: Optional[int]):
4344
for s in store:
4445
if version is None:
4546
version = iavl_latest_version(db, s)
46-
bz = db.get(store_prefix(s) + root_key(version))
47+
bz = db.get(store_prefix(s) + node_key(root_key(version)))
48+
if not bz:
49+
bz = db.get(store_prefix(s) + legacy_root_key(version))
4750
print(f"{s}: {binascii.hexlify(bz or b'').decode()}")
4851

4952

iavl/iavl.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import rocksdb
1111

1212
from .utils import (ROOT_KEY_PREFIX, GetNode, PersistedNode, encode_bytes,
13-
node_key, root_key, visit_iavl_nodes)
13+
legacy_node_key, root_key, visit_iavl_nodes)
1414

1515
NodeRef = Union[bytes, "Node"]
1616

@@ -35,7 +35,7 @@ def get(self, hash: bytes) -> Optional[PersistedNode]:
3535
try:
3636
return self.cache[hash]
3737
except KeyError:
38-
bz = self.db.get(self.prefix + node_key(hash))
38+
bz = self.db.get(self.prefix + legacy_node_key(hash))
3939
if bz is None:
4040
return
4141
node = PersistedNode.decode(bz, hash)
@@ -52,7 +52,7 @@ def batch_remove_node(self, hash: bytes):
5252
"remove node"
5353
if self.batch is None:
5454
self.batch = rocksdb.WriteBatch()
55-
self.batch.delete(node_key(hash))
55+
self.batch.delete(legacy_node_key(hash))
5656
self.cache.pop(hash, None)
5757

5858
def batch_remove_root_hash(self, version: int):
@@ -64,7 +64,7 @@ def batch_set_node(self, hash: bytes, node: PersistedNode):
6464
if self.batch is None:
6565
self.batch = rocksdb.WriteBatch()
6666
self.cache[hash] = node
67-
self.batch.put(node_key(hash), node.encode())
67+
self.batch.put(legacy_node_key(hash), node.encode())
6868

6969
def batch_set_root_hash(self, version: int, hash: bytes):
7070
if self.batch is None:

iavl/utils.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import hashlib
2+
import struct
23
import itertools
34
from collections.abc import Iterator
45
from typing import Callable, List, NamedTuple, Optional, Tuple
@@ -11,9 +12,10 @@
1112
EMPTY_HASH = hashlib.sha256().digest()
1213
FAST_KEY_PREFIX = b"f"
1314
METADATA_KEY_PREFIX = b"m"
14-
NODE_KEY_PREFIX = b"n"
15+
NODE_KEY_PREFIX = b"s"
1516
ORPHAN_KEY_PREFIX = b"o"
1617
ROOT_KEY_PREFIX = b"r"
18+
LEGACY_NODE_KEY_PREFIX = b"n"
1719
GetNode = Callable[bytes, Optional["PersistedNode"]]
1820

1921

@@ -131,13 +133,33 @@ def prefix_iteritems(
131133

132134

133135
def root_key(v: int) -> bytes:
136+
return struct.pack(">qI", v, 1)
137+
138+
139+
def legacy_root_key(v: int) -> bytes:
134140
return ROOT_KEY_PREFIX + v.to_bytes(8, "big")
135141

136142

137143
def node_key(hash: bytes) -> bytes:
144+
if len(hash) != 12:
145+
raise ValueError("Key must be 12 bytes")
138146
return NODE_KEY_PREFIX + hash
139147

140148

149+
def legacy_node_key(hash: bytes) -> bytes:
150+
return LEGACY_NODE_KEY_PREFIX + hash
151+
152+
153+
def parse_node_key(key: bytes) -> tuple[int, int]:
154+
if not key.startswith(NODE_KEY_PREFIX):
155+
raise ValueError("Key must start with root prefix 's'")
156+
key = key[len(NODE_KEY_PREFIX):]
157+
if len(key) != 12:
158+
raise ValueError("Key must be 12 bytes after prefix")
159+
version, nonce = struct.unpack(">qI", key)
160+
return version, nonce
161+
162+
141163
def fast_node_key(key: bytes) -> bytes:
142164
return FAST_KEY_PREFIX + key
143165

@@ -246,10 +268,11 @@ def decode_fast_node(bz: bytes) -> (int, bytes, int):
246268

247269

248270
def get_node(
249-
db: DBM, hash: bytes, store: Optional[str] = None
271+
db: DBM, hash: bytes, store: Optional[str] = None, legacy=False,
250272
) -> Optional[PersistedNode]:
251-
prefix = store_prefix(store) if store is not None else b""
252-
bz = db.get(prefix + node_key(hash))
273+
prefix = store_prefix(store) if store else b""
274+
key = legacy_node_key(hash) if legacy else node_key(hash)
275+
bz = db.get(prefix + key)
253276
if not bz:
254277
return
255278
node, _ = decode_node(bz, hash)
@@ -259,10 +282,13 @@ def get_node(
259282
def get_root_node(
260283
db: DBM, version: int, store: Optional[str] = None
261284
) -> Optional[PersistedNode]:
262-
prefix = store_prefix(store) if store is not None else b""
263-
hash = db.get(prefix + root_key(version))
285+
prefix = store_prefix(store) if store else b""
286+
hash = db.get(prefix + node_key(root_key(version)))
264287
if not hash:
265-
return
288+
hash = db.get(prefix + legacy_root_key(version))
289+
if not hash:
290+
return
291+
return get_node(db, hash, store, legacy=True)
266292
return get_node(db, hash, store)
267293

268294

@@ -312,7 +338,7 @@ def iter_iavl_tree(
312338
prefix = store_prefix(store) if store is not None else b""
313339

314340
def get_node(hash: bytes) -> PersistedNode:
315-
n, _ = decode_node(db.get(prefix + node_key(hash)), hash)
341+
n, _ = decode_node(db.get(prefix + legacy_node_key(hash)), hash)
316342
return n
317343

318344
def prune_check(node: PersistedNode) -> (bool, bool):

iavl/visualize.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from hexbytes import HexBytes
66

77
from .iavl import NodeDB
8-
from .utils import PersistedNode, decode_node, node_key
8+
from .utils import PersistedNode, decode_node, legacy_node_key
99

1010

1111
def label(node: PersistedNode):
@@ -26,7 +26,7 @@ def visualize_iavl(
2626
g = Digraph(comment="IAVL Tree")
2727

2828
def get_node(hash: bytes) -> PersistedNode:
29-
n, _ = decode_node(db.get(prefix + node_key(hash)), hash)
29+
n, _ = decode_node(db.get(prefix + legacy_node_key(hash)), hash)
3030
return n
3131

3232
def vis_node(hash: bytes, n: PersistedNode):

0 commit comments

Comments
 (0)