Skip to content

Commit

Permalink
add ephemeral header index
Browse files Browse the repository at this point in the history
  • Loading branch information
acolytec3 committed Feb 14, 2025
1 parent fbfd478 commit 4a67c82
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
23 changes: 21 additions & 2 deletions packages/portalnetwork/src/networks/history/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class HistoryNetwork extends BaseNetwork {
networkId: NetworkId.HistoryNetwork
networkName = 'HistoryNetwork'
logger: Debugger

public ephemeralHeaderIndex: Map<bigint, string> // Map of slot numbers to hashes
public blockHashIndex: Map<string, string>
constructor({ client, db, radius, maxStorage }: BaseNetworkConfig) {
super({ client, networkId: NetworkId.HistoryNetwork, db, radius, maxStorage })
Expand All @@ -60,6 +60,7 @@ export class HistoryNetwork extends BaseNetwork {
this.logger = debug(this.enr.nodeId.slice(0, 5)).extend('Portal').extend('HistoryNetwork')
this.routingTable.setLogger(this.logger)
this.blockHashIndex = new Map()
this.ephemeralHeaderIndex = new Map()
}

public blockNumberToHash(blockNumber: bigint): Uint8Array | undefined {
Expand Down Expand Up @@ -266,6 +267,18 @@ export class HistoryNetwork extends BaseNetwork {
* @returns the value of the FOUNDCONTENT response or undefined
*/
public sendFindContent = async (enr: ENR, key: Uint8Array) => {
if (key[0] === HistoryNetworkContentType.EphemeralHeader) {
const beacon = this.portal.network()['0x500c']
if (
beacon === undefined ||
beacon.lightClient?.status === RunStatusCode.uninitialized ||
beacon.lightClient?.status === RunStatusCode.stopped
) {
const errorMessage = 'Cannot verify ephemeral headers when beacon network is not running'
this.logger.extend('FINDCONTENT')(errorMessage)
throw new Error(errorMessage)
}
}
this.portal.metrics?.findContentMessagesSent.inc()
const findContentMsg: FindContentMessage = { contentKey: key }
const payload = PortalWireMessageType.serialize({
Expand Down Expand Up @@ -381,7 +394,6 @@ export class HistoryNetwork extends BaseNetwork {
break
}

// TODO: Keep an in-memory list of current ephemeral headers (by number and hash) and purge ones that are too old
case HistoryNetworkContentType.EphemeralHeader: {
const payload = EphemeralHeaderPayload.deserialize(value)
try {
Expand All @@ -397,6 +409,8 @@ export class HistoryNetwork extends BaseNetwork {
}
const hashKey = getEphemeralHeaderDbKey(firstHeader.hash())
await this.put(hashKey, bytesToHex(payload[0]))
// Index ephemeral header by block number
this.ephemeralHeaderIndex.set(firstHeader.number, bytesToHex(firstHeader.hash()))
let prevHeader = firstHeader
// Should get maximum of 256 headers
// TODO: Should we check this and ban/mark down the score of peers who violate this rule?
Expand All @@ -408,6 +422,11 @@ export class HistoryNetwork extends BaseNetwork {
// Verify that ancestor header matches parent hash of previous header
const hashKey = getEphemeralHeaderDbKey(ancestorHeader.hash())
await this.put(hashKey, bytesToHex(header))
// Index ephemeral header by block number
this.ephemeralHeaderIndex.set(
ancestorHeader.number,
bytesToHex(ancestorHeader.hash()),
)
prevHeader = ancestorHeader
} else {
const errorMessage = `invalid ephemeral header payload; expected parent hash ${bytesToHex(ancestorHeader.parentHash)} but got ${bytesToHex(prevHeader.hash())}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
getContentKey,
getEphemeralHeaderDbKey,
} from '../../../src/index.js'
import { hexToBytes } from '@ethereumjs/util'
import { bytesToHex, hexToBytes } from '@ethereumjs/util'
describe('ephemeral header handling', () => {
it('should be able to store a valid ephemeral header payload', async () => {
const node = await PortalNetwork.create({})
Expand All @@ -26,5 +26,9 @@ describe('ephemeral header handling', () => {
await network?.store(contentKey, headerPayload)
const storedHeaderPayload = await network?.get(getEphemeralHeaderDbKey(headers[0].hash()))
assert.deepEqual(hexToBytes(storedHeaderPayload!), headers[0].serialize())
assert.equal(
network?.ephemeralHeaderIndex.get(headers[1].number),
bytesToHex(headers[1].hash()),
)
})
})

0 comments on commit 4a67c82

Please sign in to comment.