@@ -7,10 +7,12 @@ import {
7
7
ssz ,
8
8
SyncPeriod ,
9
9
} from "@lodestar/types" ;
10
- import { ForkName } from "@lodestar/params" ;
11
- import { ChainForkConfig } from "@lodestar/config" ;
10
+ import { fromHex } from "@lodestar/utils" ;
11
+ import { ForkName , ZERO_HASH } from "@lodestar/params" ;
12
+ import { BeaconConfig , ChainForkConfig , createBeaconConfig } from "@lodestar/config" ;
13
+ import { genesisData , NetworkName } from "@lodestar/config/networks" ;
12
14
import { Endpoint , RouteDefinitions , Schema } from "../../utils/index.js" ;
13
- import { VersionCodec , VersionMeta } from "../../utils/metadata.js" ;
15
+ import { MetaHeader , VersionCodec , VersionMeta } from "../../utils/metadata.js" ;
14
16
import { getLightClientForkTypes , toForkName } from "../../utils/fork.js" ;
15
17
import {
16
18
EmptyArgs ,
@@ -19,7 +21,6 @@ import {
19
21
EmptyMetaCodec ,
20
22
EmptyRequest ,
21
23
WithVersion ,
22
- JsonOnlyResp ,
23
24
} from "../../utils/codecs.js" ;
24
25
25
26
// See /packages/api/src/routes/index.ts for reasoning and instructions to add new routes
@@ -90,7 +91,18 @@ export type Endpoints = {
90
91
> ;
91
92
} ;
92
93
93
- export function getDefinitions ( _config : ChainForkConfig ) : RouteDefinitions < Endpoints > {
94
+ export function getDefinitions ( config : ChainForkConfig ) : RouteDefinitions < Endpoints > {
95
+ // Cache config so fork digests don't need to be recomputed
96
+ let beaconConfig : BeaconConfig | undefined ;
97
+
98
+ const cachedBeaconConfig = ( ) : BeaconConfig => {
99
+ if ( beaconConfig === undefined ) {
100
+ const genesisValidatorsRoot = genesisData [ config . CONFIG_NAME as NetworkName ] ?. genesisValidatorsRoot ;
101
+ beaconConfig = createBeaconConfig ( config , genesisValidatorsRoot ? fromHex ( genesisValidatorsRoot ) : ZERO_HASH ) ;
102
+ }
103
+ return beaconConfig ;
104
+ } ;
105
+
94
106
return {
95
107
getLightClientUpdatesByRange : {
96
108
url : "/eth/v1/beacon/light_client/updates" ,
@@ -100,7 +112,7 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
100
112
parseReq : ( { query} ) => ( { startPeriod : query . start_period , count : query . count } ) ,
101
113
schema : { query : { start_period : Schema . UintRequired , count : Schema . UintRequired } } ,
102
114
} ,
103
- resp : JsonOnlyResp ( {
115
+ resp : {
104
116
data : {
105
117
toJson : ( data , meta ) => {
106
118
const json : unknown [ ] = [ ] ;
@@ -118,12 +130,44 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
118
130
}
119
131
return value ;
120
132
} ,
133
+ serialize : ( data , meta ) => {
134
+ const chunks : Uint8Array [ ] = [ ] ;
135
+ for ( const [ i , update ] of data . entries ( ) ) {
136
+ const version = meta . versions [ i ] ;
137
+ const forkDigest = cachedBeaconConfig ( ) . forkName2ForkDigest ( version ) ;
138
+ const serialized = getLightClientForkTypes ( version ) . LightClientUpdate . serialize ( update ) ;
139
+ const length = ssz . UintNum64 . serialize ( 4 + serialized . length ) ;
140
+ chunks . push ( length , forkDigest , serialized ) ;
141
+ }
142
+ return Buffer . concat ( chunks ) ;
143
+ } ,
144
+ deserialize : ( data ) => {
145
+ let offset = 0 ;
146
+ const updates : LightClientUpdate [ ] = [ ] ;
147
+ while ( offset < data . length ) {
148
+ const length = ssz . UintNum64 . deserialize ( data . subarray ( offset , offset + 8 ) ) ;
149
+ const forkDigest = ssz . ForkDigest . deserialize ( data . subarray ( offset + 8 , offset + 12 ) ) ;
150
+ const version = cachedBeaconConfig ( ) . forkDigest2ForkName ( forkDigest ) ;
151
+ updates . push (
152
+ getLightClientForkTypes ( version ) . LightClientUpdate . deserialize (
153
+ data . subarray ( offset + 12 , offset + 8 + length )
154
+ )
155
+ ) ;
156
+ offset += 8 + length ;
157
+ }
158
+ return updates ;
159
+ } ,
121
160
} ,
122
161
meta : {
123
162
toJson : ( meta ) => meta ,
124
163
fromJson : ( val ) => val as { versions : ForkName [ ] } ,
125
- toHeadersObject : ( ) => ( { } ) ,
126
- fromHeaders : ( ) => ( { versions : [ ] } ) ,
164
+ toHeadersObject : ( meta ) => ( {
165
+ [ MetaHeader . Version ] : meta . versions . join ( "," ) ,
166
+ } ) ,
167
+ fromHeaders : ( headers ) => {
168
+ const versions = headers . getOrDefault ( MetaHeader . Version , "" ) ;
169
+ return { versions : versions === "" ? [ ] : ( versions . split ( "," ) as ForkName [ ] ) } ;
170
+ } ,
127
171
} ,
128
172
transform : {
129
173
toResponse : ( data , meta ) => {
@@ -147,7 +191,7 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
147
191
return { data : updates , meta} ;
148
192
} ,
149
193
} ,
150
- } ) ,
194
+ } ,
151
195
} ,
152
196
getLightClientOptimisticUpdate : {
153
197
url : "/eth/v1/beacon/light_client/optimistic_update" ,
0 commit comments