diff --git a/nimbus/db/aristo/aristo_blobify.nim b/nimbus/db/aristo/aristo_blobify.nim index 52b65a1dd..98d287ee4 100644 --- a/nimbus/db/aristo/aristo_blobify.nim +++ b/nimbus/db/aristo/aristo_blobify.nim @@ -68,10 +68,12 @@ proc deblobify*[T: uint64|VertexID](data: openArray[byte], _: type T): Result[T, if data.len < 1 or data.len > 8: return err(Deblob64LenUnsupported) - var tmp: array[8, byte] - discard tmp.toOpenArray(8 - data.len, 7).copyFrom(data) + var tmp = 0'u64 + let start = 8 - data.len + for i in 0.. 32: diff --git a/nimbus/db/aristo/aristo_desc/desc_nibbles.nim b/nimbus/db/aristo/aristo_desc/desc_nibbles.nim index 200b600a8..beb10324d 100644 --- a/nimbus/db/aristo/aristo_desc/desc_nibbles.nim +++ b/nimbus/db/aristo/aristo_desc/desc_nibbles.nim @@ -78,9 +78,9 @@ func slice*(r: NibblesBuf, ibegin: int, iend = -1): NibblesBuf {.noinit.} = result.iend = e.int8 func replaceSuffix*(r: NibblesBuf, suffix: NibblesBuf): NibblesBuf = - for i in 0.. 0: result.isLeaf = (r[0] and 0x20) != 0 let hasOddLen = (r[0] and 0x10) != 0 - var i = 0'i8 - if hasOddLen: - result.nibbles[0] = r[0] and 0x0f - i += 1 + result.nibbles.iend = + if hasOddLen: + result.nibbles.bytes[0] = r[0] shl 4 - for j in 1 ..< r.len: - if i >= 64: - break - result.nibbles[i] = r[j] shr 4 - result.nibbles[i + 1] = r[j] and 0x0f - i += 2 + let bytes = min(31, r.len - 1) + for j in 0 ..< bytes: + result.nibbles.bytes[j] = result.nibbles.bytes[j] or r[j + 1] shr 4 + result.nibbles.bytes[j + 1] = r[j + 1] shl 4 - result.nibbles.iend = i + int8(bytes) * 2 + 1 + else: + let bytes = min(32, r.len - 1) + assign(result.nibbles.bytes.toOpenArray(0, bytes - 1), r.toOpenArray(1, bytes)) + int8(bytes) * 2 else: result.isLeaf = false + result.nibbles.iend = 0 func `&`*(a, b: NibblesBuf): NibblesBuf {.noinit.} = + result.ibegin = 0 for i in 0 ..< a.len: result[i] = a[i] diff --git a/tests/test_aristo.nim b/tests/test_aristo.nim index 3846fc410..b3ef861fe 100644 --- a/tests/test_aristo.nim +++ b/tests/test_aristo.nim @@ -20,6 +20,7 @@ import ./replay/pp, ./test_aristo/test_blobify, ./test_aristo/test_merge_proof, + ./test_aristo/test_nibbles, ./test_aristo/test_portal_proof, ./test_aristo/test_compute, ./test_aristo/[ diff --git a/tests/test_aristo/test_nibbles.nim b/tests/test_aristo/test_nibbles.nim new file mode 100644 index 000000000..8fcaffe8a --- /dev/null +++ b/tests/test_aristo/test_nibbles.nim @@ -0,0 +1,86 @@ +# Nimbus +# Copyright (c) 2024 Status Research & Development GmbH +# Licensed under either of +# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or +# http://www.apache.org/licenses/LICENSE-2.0) +# * MIT license ([LICENSE-MIT](LICENSE-MIT) or +# http://opensource.org/licenses/MIT) +# at your option. This file may not be copied, modified, or +# distributed except according to those terms. + +{.used.} + +import + std/sequtils, + stew/byteutils, + unittest2, + ../../nimbus/db/aristo/aristo_desc/desc_nibbles + +suite "Nibbles": + test "trivial cases": + block: + let n = NibblesBuf.fromBytes([]) + check: + n.len == 0 + block: + let n = NibblesBuf.fromBytes([byte 0x10]) + check: + n.len == 2 + n[0] == 1 + n[1] == 0 + $n.slice(1) == "0" + $n.slice(2) == "" + + block: + let n = NibblesBuf.fromBytes(repeat(byte 0x12, 32)) + check: + n.len == 64 + n[0] == 1 + n[63] == 2 + + block: + let n = NibblesBuf.fromBytes(repeat(byte 0x12, 33)) + check: + n.len == 64 + n[0] == 1 + n[63] == 2 + + test "to/from hex encoding": + block: + let n = NibblesBuf.fromBytes([byte 0x12, 0x34, 0x56]) + + let + he = n.toHexPrefix(true) + ho = n.slice(1).toHexPrefix(true) + + check: + NibblesBuf.fromHexPrefix(he.data()) == (true, n) + NibblesBuf.fromHexPrefix(ho.data()) == (true, n.slice(1)) + block: + let n = NibblesBuf.fromBytes(repeat(byte 0x12, 32)) + + let + he = n.toHexPrefix(true) + ho = n.slice(1).toHexPrefix(true) + + check: + NibblesBuf.fromHexPrefix(he.data()) == (true, n) + NibblesBuf.fromHexPrefix(ho.data()) == (true, n.slice(1)) + + NibblesBuf.fromHexPrefix(@(he.data()) & @[byte 1]) == (true, n) + NibblesBuf.fromHexPrefix(@(ho.data()) & @[byte 1]) == (true, n.slice(1)) + + test "long": + let n = NibblesBuf.fromBytes( + hexToSeqByte("0100000000000000000000000000000000000000000000000000000000000000") + ) + + check $n == "0100000000000000000000000000000000000000000000000000000000000000" + check $n.slice(1) == "100000000000000000000000000000000000000000000000000000000000000" + + let + he = n.toHexPrefix(true) + ho = n.slice(1).toHexPrefix(true) + check: + NibblesBuf.fromHexPrefix(he.data()) == (true, n) + NibblesBuf.fromHexPrefix(ho.data()) == (true, n.slice(1))