Skip to content

Commit

Permalink
Merge branch 'master' into prague-def-hf
Browse files Browse the repository at this point in the history
  • Loading branch information
jochem-brouwer authored Feb 24, 2025
2 parents 760a2b3 + bd77a74 commit fa84173
Show file tree
Hide file tree
Showing 17 changed files with 37 additions and 74 deletions.
15 changes: 9 additions & 6 deletions packages/client/src/sync/fetcher/accountfetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
setLengthLeft,
} from '@ethereumjs/util'
import debugDefault from 'debug'
import { keccak256 } from 'ethereum-cryptography/keccak.js'

import { Event } from '../../types.js'
import { short } from '../../util/index.js'
Expand Down Expand Up @@ -324,10 +323,15 @@ export class AccountFetcher extends Fetcher<JobTask, AccountData[], AccountData>
const keys = accounts.map((acc: any) => acc.hash)
const values = accounts.map((acc: any) => accountBodyToRLP(acc.body))
// convert the request to the right values
return verifyMerkleRangeProof(stateRoot, origin, keys[keys.length - 1], keys, values, proof, {
common: this.config.chainCommon,
useKeyHashingFunction: this.config.chainCommon?.customCrypto?.keccak256 ?? keccak256,
})
return verifyMerkleRangeProof(
stateRoot,
origin,
keys[keys.length - 1],
keys,
values,
proof,
this.config.chainCommon?.customCrypto?.keccak256,
)
}

private getOrigin(job: Job<JobTask, AccountData[], AccountData>): Uint8Array {
Expand Down Expand Up @@ -412,7 +416,6 @@ export class AccountFetcher extends Fetcher<JobTask, AccountData[], AccountData>
[],
[],
<any>rangeResult.proof,
{ useKeyHashingFunction: keccak256 },
)
// if proof is false, reject corrupt peer
if (isMissingRightRange !== false) return undefined
Expand Down
12 changes: 2 additions & 10 deletions packages/client/src/sync/fetcher/storagefetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
short,
} from '@ethereumjs/util'
import debugDefault from 'debug'
import { keccak256 } from 'ethereum-cryptography/keccak'

import { Fetcher } from './fetcher.js'
import { getInitFetcherDoneFlags } from './types.js'
Expand Down Expand Up @@ -135,10 +134,7 @@ export class StorageFetcher extends Fetcher<JobTask, StorageData[][], StorageDat
keys,
values,
proof ?? null,
{
common: this.config.chainCommon,
useKeyHashingFunction: this.config.chainCommon?.customCrypto?.keccak256 ?? keccak256,
},
this.config.chainCommon?.customCrypto?.keccak256,
)
} catch (err) {
this.DEBUG && this.debug(`verifyRangeProof failure: ${(err as Error).stack}`)
Expand Down Expand Up @@ -287,7 +283,6 @@ export class StorageFetcher extends Fetcher<JobTask, StorageData[][], StorageDat
[],
[],
<any>rangeResult.proof,
{ useKeyHashingFunction: keccak256 },
)

// if proof is false, reject corrupt peer
Expand Down Expand Up @@ -344,10 +339,7 @@ export class StorageFetcher extends Fetcher<JobTask, StorageData[][], StorageDat
accountSlots.map((s) => s.hash),
accountSlots.map((s) => s.body),
null,
{
common: this.config.chainCommon,
useKeyHashingFunction: this.config.chainCommon?.customCrypto?.keccak256 ?? keccak256,
},
this.config.chainCommon?.customCrypto?.keccak256,
)

