Skip to content

Commit

Permalink
More progress syncing from PN data
Browse files Browse the repository at this point in the history
  • Loading branch information
acolytec3 committed Sep 2, 2023
1 parent 74c41ec commit a512dc0
Show file tree
Hide file tree
Showing 8 changed files with 2,449 additions and 80 deletions.
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions packages/portalnetwork/src/subprotocols/beacon/beacon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { bytesToInt, concatBytes, padToEven } from '@ethereumjs/util'
import { RequestCode, FoundContent, randUint16, MAX_PACKET_SIZE } from '../../wire/index.js'
import { ssz } from '@lodestar/types'
import { LightClientUpdate } from '@lodestar/types/lib/allForks/types.js'
import { computeSyncPeriodAtSlot } from './util.js'
import { computeSyncPeriodAtSlot } from '@lodestar/light-client/utils'
import { INodeAddress } from '@chainsafe/discv5/lib/session/nodeInfo.js'
import { Lightclient } from '@lodestar/light-client'
import { UltralightTransport } from './ultralightTransport.js'
Expand Down Expand Up @@ -56,6 +56,7 @@ export class BeaconLightClientNetwork extends BaseProtocol {
*/
public initializeLightClient = async (blockRoot: string) => {
const lcLogger = this.logger.extend('LightClient')

const lcLoggerError = lcLogger.extend('ERROR')
const lcLoggerWarn = lcLogger.extend('WARN')
const lcLoggerInfo = lcLogger.extend('INFO')
Expand All @@ -69,9 +70,10 @@ export class BeaconLightClientNetwork extends BaseProtocol {
transport: new UltralightTransport(this),
checkpointRoot: fromHexString(blockRoot),
logger: {
error: (msg, context) => {
error: (msg, context, error) => {
msg && lcLoggerError(msg)
context && lcLoggerError(context)
error && lcLoggerError(error)
},
warn: (msg, context) => {
msg && lcLoggerWarn(msg)
Expand Down
2 changes: 1 addition & 1 deletion packages/portalnetwork/src/subprotocols/beacon/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Bytes32Type } from '../types.js'
export const MainnetGenesisValidatorsRoot =
'0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95'

export const MainnetGenesisTime = 1621504614
export const MainnetGenesisTime = 1606824023

export const MAX_REQUEST_LIGHT_CLIENT_UPDATES = 128

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,13 @@ export class UltralightTransport implements LightClientTransport {
),
)
if (decoded !== undefined) {
const forkhash = decoded.value.slice(0, 4) as Uint8Array
const forkname = this.protocol.beaconConfig.forkDigest2ForkName(forkhash) as any
const updateRange = LightClientUpdatesByRange.deserialize(
(decoded.value as Uint8Array).slice(4),
)
for (const update in updateRange) {
const updateRange = LightClientUpdatesByRange.deserialize(decoded.value as Uint8Array)
for (const update of updateRange) {
const forkhash = update.slice(0, 4)
const forkname = this.protocol.beaconConfig.forkDigest2ForkName(forkhash) as any
range.push({
version: forkname as ForkName,
data: (ssz as any)[forkname].LightClientUpdate.deserialize(update),
data: (ssz as any)[forkname].LightClientUpdate.deserialize(update.slice(4)),
})
}
return range
Expand Down
59 changes: 1 addition & 58 deletions packages/portalnetwork/src/subprotocols/beacon/util.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,11 @@
import { BitArray, fromHexString, toHexString } from '@chainsafe/ssz'
import { toHexString } from '@chainsafe/ssz'
import {
BeaconLightClientNetworkContentType,
LightClientBootstrapKey,
LightClientFinalityUpdateKey,
LightClientOptimisticUpdateKey,
LightClientUpdatesByRange,
} from './types.js'
import { EPOCHS_PER_SYNC_COMMITTEE_PERIOD, SLOTS_PER_EPOCH } from '@lodestar/params'
import { Epoch, Slot, SyncPeriod } from '@lodestar/types'

export const attestedHeaderFromJson = (data: any) => {
return {
slot: BigInt(data.beacon.slot),
proposerIndex: BigInt(data.beacon.proposer_index),
parentRoot: fromHexString(data.beacon.parent_root),
stateRoot: fromHexString(data.beacon.state_root),
bodyRoot: fromHexString(data.beacon.body_root),
}
}

export const syncAggregateFromJson = (data: any) => {
return {
syncCommitteeBits: new BitArray(
new Uint8Array(
Array.from(BigInt(data.sync_committee_bits).toString(2)).map((el) => parseInt(el)),
),
256, // TODO: Fix this so Bitlength is equal to SYNC_COMMITTEE_SIZE - 512
),
syncCommitteeSignature: fromHexString(data.sync_committee_signature),
}
}

export const lightClientOptimisticUpdateFromJson = (data: any) => {
return {
attestedHeader: attestedHeaderFromJson(data.attested_header),
syncAggregate: syncAggregateFromJson(data.sync_aggregate),
}
}

/**
* Serializes a beacon network content key
Expand Down Expand Up @@ -73,29 +42,3 @@ export const decodeBeaconContentKey = (serializedKey: Uint8Array) => {
throw new Error(`unknown content type ${selector}`)
}
}

/******** Borrowed directly from Lodestar **************/
// Copied from here - https://github.com/ChainSafe/lodestar/blob/unstable/packages/light-client/src/utils/clock.ts
// Borrowed from Lodestar since we don't want to have to import all of the Lodestar dependency tree for a few helper functions
// TODO: Remove if we ever decide to fully incorporate the Lodestar light client into our code base
/**
* Return the epoch number at the given slot.
*/
export function computeEpochAtSlot(slot: Slot): Epoch {
return Math.floor(slot / SLOTS_PER_EPOCH)
}

/**
* Return the sync committee period at epoch
*/
export function computeSyncPeriodAtEpoch(epoch: Epoch): SyncPeriod {
return Math.floor(epoch / EPOCHS_PER_SYNC_COMMITTEE_PERIOD)
}

/**
* Return the sync committee period at slot
*/
export function computeSyncPeriodAtSlot(slot: Slot): SyncPeriod {
return computeSyncPeriodAtEpoch(computeEpochAtSlot(slot))
}
/************************ ****************************/
66 changes: 55 additions & 11 deletions packages/portalnetwork/test/integration/beaconProtocol.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@ import {
BeaconLightClientNetwork,
BeaconLightClientNetworkContentType,
toHexString,
getBeaconContentKey,
LightClientBootstrapKey,
LightClientUpdatesByRange,
} from '../../src/index.js'
import { createRequire } from 'module'

import { SignableENR } from '@chainsafe/discv5'
import { ssz } from '@lodestar/types'

import { ForkName } from '@lodestar/params'
import { concatBytes } from '@ethereumjs/util'
import { RunStatusCode } from '@lodestar/light-client'

const require = createRequire(import.meta.url)

Expand Down Expand Up @@ -281,8 +289,6 @@ describe('beacon light client sync tests', () => {
},
})

node1.enableLog('*Portal:BeaconLightClientNetwork*')
node2.enableLog('*Portal:BeaconLightClientNetwork*')
await node1.start()
await node2.start()
const protocol1 = node1.protocols.get(
Expand Down Expand Up @@ -315,6 +321,7 @@ describe('beacon light client sync tests', () => {
})
it.only('should start syncing the lightclient', async () => {
vi.useFakeTimers()
vi.setSystemTime(1693430999000)
const id1 = await createFromProtobuf(fromHexString(privateKeys[0]))
const enr1 = SignableENR.createFromPeerId(id1)
const initMa: any = multiaddr(`/ip4/127.0.0.1/udp/3009`)
Expand Down Expand Up @@ -346,8 +353,9 @@ describe('beacon light client sync tests', () => {
},
})

node1.enableLog('*Portal:BeaconLightClientNetwork*')
node2.enableLog('*Portal:BeaconLightClientNetwork*')
node1.enableLog('*Portal*')
node2.enableLog('*Portal*')

await node1.start()
await node2.start()
const protocol1 = node1.protocols.get(
Expand All @@ -365,19 +373,55 @@ describe('beacon light client sync tests', () => {
'node1 added node2 to routing table',
)

const bootstrap = specTestVectors.bootstrap['6718368']
const bootstrapJSON = require('./testdata/bootstrap.json').data
const bootstrap = ssz.capella.LightClientBootstrap.fromJson(bootstrapJSON)
const range = require('./testdata/lcUpdateRange.json')
const capellaForkDigest = protocol1.beaconConfig.forkName2ForkDigest(ForkName.capella)
const update1 = concatBytes(
capellaForkDigest,
ssz.capella.LightClientUpdate.serialize(
ssz.capella.LightClientUpdate.fromJson(range[0].data),
),
)
const update2 = concatBytes(
capellaForkDigest,
ssz.capella.LightClientUpdate.serialize(
ssz.capella.LightClientUpdate.fromJson(range[1].data),
),
)
const update3 = concatBytes(
capellaForkDigest,
ssz.capella.LightClientUpdate.serialize(
ssz.capella.LightClientUpdate.fromJson(range[2].data),
),
)

await protocol1.store(
BeaconLightClientNetworkContentType.LightClientBootstrap,
bootstrap.content_key,
fromHexString(bootstrap.content_value),
getBeaconContentKey(
BeaconLightClientNetworkContentType.LightClientBootstrap,
LightClientBootstrapKey.serialize({
blockHash: ssz.phase0.BeaconBlockHeader.hashTreeRoot(bootstrap.header.beacon),
}),
),
concatBytes(capellaForkDigest, ssz.capella.LightClientBootstrap.serialize(bootstrap)),
)

const updatesByRange = specTestVectors.updateByRange['6684738']
await protocol1.storeUpdateRange(fromHexString(updatesByRange.content_value))
const updatesByRange = LightClientUpdatesByRange.serialize([update1, update2, update3])

await protocol1.storeUpdateRange(updatesByRange)

await protocol2.initializeLightClient(
'0xbd9f42d9a42d972bdaf4dee84e5b419dd432b52867258acb7bcc7f567b6e3af1',
'0x3e733d7db0b70c17a00c125da9cce68cbdb8135c4400afedd88c17f11a3e3b7b',
)

protocol2.on('ContentAdded', (contentType, contentKey) =>
console.log('content!@', contentType, contentKey),
)
await protocol2.lightClient?.start()
})

while (protocol2.lightClient?.status !== RunStatusCode.started) {
await new Promise((r) => setTimeout(r, 1000))
}
}, 20000)
})
Loading

0 comments on commit a512dc0

Please sign in to comment.