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