Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into opcode-blobgasfee
Browse files Browse the repository at this point in the history
  • Loading branch information
g11tech committed Sep 19, 2023
2 parents 1e84dde + bd70544 commit 7665573
Show file tree
Hide file tree
Showing 5 changed files with 303 additions and 32 deletions.
72 changes: 46 additions & 26 deletions packages/client/test/sync/fetcher/storagefetcher.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { RLP } from '@ethereumjs/rlp'
import { hexToBytes } from '@ethereumjs/util'
import { utf8ToBytes } from 'ethereum-cryptography/utils'
import * as td from 'testdouble'
import { assert, describe, it } from 'vitest'
import { assert, describe, it, vi } from 'vitest'

import { Chain } from '../../../src/blockchain'
import { Config } from '../../../src/config'
Expand All @@ -14,13 +13,17 @@ import { _accountRangeRLP } from './accountfetcher.spec'
const _storageRangesRLP =
'0xf83e0bf83af838f7a0290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639594053cd080a26cb03d5e6d2956cebb31c56e7660cac0'

;(BigInt.prototype as any).toJSON = function () {
return this.toString()
}

describe('[StorageFetcher]', async () => {
class PeerPool {
idle() {}
ban() {}
}
PeerPool.prototype.idle = td.func<any>()
PeerPool.prototype.ban = td.func<any>()
PeerPool.prototype.idle = vi.fn()
PeerPool.prototype.ban = vi.fn()

const { StorageFetcher } = await import('../../../src/sync/fetcher/storagefetcher')

Expand Down Expand Up @@ -271,11 +274,17 @@ describe('[StorageFetcher]', async () => {
resData
)
const { reqId, slots, proof } = res
const mockedGetStorageRanges = td.func<any>()
td.when(mockedGetStorageRanges(td.matchers.anything())).thenReturn({
reqId,
slots,
proof,
const mockedGetStorageRanges = vi.fn((input) => {
const expected = {
root: utf8ToBytes(''),
accounts: [
hexToBytes('0x00009e5969eba9656d7e4dad5b0596241deb87c29bbab71c23b602c2b88a7276'),
],
origin: hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000000'),
limit: hexToBytes('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'),
bytes: BigInt(50000),
}
if (JSON.stringify(input) !== JSON.stringify(expected)) throw Error('input not as expected')
})
const peer = {
snap: { getStorageRanges: mockedGetStorageRanges },
Expand All @@ -284,17 +293,33 @@ describe('[StorageFetcher]', async () => {
}
const job = { peer, partialResult, task }
await fetcher.request(job as any)
td.verify(
job.peer.snap.getStorageRanges({
root: utf8ToBytes(''),
accounts: [
hexToBytes('0x00009e5969eba9656d7e4dad5b0596241deb87c29bbab71c23b602c2b88a7276'),
],
origin: td.matchers.anything(),
limit: td.matchers.anything(),
bytes: BigInt(50000),
})

peer.snap.getStorageRanges = vi.fn().mockReturnValueOnce({
reqId,
slots: [],
proof: [new Uint8Array()],
})
let ret = await fetcher.request(job as any)
assert.ok(
ret?.completed === true,
'should handle peer that is signaling that an empty range has been requested with no elements remaining to the right'
)

peer.snap.getStorageRanges = vi.fn().mockReturnValueOnce({
reqId,
slots: slots + [new Uint8Array()],
proof,
})
ret = await fetcher.request(job as any)
assert.notOk(ret, "Reject the response if the hash sets and slot sets don't match")

peer.snap.getStorageRanges = vi.fn().mockReturnValueOnce({
reqId,
slots: [],
proof: [],
})
ret = await fetcher.request(job as any)
assert.notOk(ret, 'Should stop requesting from peer that rejected storage request')
})

it('should verify proof correctly', async () => {
Expand Down Expand Up @@ -334,8 +359,7 @@ describe('[StorageFetcher]', async () => {
resData
)
const { reqId, slots, proof } = res
const mockedGetStorageRanges = td.func<any>()
td.when(mockedGetStorageRanges(td.matchers.anything())).thenReturn({
const mockedGetStorageRanges = vi.fn().mockReturnValueOnce({
reqId,
slots,
proof,
Expand Down Expand Up @@ -404,11 +428,7 @@ describe('[StorageFetcher]', async () => {
first: BigInt(1),
count: BigInt(10),
})
td.when((fetcher as any).pool.idle(td.matchers.anything())).thenReturn('peer0')
;(fetcher as any).pool.idle = vi.fn(() => 'peer0')
assert.equal(fetcher.peer(), 'peer0' as any, 'found peer')
})

it('should reset td', () => {
td.reset()
})
})
56 changes: 56 additions & 0 deletions packages/trie/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,62 @@ npm run profiling

0x processes the stacks and generates a profile folder (`<pid>.0x`) containing [`flamegraph.html`](https://github.com/davidmarkclements/0x/blob/master/docs/ui.md).

## Debugging

The `Trie` class features optional debug logging.. Individual debug selections can be activated on the CL with `DEBUG=ethjs,[Logger Selection]`.

`ethjs` **must** be included in the `DEBUG` environment variables to enable **any** logs.
Additional log selections can be added with a comma separated list (no spaces). Logs with extensions can be enabled with a colon `:`, and `*` can be used to include all extensions.

`DEBUG=ethjs,thislog,thatlog,otherlog,otherlog:sublog,anotherLog:* node myscript.js`

The following options are available:

| Logger | Description |
| ----------------- | ---------------------------------------------- |
| `trie` | minimal info logging for all trie methods |
| `trie:<METHOD>` | debug logging for specific trie method |
| `trie:<METHOD>:*` | verbose debug logging for specific trie method |
| `trie:*` | verbose debug logging for all trie methods |

To observe the logging in action at different levels:

Run with minimal logging:

```shell
DEBUG=ethjs,trie npx vitest test/util/log.spec.ts
```

Run with **put** method logging:

```shell
DEBUG=ethjs,trie:PUT npx vitest test/util/log.spec.ts
```

Run with **trie** + **put**/**get**/**del** logging:

```shell
DEBUG=ethjs,trie,trie:PUT,trie:GET,trie:DEL npx vitest test/util/log.spec.ts
```

Run with **findPath** debug logging:

```shell
DEBUG=ethjs,trie:FIND_PATH npx vitest test/util/log.spec.ts
```

Run with **findPath** verbose logging:

```shell
DEBUG=ethjs,trie:FIND_PATH:* npx vitest test/util/log.spec.ts
```

Run with max logging:

```shell
DEBUG=ethjs,trie:* npx vitest test/util/log.spec.ts
```

## References

- Wiki
Expand Down
31 changes: 31 additions & 0 deletions packages/trie/examples/logDemo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { utf8ToBytes } from 'ethereum-cryptography/utils'
import { Trie } from '../dist/cjs/index.js'
import { debug } from 'debug'

debug.enable('*')

const trie_entries: [string, string | null][] = [
['do', 'verb'],
['ether', 'wookiedoo'],
['horse', 'stallion'],
['shaman', 'horse'],
['doge', 'coin'],
['ether', null],
['dog', 'puppy'],
['shaman', null],
]

const main = async () => {
process.env.DEBUG = 'ethjs,*trie*'
const trie = new Trie({
useRootPersistence: true,
})
for (const [key, value] of trie_entries) {
await trie.put(utf8ToBytes(key), value === null ? Uint8Array.from([]) : utf8ToBytes(value))
}
const proof = await trie.createProof(utf8ToBytes('doge'))
const valid = await trie.verifyProof(trie.root(), utf8ToBytes('doge'), proof)
console.log('valid', valid)
}

main()
Loading

0 comments on commit 7665573

Please sign in to comment.