if (proof?.length === 0)
Expand Down
7 changes: 1 addition & 6 deletions packages/client/test/net/protocol/snapprotocol.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,7 @@ describe('[SnapProtocol]', () => {
try {
const keys = accounts.map((acc: any) => acc.hash)
const values = accounts.map((acc: any) => accountBodyToRLP(acc.body))
await verifyMerkleRangeProof(stateRoot, keys[0], keys[keys.length - 1], keys, values, proof, {
useKeyHashingFunction: keccak256,
})
await verifyMerkleRangeProof(stateRoot, keys[0], keys[keys.length - 1], keys, values, proof)
} catch (e) {
assert.fail(`AccountRange proof verification failed with message=${(e as Error).message}`)
}
Expand Down Expand Up @@ -331,9 +329,6 @@ describe('[SnapProtocol]', () => {
keys,
values,
proof,
{
useKeyHashingFunction: keccak256,
},
)
} catch (e) {
assert.fail(`StorageRange proof verification failed with message=${(e as Error).message}`)
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion packages/mpt/src/db/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './checkpoint.js'
export * from './checkpointDB.js'
2 changes: 1 addition & 1 deletion packages/mpt/src/mpt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
import debug from 'debug'
import { keccak256 } from 'ethereum-cryptography/keccak.js'

import { CheckpointDB } from './db/index.js'
import { CheckpointDB } from './db/checkpointDB.js'
import {
BranchMPTNode,
ExtensionMPTNode,
Expand Down
1 change: 1 addition & 0 deletions packages/mpt/src/proof/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './proof.js'
export * from './range.js'
37 changes: 0 additions & 37 deletions packages/mpt/src/proof/proof.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { bytesToHex, concatBytes, equalsBytes } from '@ethereumjs/util'
import { keccak256 } from 'ethereum-cryptography/keccak'

import { createMPTFromProof } from '../constructors.js'
import { MerklePatriciaTrie } from '../index.js'
import { bytesToNibbles } from '../util/nibbles.js'

import { verifyRangeProof } from './range.js'

import type { MPTOpts, Proof } from '../index.js'
import type { PutBatch } from '@ethereumjs/util'
Expand Down Expand Up @@ -34,39 +30,6 @@ export async function verifyMerkleProof(
}
}

// /**
// * A range proof is a proof that includes the encoded trie nodes from the root node to leaf node for one or more branches of a trie,
// * allowing an entire range of leaf nodes to be validated. This is useful in applications such as snap sync where contiguous ranges
// * of state trie data is received and validated for constructing world state, locally. Also see {@link verifyRangeProof}.
// * @param rootHash - root hash of state trie this proof is being verified against.
// * @param firstKey - first key of range being proven.
// * @param lastKey - last key of range being proven.
// * @param keys - key list of leaf data being proven.
// * @param values - value list of leaf data being proven, one-to-one correspondence with keys.
// * @param proof - proof node list, if all-elements-proof where no proof is needed, proof should be null, and both `firstKey` and `lastKey` must be null as well
// * @param opts - optional, the opts may include a custom hashing function to use with the trie for proof verification
// * @returns a flag to indicate whether there exists more trie node in the trie
// */
export function verifyMerkleRangeProof(
rootHash: Uint8Array,
firstKey: Uint8Array | null,
lastKey: Uint8Array | null,
keys: Uint8Array[],
values: Uint8Array[],
proof: Uint8Array[] | null,
opts?: MPTOpts,
): Promise<boolean> {
return verifyRangeProof(
rootHash,
firstKey && bytesToNibbles(firstKey),
lastKey && bytesToNibbles(lastKey),
keys.map((k) => k).map(bytesToNibbles),
values,
proof,
opts?.useKeyHashingFunction ?? keccak256,
)
}

/**
* Creates a proof from a trie and key that can be verified using {@link verifyMPTWithMerkleProof}. An (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains
* the encoded trie nodes from the root node to the leaf node storing state data. The returned proof will be in the format of an array that contains Uint8Arrays of
Expand Down
27 changes: 18 additions & 9 deletions packages/mpt/src/proof/range.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { equalsBytes } from '@ethereumjs/util'
import { keccak256 } from 'ethereum-cryptography/keccak'

import { createMPTFromProof } from '../index.js'
import { MerklePatriciaTrie } from '../mpt.js'
import { BranchMPTNode, ExtensionMPTNode, LeafMPTNode } from '../node/index.js'
import { nibblesCompare, nibblesTypeToPackedBytes } from '../util/nibbles.js'
import { bytesToNibbles, nibblesCompare, nibblesTypeToPackedBytes } from '../util/nibbles.js'

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

Expand Down Expand Up @@ -386,9 +387,11 @@ async function hasRightElement(trie: MerklePatriciaTrie, key: Nibbles): Promise<
}

/**
* verifyRangeProof checks whether the given leaf nodes and edge proof
* can prove the given trie leaves range is matched with the specific root.
* Used internally by the verifyMerkleRangeProof wrapper function.
* Checks whether the given leaf nodes and edge proof can prove the given trie leaves range is matched with the specific root.
*
* A range proof is a proof that includes the encoded trie nodes from the root node to leaf node for one or more branches of a trie,
* allowing an entire range of leaf nodes to be validated. This is useful in applications such as snap sync where contiguous ranges
* of state trie data is received and validated for constructing world state, locally.
*
* There are four situations:
*
Expand All @@ -412,17 +415,23 @@ async function hasRightElement(trie: MerklePatriciaTrie, key: Nibbles): Promise<
* @param keys - key list of leaf data being proven.
* @param values - value list of leaf data being proven, one-to-one correspondence with keys.
* @param proof - proof node list, if all-elements-proof where no proof is needed, proof should be null, and both `firstKey` and `lastKey` must be null as well
* @param opts - optional, the opts may include a custom hashing function to use with the trie for proof verification
* @returns a flag to indicate whether there exists more trie node in the trie
*/
export async function verifyRangeProof(
export async function verifyMerkleRangeProof(
rootHash: Uint8Array,
firstKey: Nibbles | null,
lastKey: Nibbles | null,
keys: Nibbles[],
firstKeyRaw: Uint8Array | null,
lastKeyRaw: Uint8Array | null,
keysRaw: Uint8Array[],
values: Uint8Array[],
proof: Uint8Array[] | null,
useKeyHashingFunction: HashKeysFunction,
useKeyHashingFunction: HashKeysFunction = keccak256,
): Promise<boolean> {
// Convert Uint8Array keys to nibbles
const firstKey = firstKeyRaw !== null ? bytesToNibbles(firstKeyRaw) : null
const lastKey = lastKeyRaw !== null ? bytesToNibbles(lastKeyRaw) : null
const keys = keysRaw.map(bytesToNibbles)

if (keys.length !== values.length) {
throw new Error('invalid keys length or values length')
}
Expand Down
2 changes: 1 addition & 1 deletion packages/statemanager/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from './cache/index.js'
export * from './merkleStateManager.js'
export * from './proofs/index.js'
export * from './proof/index.js'
export * from './rpcStateManager.js'
export * from './simpleStateManager.js'
export * from './statefulVerkleStateManager.js'
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion packages/statemanager/test/proofStateManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js'
import { assert, describe, it } from 'vitest'

import { MerkleStateManager } from '../src/index.js'
import { getMerkleStateProof, verifyMerkleStateProof } from '../src/proofs/index.js'
import { getMerkleStateProof, verifyMerkleStateProof } from '../src/proof/index.js'

import { ropstenContractWithStorageData } from './testdata/ropsten_contractWithStorage.js'
import { ropstenNonexistentAccountData } from './testdata/ropsten_nonexistentAccount.js'
Expand Down
2 changes: 1 addition & 1 deletion packages/statemanager/test/rpcStateManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { createVM, runBlock, runTx } from '@ethereumjs/vm'
import { assert, describe, expect, it, vi } from 'vitest'

import { MerkleStateManager } from '../src/merkleStateManager.js'
import { getRPCStateProof } from '../src/proofs/index.js'
import { getRPCStateProof } from '../src/proof/index.js'
import { RPCBlockChain, RPCStateManager } from '../src/rpcStateManager.js'

import { block as blockData } from './testdata/providerData/blocks/block0x7a120.js'
Expand Down
2 changes: 1 addition & 1 deletion packages/statemanager/test/stateManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
addMerkleStateProofData,
fromMerkleStateProof,
getMerkleStateProof,
} from '../src/proofs/index.js'
} from '../src/proof/index.js'

import type { PrefixedHexString } from '@ethereumjs/util'

Expand Down

0 comments on commit fa84173

Please sign in to comment.