Skip to content

Commit

Permalink
Refactor trie util helpers (#3534)
Browse files Browse the repository at this point in the history
* Rename nibblestoBytes to nibblesTypeToPackedBytes

* Rename function

* Fix function name

* Make nibblesToBytes return a byte array to conform to how bytesToNibbles returns one

* Fix lint issues

* Fix function name

* Fix lint issue

* update import

---------

Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com>
  • Loading branch information
scorbajio and acolytec3 authored Jul 24, 2024
1 parent 6a68531 commit da22a38
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 37 deletions.
4 changes: 2 additions & 2 deletions packages/trie/src/node/node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RLP } from '@ethereumjs/rlp'

import { addHexPrefix, removeHexPrefix } from '../util/hex.js'
import { nibblestoBytes } from '../util/nibbles.js'
import { nibblesTypeToPackedBytes } from '../util/nibbles.js'

import type { Nibbles } from '../types.js'

Expand Down Expand Up @@ -45,7 +45,7 @@ export class Node {
}

raw(): [Uint8Array, Uint8Array] {
return [nibblestoBytes(this.encodedKey()), this._value]
return [nibblesTypeToPackedBytes(this.encodedKey()), this._value]
}

serialize(): Uint8Array {
Expand Down
10 changes: 5 additions & 5 deletions packages/trie/src/proof/range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { equalsBytes } from '@ethereumjs/util'
import { createTrieFromProof } from '../index.js'
import { BranchNode, ExtensionNode, LeafNode } from '../node/index.js'
import { Trie } from '../trie.js'
import { nibblesCompare, nibblestoBytes } from '../util/nibbles.js'
import { nibblesCompare, nibblesTypeToPackedBytes } from '../util/nibbles.js'

import type { HashKeysFunction, Nibbles, TrieNode } from '../types.js'

Expand Down Expand Up @@ -439,7 +439,7 @@ export async function verifyRangeProof(
if (proof === null && firstKey === null && lastKey === null) {
const trie = new Trie({ useKeyHashingFunction })
for (let i = 0; i < keys.length; i++) {
await trie.put(nibblestoBytes(keys[i]), values[i])
await trie.put(nibblesTypeToPackedBytes(keys[i]), values[i])
}
if (!equalsBytes(rootHash, trie.root())) {
throw new Error('invalid all elements proof: root mismatch')
Expand All @@ -452,7 +452,7 @@ export async function verifyRangeProof(
if (keys.length === 0) {
const { trie, value } = await verifyProof(
rootHash,
nibblestoBytes(firstKey),
nibblesTypeToPackedBytes(firstKey),
proof,
useKeyHashingFunction
)
Expand All @@ -475,7 +475,7 @@ export async function verifyRangeProof(
if (keys.length === 1 && nibblesCompare(firstKey, lastKey) === 0) {
const { trie, value } = await verifyProof(
rootHash,
nibblestoBytes(firstKey),
nibblesTypeToPackedBytes(firstKey),
proof,
useKeyHashingFunction
)
Expand Down Expand Up @@ -513,7 +513,7 @@ export async function verifyRangeProof(

// Put all elements to the trie
for (let i = 0; i < keys.length; i++) {
await trie.put(nibblestoBytes(keys[i]), values[i])
await trie.put(nibblesTypeToPackedBytes(keys[i]), values[i])
}

// Compare rootHash
Expand Down
5 changes: 2 additions & 3 deletions packages/trie/src/trie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ import {
import { verifyRangeProof } from './proof/range.js'
import { ROOT_DB_KEY } from './types.js'
import { _walkTrie } from './util/asyncWalk.js'
import { nibbleTypeToPackedBytes } from './util/encoding.js'
import { bytesToNibbles, matchingNibbleLength } from './util/nibbles.js'
import { bytesToNibbles, matchingNibbleLength, nibblesTypeToPackedBytes } from './util/nibbles.js'
import { WalkController } from './util/walkController.js'

import type {
Expand Down Expand Up @@ -1239,7 +1238,7 @@ export class Trie {
let nextKey: string | null = null
await this.walkAllValueNodes(async (node: TrieNode, currentKey: number[]) => {
if (node instanceof LeafNode) {
const keyBytes = nibbleTypeToPackedBytes(currentKey.concat(node.key()))
const keyBytes = nibblesTypeToPackedBytes(currentKey.concat(node.key()))
if (!inRange) {
// Check if the key is already in the correct range.
if (bytesToBigInt(keyBytes) >= startKey) {
Expand Down
35 changes: 11 additions & 24 deletions packages/trie/src/util/encoding.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { hexToBytes, toBytes, unprefixedHexToBytes } from '@ethereumjs/util'
import { concatBytes, hexToBytes, toBytes, unprefixedHexToBytes } from '@ethereumjs/util'

import { nibblesTypeToPackedBytes } from './nibbles.js'

import type { Nibbles } from '../types.js'

Expand Down Expand Up @@ -32,10 +34,13 @@ export const hasTerminator = (nibbles: Uint8Array) => {
return nibbles.length > 0 && nibbles[nibbles.length - 1] === 16
}

export const nibblesToBytes = (nibbles: Uint8Array, bytes: Uint8Array) => {
export const nibblesToBytes = (nibbles: Uint8Array) => {
const bytes = new Uint8Array(nibbles.length / 2)
for (let bi = 0, ni = 0; ni < nibbles.length; bi += 1, ni += 2) {
bytes[bi] = (nibbles[ni] << 4) | nibbles[ni + 1]
}

return bytes
}

export const hexToKeybytes = (hex: Uint8Array) => {
Expand All @@ -45,10 +50,8 @@ export const hexToKeybytes = (hex: Uint8Array) => {
if (hex.length % 2 === 1) {
throw Error("Can't convert hex key of odd length")
}
const key = new Uint8Array(hex.length / 2)
nibblesToBytes(hex, key)

return key
return nibblesToBytes(hex)
}

// hex to compact
Expand All @@ -69,9 +72,9 @@ export const nibblesToCompactBytes = (nibbles: Uint8Array) => {
buf[0] |= nibbles[0]
nibbles = nibbles.subarray(1)
}

// create bytes out of the rest even nibbles
nibblesToBytes(nibbles, buf.subarray(1))
return buf
return concatBytes(buf.subarray(0, 1), nibblesToBytes(nibbles))
}

export const bytesToNibbles = (str: Uint8Array) => {
Expand Down Expand Up @@ -103,22 +106,6 @@ export const compactBytesToNibbles = (compact: Uint8Array) => {
return base.subarray(chop)
}

/**
* Packs every two nibbles into a single byte
*
* @param arr Nibble typed nibble array
* @returns Uint8Array typed byte array
*/
export const nibbleTypeToPackedBytes = (arr: Nibbles): Uint8Array => {
const buf = new Uint8Array(arr.length / 2)
for (let i = 0; i < buf.length; i++) {
let q = i * 2
buf[i] = (arr[q] << 4) + arr[++q]
}

return buf
}

/**
* Converts each nibble into a single byte
*
Expand Down Expand Up @@ -167,7 +154,7 @@ export const pathToHexKey = (path: string, extension: Nibbles, retType: string):
if (retType === 'hex') {
return nibbleTypeToByteType(n.concat(extension))
} else if (retType === 'keybyte') {
return nibbleTypeToPackedBytes(n.concat(extension))
return nibblesTypeToPackedBytes(n.concat(extension))
}
throw Error('retType must be either "keybyte" or "hex"')
}
Expand Down
2 changes: 1 addition & 1 deletion packages/trie/src/util/nibbles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function bytesToNibbles(key: Uint8Array): Nibbles {
* @private
* @param arr - Nibble array
*/
export function nibblestoBytes(arr: Nibbles): Uint8Array {
export function nibblesTypeToPackedBytes(arr: Nibbles): Uint8Array {
const buf = new Uint8Array(arr.length / 2)
for (let i = 0; i < buf.length; i++) {
let q = i * 2
Expand Down
4 changes: 2 additions & 2 deletions packages/trie/test/util/encodingUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import {
compactBytesToNibbles,
mergeAndFormatKeyPaths,
nibbleTypeToByteType,
nibbleTypeToPackedBytes,
nibblesToCompactBytes,
pathToHexKey,
} from '../../src/util/encoding.js'
import { nibblesTypeToPackedBytes } from '../../src/util/nibbles.js'

import type { Nibbles } from '../../src/types.js'

Expand Down Expand Up @@ -93,7 +93,7 @@ describe('encoding', () => {
// Calculate the expected result manually based on the functions used in the pathToHexKey function
const b = hexToBytes(`0x${path}`)
const n = byteTypeToNibbleType(b)
const expected = nibbleTypeToPackedBytes(n.concat(extension))
const expected = nibblesTypeToPackedBytes(n.concat(extension))

assert.deepEqual(
result,
Expand Down

0 comments on commit da22a38

Please sign in to comment.