Skip to content

Commit 4cefc9f

Browse files
committed
Add tests for no headers and subset of headers
1 parent 7a61983 commit 4cefc9f

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

packages/portalnetwork/src/networks/history/history.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ export class HistoryNetwork extends BaseNetwork {
411411
// Retrieve the starting header from the FINDCONTENT request
412412
const headerKey = getEphemeralHeaderDbKey(contentKey.keyOpt.blockHash)
413413
const firstHeader = await this.findContentLocally(headerKey)
414+
414415
if (firstHeader === undefined) {
415416
// If we don't have the requested header, send an empty payload
416417
// We never send an ENRs response for ephemeral headers
@@ -423,7 +424,12 @@ export class HistoryNetwork extends BaseNetwork {
423424
this.logger.extend('FOUNDCONTENT')(
424425
`Header not found for ${bytesToHex(contentKey.keyOpt.blockHash)}, sending empty ephemeral headers response to ${shortId(src.nodeId)}`,
425426
)
426-
await this.sendResponse(src, requestId, messagePayload)
427+
await this.sendResponse(
428+
src,
429+
requestId,
430+
concatBytes(Uint8Array.from([MessageCodes.CONTENT]), messagePayload),
431+
)
432+
return
427433
} else {
428434
this.logger.extend('FOUNDCONTENT')(
429435
`Header found for ${bytesToHex(contentKey.keyOpt.blockHash)}, assembling ephemeral headers response to ${shortId(src.nodeId)}`,
@@ -433,7 +439,7 @@ export class HistoryNetwork extends BaseNetwork {
433439
const firstHeaderNumber = this.ephemeralHeaderIndex.getByValue(
434440
bytesToHex(contentKey.keyOpt.blockHash),
435441
)
436-
for (let x = 1; x <= contentKey.keyOpt.ancestorCount; x++) {
442+
for (let x = 1; x < contentKey.keyOpt.ancestorCount; x++) {
437443
// Determine if we have the ancestor header at block number `firstHeaderNumber - x`
438444
const ancestorNumber = firstHeaderNumber! - BigInt(x)
439445
const ancestorHash = this.ephemeralHeaderIndex.getByKey(ancestorNumber)

packages/portalnetwork/test/integration/ephemeralHeaders.spec.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { SignableENR } from '@chainsafe/enr'
22
import type { BlockHeader, JsonRpcBlock } from '@ethereumjs/block'
33
import { Block } from '@ethereumjs/block'
4-
import { hexToBytes } from '@ethereumjs/util'
4+
import { hexToBytes, randomBytes } from '@ethereumjs/util'
55
import { keys } from '@libp2p/crypto'
66
import { multiaddr } from '@multiformats/multiaddr'
77
import { assert, beforeAll, describe, it } from 'vitest'
@@ -86,5 +86,35 @@ describe('should be able to retrieve ephemeral headers from a peer', () => {
8686
} else {
8787
assert.fail('Expected content in response')
8888
}
89-
})
89+
90+
const contentKeyForOneAncestor = getContentKey(HistoryNetworkContentType.EphemeralHeader, {
91+
blockHash: headers[0].hash(),
92+
ancestorCount: 1,
93+
})
94+
95+
const res2 = await network2!.sendFindContent(node1.discv5.enr.toENR(), contentKeyForOneAncestor)
96+
assert.exists(res2)
97+
if ('content' in res2!) {
98+
const payload = EphemeralHeaderPayload.deserialize(res2.content)
99+
assert.equal(payload.length, 1, 'should only get a single ancestor')
100+
} else {
101+
assert.fail('Expected content in response')
102+
}
103+
104+
// Verify that we get an empty ephemeral headers payload for a random blockhash
105+
const res3 = await network2!.sendFindContent(
106+
node1.discv5.enr.toENR(),
107+
getContentKey(HistoryNetworkContentType.EphemeralHeader, {
108+
blockHash: randomBytes(32),
109+
ancestorCount: 255,
110+
}),
111+
)
112+
assert.exists(res3)
113+
if ('content' in res3!) {
114+
const payload = EphemeralHeaderPayload.deserialize(res3.content)
115+
assert.equal(payload.length, 0, 'should not get any headers for a random blockhash')
116+
} else {
117+
assert.fail('Expected content in response')
118+
}
119+
}, 10000)
90120
})

0 commit comments

Comments
 (0)