11import { readFileSync } from 'fs'
22import { ssz } from '@lodestar/types'
3- import { concatBytes , hexToBytes } from '@ethereumjs/util'
3+ import { bytesToHex , concatBytes , hexToBytes } from '@ethereumjs/util'
44import {
5- BeaconLightClientNetworkContentType ,
6- HistoricalSummariesKey ,
7- HistoricalSummariesWithProof ,
8- HistoryNetworkContentType ,
9- LightClientBootstrapKey ,
10- NetworkId ,
11- PortalNetwork ,
12- getBeaconContentKey ,
13- getContentKey
5+ BeaconLightClientNetworkContentType ,
6+ BlockHeaderWithProof ,
7+ HistoricalSummariesKey ,
8+ HistoricalSummariesWithProof ,
9+ HistoryNetworkContentType ,
10+ LightClientBootstrapKey ,
11+ NetworkId ,
12+ PortalNetwork ,
13+ getBeaconContentKey ,
14+ getContentKey ,
1415} from '../../src/index.js'
1516import { createBeaconConfig } from '@lodestar/config'
1617import { mainnetChainConfig } from '@lodestar/config/configs'
@@ -20,93 +21,105 @@ import { assert, describe, it, vi } from 'vitest'
2021import { multiaddr } from '@multiformats/multiaddr'
2122import { SignableENR } from '@chainsafe/enr'
2223import { keys } from '@libp2p/crypto'
23-
24+ import { BlockHeader } from '@ethereumjs/block'
2425
2526describe ( 'Block Bridge Data Test' , ( ) => {
26- it ( 'should store and retrieve block header data' , async ( ) => {
27- vi . useFakeTimers ( { shouldAdvanceTime : true , shouldClearNativeTimers : true } )
28- vi . setSystemTime ( 1737151319000 )
29- const privateKeys = [
30- '0x0a2700250802122102273097673a2948af93317235d2f02ad9cf3b79a34eeb37720c5f19e09f11783c12250802122102273097673a2948af93317235d2f02ad9cf3b79a34eeb37720c5f19e09f11783c1a2408021220aae0fff4ac28fdcdf14ee8ecb591c7f1bc78651206d86afe16479a63d9cb73bd' ,
31- '0x0a27002508021221039909a8a7e81dbdc867480f0eeb7468189d1e7a1dd7ee8a13ee486c8cbd743764122508021221039909a8a7e81dbdc867480f0eeb7468189d1e7a1dd7ee8a13ee486c8cbd7437641a2408021220c6eb3ae347433e8cfe7a0a195cc17fc8afcd478b9fb74be56d13bccc67813130' ,
32- ]
33- const pk1 = keys . privateKeyFromProtobuf ( hexToBytes ( privateKeys [ 0 ] ) . slice ( - 36 ) )
34- const enr1 = SignableENR . createFromPrivateKey ( pk1 )
35- const initMa : any = multiaddr ( `/ip4/127.0.0.1/udp/5033` )
36-
37- const client = await PortalNetwork . create ( {
38- supportedNetworks : [ { networkId : NetworkId . HistoryNetwork } , { networkId : NetworkId . BeaconChainNetwork } ] , config : { enr : enr1 , bindAddrs : { ip4 : initMa } , privateKey : pk1 }
39- } )
40- await client . start ( )
41-
42- const bootstrapHex = JSON . parse ( readFileSync ( './test/integration/testdata/postCapellaData/bootstrap.json' , 'utf8' ) )
43- const historicalSummariesJson = JSON . parse ( readFileSync ( './test/integration/testdata/postCapellaData/historical_summaries.json' , 'utf8' ) )
44- const fullBlock = JSON . parse ( readFileSync ( './test/integration/testdata/postCapellaData/full_block.json' , 'utf8' ) )
45- const headerWithProof = JSON . parse ( readFileSync ( './test/integration/testdata/postCapellaData/header_with_proof.json' , 'utf8' ) )
46-
47- const bootstrap = ssz . deneb . LightClientBootstrap . deserialize ( hexToBytes ( bootstrapHex . bootstrap ) )
48- const bootstrapRoot = '0x47a956b9cd45c73a60dac4c89dc869a5faa46a9d5d802486f31025c74d41ef39'
49-
50- // Get fork info
51- const forkConfig = getChainForkConfigFromNetwork ( 'mainnet' )
52- const bootstrapSlot = bootstrap . header . beacon . slot
53- const forkName = forkConfig . getForkName ( bootstrapSlot )
54- const forkDigest = createBeaconConfig (
55- mainnetChainConfig ,
56- hexToBytes ( genesisData . mainnet . genesisValidatorsRoot )
57- ) . forkName2ForkDigest ( forkName )
58-
59- // Store bootstrap
60-
61- const bootstrapKey = getBeaconContentKey (
62- BeaconLightClientNetworkContentType . LightClientBootstrap ,
63- LightClientBootstrapKey . serialize ( { blockHash : hexToBytes ( bootstrapRoot ) } )
64- )
65- const bootstrapValue = concatBytes (
66- forkDigest ,
67- ssz . deneb . LightClientBootstrap . serialize ( bootstrap )
68- )
69-
70-
71- const beacon = client . network ( ) [ '0x500c' ]
72- const history = client . network ( ) [ '0x500b' ]
73-
74- await beacon ?. store ( bootstrapKey , bootstrapValue )
75-
76- // Start light client
77- await beacon ?. initializeLightClient ( bootstrapRoot )
78-
79- const historicalSummariesEpoch = computeEpochAtSlot ( bootstrapSlot )
80-
81- // Store historical summaries
82- const historicalSummariesObj = HistoricalSummariesWithProof . fromJson ( {
83- epoch : historicalSummariesEpoch ,
84- historical_summaries : historicalSummariesJson . historical_summaries ,
85- proof : historicalSummariesJson . proof
86- } )
87- const summariesKey = getBeaconContentKey (
88- BeaconLightClientNetworkContentType . HistoricalSummaries ,
89- HistoricalSummariesKey . serialize ( { epoch : BigInt ( historicalSummariesEpoch ) } )
90- )
91- const summariesValue = concatBytes (
92- forkDigest ,
93- HistoricalSummariesWithProof . serialize ( historicalSummariesObj )
94- )
95- await beacon ?. store ( summariesKey , summariesValue )
96-
97- // Store header with proof
98- const blockHash = fullBlock . data . message . body . execution_payload . block_hash
99-
100- const headerKey = getContentKey (
101- HistoryNetworkContentType . BlockHeader ,
102- hexToBytes ( blockHash )
103- )
104- await history ?. store ( headerKey , hexToBytes ( headerWithProof ) )
105-
106- // Verify block header can be retrieved
107- const retrievedHeader = await client . ETH . getBlockByHash ( hexToBytes ( blockHash ) , false )
108- assert . equal ( retrievedHeader ! . header . number , fullBlock . data . message . body . execution_payload . block_number )
109-
110- await client . stop ( )
111- } , 10000 )
112- } )
27+ it ( 'should store and retrieve block header data' , async ( ) => {
28+ vi . useFakeTimers ( { shouldAdvanceTime : true , shouldClearNativeTimers : true } )
29+ vi . setSystemTime ( 1737151319000 )
30+ const privateKeys = [
31+ '0x0a2700250802122102273097673a2948af93317235d2f02ad9cf3b79a34eeb37720c5f19e09f11783c12250802122102273097673a2948af93317235d2f02ad9cf3b79a34eeb37720c5f19e09f11783c1a2408021220aae0fff4ac28fdcdf14ee8ecb591c7f1bc78651206d86afe16479a63d9cb73bd' ,
32+ '0x0a27002508021221039909a8a7e81dbdc867480f0eeb7468189d1e7a1dd7ee8a13ee486c8cbd743764122508021221039909a8a7e81dbdc867480f0eeb7468189d1e7a1dd7ee8a13ee486c8cbd7437641a2408021220c6eb3ae347433e8cfe7a0a195cc17fc8afcd478b9fb74be56d13bccc67813130' ,
33+ ]
34+ const pk1 = keys . privateKeyFromProtobuf ( hexToBytes ( privateKeys [ 0 ] ) . slice ( - 36 ) )
35+ const enr1 = SignableENR . createFromPrivateKey ( pk1 )
36+ const initMa : any = multiaddr ( `/ip4/127.0.0.1/udp/5033` )
37+
38+ const client = await PortalNetwork . create ( {
39+ supportedNetworks : [
40+ { networkId : NetworkId . HistoryNetwork } ,
41+ { networkId : NetworkId . BeaconChainNetwork } ,
42+ ] ,
43+ config : { enr : enr1 , bindAddrs : { ip4 : initMa } , privateKey : pk1 } ,
44+ } )
45+ await client . start ( )
46+
47+ const bootstrapHex = JSON . parse (
48+ readFileSync ( './test/integration/testdata/postCapellaData/bootstrap.json' , 'utf8' ) ,
49+ )
50+ const historicalSummariesJson = JSON . parse (
51+ readFileSync ( './test/integration/testdata/postCapellaData/historical_summaries.json' , 'utf8' ) ,
52+ )
53+ const fullBlock = JSON . parse (
54+ readFileSync ( './test/integration/testdata/postCapellaData/full_block.json' , 'utf8' ) ,
55+ )
56+ const headerWithProof = JSON . parse (
57+ readFileSync ( './test/integration/testdata/postCapellaData/header_with_proof.json' , 'utf8' ) ,
58+ )
59+
60+ const bootstrap = ssz . deneb . LightClientBootstrap . deserialize ( hexToBytes ( bootstrapHex . bootstrap ) )
61+ const bootstrapRoot = '0x47a956b9cd45c73a60dac4c89dc869a5faa46a9d5d802486f31025c74d41ef39'
62+
63+ // Get fork info
64+ const forkConfig = getChainForkConfigFromNetwork ( 'mainnet' )
65+ const bootstrapSlot = bootstrap . header . beacon . slot
66+ const forkName = forkConfig . getForkName ( bootstrapSlot )
67+ const forkDigest = createBeaconConfig (
68+ mainnetChainConfig ,
69+ hexToBytes ( genesisData . mainnet . genesisValidatorsRoot ) ,
70+ ) . forkName2ForkDigest ( forkName )
71+
72+ // Store bootstrap
73+
74+ const bootstrapKey = getBeaconContentKey (
75+ BeaconLightClientNetworkContentType . LightClientBootstrap ,
76+ LightClientBootstrapKey . serialize ( { blockHash : hexToBytes ( bootstrapRoot ) } ) ,
77+ )
78+ const bootstrapValue = concatBytes (
79+ forkDigest ,
80+ ssz . deneb . LightClientBootstrap . serialize ( bootstrap ) ,
81+ )
82+
83+ const beacon = client . network ( ) [ '0x500c' ]
84+ const history = client . network ( ) [ '0x500b' ]
85+
86+ await beacon ?. store ( bootstrapKey , bootstrapValue )
87+
88+ // Start light client
89+ await beacon ?. initializeLightClient ( bootstrapRoot )
90+
91+ const historicalSummariesEpoch = computeEpochAtSlot ( bootstrapSlot )
92+
93+ // Store historical summaries
94+ const historicalSummariesObj = HistoricalSummariesWithProof . fromJson ( {
95+ epoch : historicalSummariesEpoch ,
96+ historical_summaries : historicalSummariesJson . historical_summaries ,
97+ proof : historicalSummariesJson . proof ,
98+ } )
99+ const summariesKey = getBeaconContentKey (
100+ BeaconLightClientNetworkContentType . HistoricalSummaries ,
101+ HistoricalSummariesKey . serialize ( { epoch : BigInt ( historicalSummariesEpoch ) } ) ,
102+ )
103+ const summariesValue = concatBytes (
104+ forkDigest ,
105+ HistoricalSummariesWithProof . serialize ( historicalSummariesObj ) ,
106+ )
107+ await beacon ?. store ( summariesKey , summariesValue )
108+
109+ // Store header with proof
110+ const blockHash = fullBlock . data . message . body . execution_payload . block_hash
111+
112+ const headerKey = getContentKey ( HistoryNetworkContentType . BlockHeader , hexToBytes ( blockHash ) )
113+ console . log ( bytesToHex ( BlockHeaderWithProof . deserialize ( hexToBytes ( headerWithProof ) ) . header ) )
114+ await history ?. store ( headerKey , hexToBytes ( headerWithProof ) )
115+
116+ // Verify block header can be retrieved
117+ const retrievedHeader = await client . ETH . getBlockByHash ( hexToBytes ( blockHash ) , false )
118+ assert . equal (
119+ retrievedHeader ! . header . number ,
120+ fullBlock . data . message . body . execution_payload . block_number ,
121+ )
122+
123+ await client . stop ( )
124+ } , 10000 )
125+ } )
0 commit comments