@@ -3,6 +3,7 @@ package handlers
33import (
44 "context"
55 "fmt"
6+ "math"
67 "net/http"
78 "net/url"
89 "strconv"
@@ -51,6 +52,9 @@ func BlocksFiltered(w http.ResponseWriter, r *http.Request) {
5152 var minBlockSize string
5253 var maxBlockSize string
5354 var withMevBlock uint64
55+ var withBuilderBlock uint64
56+ var builder string
57+ var invertBuilder bool
5458 var minTxCount string
5559 var maxTxCount string
5660 var minBlobCount string
@@ -86,6 +90,15 @@ func BlocksFiltered(w http.ResponseWriter, r *http.Request) {
8690 if urlArgs .Has ("f.mev" ) {
8791 withMevBlock , _ = strconv .ParseUint (urlArgs .Get ("f.mev" ), 10 , 64 )
8892 }
93+ if urlArgs .Has ("f.builderblock" ) {
94+ withBuilderBlock , _ = strconv .ParseUint (urlArgs .Get ("f.builderblock" ), 10 , 64 )
95+ }
96+ if urlArgs .Has ("f.builder" ) {
97+ builder = urlArgs .Get ("f.builder" )
98+ }
99+ if urlArgs .Has ("f.binvert" ) {
100+ invertBuilder = urlArgs .Get ("f.binvert" ) == "on"
101+ }
89102 if urlArgs .Has ("f.mintx" ) {
90103 minTxCount = urlArgs .Get ("f.mintx" )
91104 }
@@ -111,7 +124,7 @@ func BlocksFiltered(w http.ResponseWriter, r *http.Request) {
111124 var pageError error
112125 pageError = services .GlobalCallRateLimiter .CheckCallLimit (r , 2 )
113126 if pageError == nil {
114- data .Data , pageError = getFilteredBlocksPageData (pageIdx , pageSize , extradata , invertextradata , minGasUsed , maxGasUsed , minGasLimit , maxGasLimit , minBlockSize , maxBlockSize , uint8 (withMevBlock ), minTxCount , maxTxCount , minBlobCount , maxBlobCount , minEpoch , maxEpoch , displayColumns )
127+ data .Data , pageError = getFilteredBlocksPageData (pageIdx , pageSize , extradata , invertextradata , minGasUsed , maxGasUsed , minGasLimit , maxGasLimit , minBlockSize , maxBlockSize , uint8 (withMevBlock ), uint8 ( withBuilderBlock ), builder , invertBuilder , minTxCount , maxTxCount , minBlobCount , maxBlobCount , minEpoch , maxEpoch , displayColumns )
115128 }
116129 if pageError != nil {
117130 handlePageError (w , r , pageError )
@@ -123,11 +136,11 @@ func BlocksFiltered(w http.ResponseWriter, r *http.Request) {
123136 }
124137}
125138
126- func getFilteredBlocksPageData (pageIdx uint64 , pageSize uint64 , extradata string , invertextradata bool , minGasUsed string , maxGasUsed string , minGasLimit string , maxGasLimit string , minBlockSize string , maxBlockSize string , withMevBlock uint8 , minTxCount string , maxTxCount string , minBlobCount string , maxBlobCount string , minEpoch string , maxEpoch string , displayColumns uint64 ) (* models.BlocksFilteredPageData , error ) {
139+ func getFilteredBlocksPageData (pageIdx uint64 , pageSize uint64 , extradata string , invertextradata bool , minGasUsed string , maxGasUsed string , minGasLimit string , maxGasLimit string , minBlockSize string , maxBlockSize string , withMevBlock uint8 , withBuilderBlock uint8 , builder string , invertBuilder bool , minTxCount string , maxTxCount string , minBlobCount string , maxBlobCount string , minEpoch string , maxEpoch string , displayColumns uint64 ) (* models.BlocksFilteredPageData , error ) {
127140 pageData := & models.BlocksFilteredPageData {}
128- pageCacheKey := fmt .Sprintf ("blocks_filtered:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v" , pageIdx , pageSize , extradata , invertextradata , minGasUsed , maxGasUsed , minGasLimit , maxGasLimit , minBlockSize , maxBlockSize , withMevBlock , minTxCount , maxTxCount , minBlobCount , maxBlobCount , minEpoch , maxEpoch , displayColumns )
141+ pageCacheKey := fmt .Sprintf ("blocks_filtered:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v " , pageIdx , pageSize , extradata , invertextradata , minGasUsed , maxGasUsed , minGasLimit , maxGasLimit , minBlockSize , maxBlockSize , withMevBlock , withBuilderBlock , builder , invertBuilder , minTxCount , maxTxCount , minBlobCount , maxBlobCount , minEpoch , maxEpoch , displayColumns )
129142 pageRes , pageErr := services .GlobalFrontendCache .ProcessCachedPage (pageCacheKey , true , pageData , func (pageCall * services.FrontendCacheProcessingPage ) interface {} {
130- return buildFilteredBlocksPageData (pageCall .CallCtx , pageIdx , pageSize , extradata , invertextradata , minGasUsed , maxGasUsed , minGasLimit , maxGasLimit , minBlockSize , maxBlockSize , withMevBlock , minTxCount , maxTxCount , minBlobCount , maxBlobCount , minEpoch , maxEpoch , displayColumns )
143+ return buildFilteredBlocksPageData (pageCall .CallCtx , pageIdx , pageSize , extradata , invertextradata , minGasUsed , maxGasUsed , minGasLimit , maxGasLimit , minBlockSize , maxBlockSize , withMevBlock , withBuilderBlock , builder , invertBuilder , minTxCount , maxTxCount , minBlobCount , maxBlobCount , minEpoch , maxEpoch , displayColumns )
131144 })
132145 if pageErr == nil && pageRes != nil {
133146 resData , resOk := pageRes .(* models.BlocksFilteredPageData )
@@ -139,8 +152,9 @@ func getFilteredBlocksPageData(pageIdx uint64, pageSize uint64, extradata string
139152 return pageData , pageErr
140153}
141154
142- func buildFilteredBlocksPageData (ctx context.Context , pageIdx uint64 , pageSize uint64 , extradata string , invertextradata bool , minGasUsed string , maxGasUsed string , minGasLimit string , maxGasLimit string , minBlockSize string , maxBlockSize string , withMevBlock uint8 , minTxCount string , maxTxCount string , minBlobCount string , maxBlobCount string , minEpoch string , maxEpoch string , displayColumns uint64 ) * models.BlocksFilteredPageData {
155+ func buildFilteredBlocksPageData (ctx context.Context , pageIdx uint64 , pageSize uint64 , extradata string , invertextradata bool , minGasUsed string , maxGasUsed string , minGasLimit string , maxGasLimit string , minBlockSize string , maxBlockSize string , withMevBlock uint8 , withBuilderBlock uint8 , builder string , invertBuilder bool , minTxCount string , maxTxCount string , minBlobCount string , maxBlobCount string , minEpoch string , maxEpoch string , displayColumns uint64 ) * models.BlocksFilteredPageData {
143156 chainState := services .GlobalBeaconService .GetChainState ()
157+ gloasActive := chainState .IsEip7732Enabled (chainState .EpochOfSlot (chainState .CurrentSlot ()))
144158 filterArgs := url.Values {}
145159
146160 if extradata != "" {
@@ -170,6 +184,15 @@ func buildFilteredBlocksPageData(ctx context.Context, pageIdx uint64, pageSize u
170184 if withMevBlock != 0 {
171185 filterArgs .Add ("f.mev" , fmt .Sprintf ("%v" , withMevBlock ))
172186 }
187+ if withBuilderBlock != 0 {
188+ filterArgs .Add ("f.builderblock" , fmt .Sprintf ("%v" , withBuilderBlock ))
189+ }
190+ if builder != "" {
191+ filterArgs .Add ("f.builder" , builder )
192+ }
193+ if invertBuilder {
194+ filterArgs .Add ("f.binvert" , "on" )
195+ }
173196 if minTxCount != "" {
174197 filterArgs .Add ("f.mintx" , minTxCount )
175198 }
@@ -199,19 +222,20 @@ func buildFilteredBlocksPageData(ctx context.Context, pageIdx uint64, pageSize u
199222 }
200223 if len (displayMap ) == 0 {
201224 displayMap = map [uint64 ]bool {
202- 1 : true , // Epoch
203- 2 : true , // Block Number
204- 3 : true , // Slot
205- 4 : true , // Status
206- 5 : true , // Time
207- 6 : true , // Tx Count
208- 7 : true , // Blob Count
209- 8 : true , // Gas Usage
210- 9 : true , // Gas Limit
211- 10 : true , // MEV Block
212- 11 : true , // Block Size
213- 12 : true , // Extra Data
214- 13 : false , // Fee Recipient
225+ 1 : true , // Epoch
226+ 2 : true , // Block Number
227+ 3 : true , // Slot
228+ 4 : true , // Status
229+ 5 : true , // Time
230+ 6 : true , // Tx Count
231+ 7 : true , // Blob Count
232+ 8 : true , // Gas Usage
233+ 9 : true , // Gas Limit
234+ 10 : ! gloasActive , // MEV Block (replaced by Builder once gloas is active)
235+ 11 : true , // Block Size
236+ 12 : true , // Extra Data
237+ 13 : false , // Fee Recipient
238+ 14 : gloasActive , // Builder (shown once gloas is active)
215239 }
216240 } else {
217241 displayMask := uint64 (0 )
@@ -234,6 +258,9 @@ func buildFilteredBlocksPageData(ctx context.Context, pageIdx uint64, pageSize u
234258 FilterMinBlockSize : minBlockSize ,
235259 FilterMaxBlockSize : maxBlockSize ,
236260 FilterWithMevBlock : withMevBlock ,
261+ FilterWithBuilder : withBuilderBlock ,
262+ FilterBuilder : builder ,
263+ FilterInvertBuilder : invertBuilder ,
237264 FilterMinTxCount : minTxCount ,
238265 FilterMaxTxCount : maxTxCount ,
239266 FilterMinBlobCount : minBlobCount ,
@@ -251,10 +278,13 @@ func buildFilteredBlocksPageData(ctx context.Context, pageIdx uint64, pageSize u
251278 DisplayGasUsage : displayMap [8 ],
252279 DisplayGasLimit : displayMap [9 ],
253280 DisplayMevBlock : displayMap [10 ],
281+ DisplayBuilder : displayMap [14 ],
254282 DisplayBlockSize : displayMap [11 ],
255283 DisplayElExtraData : displayMap [12 ],
256284 DisplayFeeRecipient : displayMap [13 ],
257285 DisplayColCount : uint64 (len (displayMap )),
286+
287+ IsGloasActive : gloasActive ,
258288 }
259289 logrus .Debugf ("blocks_filtered page called: %v:%v [%v]" , pageIdx , pageSize , extradata )
260290 if pageIdx == 0 {
@@ -278,11 +308,20 @@ func buildFilteredBlocksPageData(ctx context.Context, pageIdx uint64, pageSize u
278308
279309 pageData .Blocks = make ([]* models.BlocksFilteredPageDataBlock , 0 )
280310 blockFilter := & dbtypes.BlockFilter {
281- ExtraData : extradata ,
282- InvertExtraData : invertextradata ,
283- WithOrphaned : 0 ,
284- WithMissing : 0 ,
285- WithMevBlock : withMevBlock ,
311+ ExtraData : extradata ,
312+ InvertExtraData : invertextradata ,
313+ WithOrphaned : 0 ,
314+ WithMissing : 0 ,
315+ WithMevBlock : withMevBlock ,
316+ WithBuilderBlock : withBuilderBlock ,
317+ }
318+
319+ if builder != "" {
320+ builderIdx , err := strconv .ParseInt (builder , 10 , 64 )
321+ if err == nil {
322+ blockFilter .BuilderIndex = & builderIdx
323+ blockFilter .InvertBuilder = invertBuilder
324+ }
286325 }
287326
288327 if minGasUsed != "" {
@@ -438,6 +477,19 @@ func buildFilteredBlocksPageData(ctx context.Context, pageIdx uint64, pageSize u
438477 blockData .Status = 1
439478 }
440479
480+ // Add builder info (build source for the Builder column)
481+ if pageData .DisplayBuilder && dbBlock .Block .Status > 0 {
482+ if dbBlock .Block .BuilderIndex == - 1 {
483+ blockData .HasBuilder = true
484+ blockData .BuilderIndex = math .MaxUint64 // self-built sentinel
485+ } else if dbBlock .Block .BuilderIndex >= 0 {
486+ blockData .HasBuilder = true
487+ blockData .BuilderIndex = uint64 (dbBlock .Block .BuilderIndex )
488+ blockData .BuilderName = services .GlobalBeaconService .GetValidatorName (uint64 (dbBlock .Block .BuilderIndex ) | services .BuilderIndexFlag )
489+ blockData .BuilderURL = services .GlobalBeaconService .GetBuilderURL (uint64 (dbBlock .Block .BuilderIndex ))
490+ }
491+ }
492+
441493 pageData .Blocks = append (pageData .Blocks , blockData )
442494 }
443495 pageData .BlockCount = uint64 (len (pageData .Blocks ))
0 commit comments