Skip to content

Commit 7fdfc67

Browse files
authored
Merge pull request #532 from ethpandaops/pk910/column-display-mask
beautify column display arg format, fix slot list views with js disabled
2 parents b92516c + 2031b5a commit 7fdfc67

File tree

7 files changed

+146
-87
lines changed

7 files changed

+146
-87
lines changed

handlers/blocks.go

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"math"
77
"net/http"
8-
"sort"
98
"strconv"
109
"strings"
1110
"time"
@@ -41,9 +40,9 @@ func Blocks(w http.ResponseWriter, r *http.Request) {
4140
if urlArgs.Has("s") {
4241
firstSlot, _ = strconv.ParseUint(urlArgs.Get("s"), 10, 64)
4342
}
44-
var displayColumns string = ""
43+
var displayColumns uint64 = 0
4544
if urlArgs.Has("d") {
46-
displayColumns = urlArgs.Get("d")
45+
displayColumns = utils.DecodeUint64BitfieldFromQuery(r.URL.RawQuery, "d")
4746
}
4847

4948
var pageError error
@@ -61,7 +60,7 @@ func Blocks(w http.ResponseWriter, r *http.Request) {
6160
}
6261
}
6362

64-
func getBlocksPageData(firstSlot uint64, pageSize uint64, displayColumns string) (*models.BlocksPageData, error) {
63+
func getBlocksPageData(firstSlot uint64, pageSize uint64, displayColumns uint64) (*models.BlocksPageData, error) {
6564
pageData := &models.BlocksPageData{}
6665
pageCacheKey := fmt.Sprintf("blocks:%v:%v:%v", firstSlot, pageSize, displayColumns)
6766
pageRes, pageErr := services.GlobalFrontendCache.ProcessCachedPage(pageCacheKey, true, pageData, func(pageCall *services.FrontendCacheProcessingPage) interface{} {
@@ -79,20 +78,17 @@ func getBlocksPageData(firstSlot uint64, pageSize uint64, displayColumns string)
7978
return pageData, pageErr
8079
}
8180

82-
func buildBlocksPageData(firstSlot uint64, pageSize uint64, displayColumns string) (*models.BlocksPageData, time.Duration) {
81+
func buildBlocksPageData(firstSlot uint64, pageSize uint64, displayColumns uint64) (*models.BlocksPageData, time.Duration) {
8382
logrus.Debugf("blocks page called: %v:%v", firstSlot, pageSize)
8483
pageData := &models.BlocksPageData{}
8584

8685
// Set display columns based on the parameter
8786
displayMap := map[uint64]bool{}
88-
displayList := []string{}
89-
if displayColumns != "" {
90-
for _, col := range strings.Split(displayColumns, " ") {
91-
colNum, err := strconv.ParseUint(col, 10, 64)
92-
if err != nil {
93-
continue
87+
if displayColumns != 0 {
88+
for i := 0; i < 64; i++ {
89+
if displayColumns&(1<<i) != 0 {
90+
displayMap[uint64(i+1)] = true
9491
}
95-
displayMap[colNum] = true
9692
}
9793
}
9894
if len(displayMap) == 0 {
@@ -117,10 +113,18 @@ func buildBlocksPageData(firstSlot uint64, pageSize uint64, displayColumns strin
117113
18: false,
118114
19: false,
119115
}
120-
} else {
121-
for col := range displayMap {
122-
displayList = append(displayList, fmt.Sprintf("%v", col))
116+
}
117+
118+
displayMask := uint64(0)
119+
for col := range displayMap {
120+
if col == 0 || col > 64 {
121+
continue
123122
}
123+
displayMask |= 1 << (col - 1)
124+
}
125+
displayColumnsParam := ""
126+
if displayMask != 0 {
127+
displayColumnsParam = fmt.Sprintf("&d=0x%x", displayMask)
124128
}
125129

126130
pageData.DisplayChain = displayMap[1]
@@ -144,17 +148,6 @@ func buildBlocksPageData(firstSlot uint64, pageSize uint64, displayColumns strin
144148
pageData.DisplayExecTime = displayMap[19]
145149
pageData.DisplayColCount = uint64(len(displayMap))
146150

147-
// Build column selection URL parameter if not default
148-
displayColumnsParam := ""
149-
if len(displayList) > 0 {
150-
sort.Slice(displayList, func(a, b int) bool {
151-
colA, _ := strconv.ParseUint(displayList[a], 10, 64)
152-
colB, _ := strconv.ParseUint(displayList[b], 10, 64)
153-
return colA < colB
154-
})
155-
displayColumnsParam = "&d=" + strings.Join(displayList, "+")
156-
}
157-
158151
chainState := services.GlobalBeaconService.GetChainState()
159152
currentSlot := chainState.CurrentSlot()
160153
currentEpoch := chainState.EpochOfSlot(currentSlot)
@@ -193,8 +186,8 @@ func buildBlocksPageData(firstSlot uint64, pageSize uint64, displayColumns strin
193186
// Populate UrlParams for page jump functionality
194187
pageData.UrlParams = make(map[string]string)
195188
pageData.UrlParams["c"] = fmt.Sprintf("%v", pageData.PageSize)
196-
if len(displayList) > 0 {
197-
pageData.UrlParams["d"] = strings.Join(displayList, "+")
189+
if displayMask != 0 {
190+
pageData.UrlParams["d"] = fmt.Sprintf("0x%x", displayMask)
198191
}
199192
pageData.MaxSlot = uint64(maxSlot)
200193

handlers/slots.go

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"math"
77
"net/http"
8-
"sort"
98
"strconv"
109
"strings"
1110
"time"
@@ -40,9 +39,9 @@ func Slots(w http.ResponseWriter, r *http.Request) {
4039
if urlArgs.Has("s") {
4140
firstSlot, _ = strconv.ParseUint(urlArgs.Get("s"), 10, 64)
4241
}
43-
var displayColumns string = ""
42+
var displayColumns uint64 = 0
4443
if urlArgs.Has("d") {
45-
displayColumns = urlArgs.Get("d")
44+
displayColumns = utils.DecodeUint64BitfieldFromQuery(r.URL.RawQuery, "d")
4645
}
4746

4847
var pageError error
@@ -60,7 +59,7 @@ func Slots(w http.ResponseWriter, r *http.Request) {
6059
}
6160
}
6261

63-
func getSlotsPageData(firstSlot uint64, pageSize uint64, displayColumns string) (*models.SlotsPageData, error) {
62+
func getSlotsPageData(firstSlot uint64, pageSize uint64, displayColumns uint64) (*models.SlotsPageData, error) {
6463
pageData := &models.SlotsPageData{}
6564
pageCacheKey := fmt.Sprintf("slots:%v:%v:%v", firstSlot, pageSize, displayColumns)
6665
pageRes, pageErr := services.GlobalFrontendCache.ProcessCachedPage(pageCacheKey, true, pageData, func(pageCall *services.FrontendCacheProcessingPage) interface{} {
@@ -78,20 +77,17 @@ func getSlotsPageData(firstSlot uint64, pageSize uint64, displayColumns string)
7877
return pageData, pageErr
7978
}
8079

81-
func buildSlotsPageData(firstSlot uint64, pageSize uint64, displayColumns string) (*models.SlotsPageData, time.Duration) {
80+
func buildSlotsPageData(firstSlot uint64, pageSize uint64, displayColumns uint64) (*models.SlotsPageData, time.Duration) {
8281
logrus.Debugf("slots page called: %v:%v", firstSlot, pageSize)
8382
pageData := &models.SlotsPageData{}
8483

8584
// Set display columns based on the parameter
8685
displayMap := map[uint64]bool{}
87-
displayList := []string{}
88-
if displayColumns != "" {
89-
for _, col := range strings.Split(displayColumns, " ") {
90-
colNum, err := strconv.ParseUint(col, 10, 64)
91-
if err != nil {
92-
continue
86+
if displayColumns != 0 {
87+
for i := 0; i < 64; i++ {
88+
if displayColumns&(1<<i) != 0 {
89+
displayMap[uint64(i+1)] = true
9390
}
94-
displayMap[colNum] = true
9591
}
9692
}
9793
if len(displayMap) == 0 {
@@ -122,10 +118,18 @@ func buildSlotsPageData(firstSlot uint64, pageSize uint64, displayColumns string
122118
18: !hasSnooperClients, // Disable receive delay if snooper clients exist
123119
19: hasSnooperClients, // Enable exec time if snooper clients exist
124120
}
125-
} else {
126-
for col := range displayMap {
127-
displayList = append(displayList, fmt.Sprintf("%v", col))
121+
}
122+
123+
displayMask := uint64(0)
124+
for col := range displayMap {
125+
if col == 0 || col > 64 {
126+
continue
128127
}
128+
displayMask |= 1 << (col - 1)
129+
}
130+
displayColumnsParam := ""
131+
if displayMask != 0 {
132+
displayColumnsParam = fmt.Sprintf("&d=0x%x", displayMask)
129133
}
130134

131135
pageData.DisplayChain = displayMap[1]
@@ -149,17 +153,6 @@ func buildSlotsPageData(firstSlot uint64, pageSize uint64, displayColumns string
149153
pageData.DisplayExecTime = displayMap[19]
150154
pageData.DisplayColCount = uint64(len(displayMap))
151155

152-
// Build column selection URL parameter if not default
153-
displayColumnsParam := ""
154-
if len(displayList) > 0 {
155-
sort.Slice(displayList, func(a, b int) bool {
156-
colA, _ := strconv.ParseUint(displayList[a], 10, 64)
157-
colB, _ := strconv.ParseUint(displayList[b], 10, 64)
158-
return colA < colB
159-
})
160-
displayColumnsParam = "&d=" + strings.Join(displayList, "+")
161-
}
162-
163156
chainState := services.GlobalBeaconService.GetChainState()
164157
currentSlot := chainState.CurrentSlot()
165158
currentEpoch := chainState.EpochOfSlot(currentSlot)
@@ -198,8 +191,8 @@ func buildSlotsPageData(firstSlot uint64, pageSize uint64, displayColumns string
198191
// Populate UrlParams for page jump functionality
199192
pageData.UrlParams = make(map[string]string)
200193
pageData.UrlParams["c"] = fmt.Sprintf("%v", pageData.PageSize)
201-
if len(displayList) > 0 {
202-
pageData.UrlParams["d"] = strings.Join(displayList, "+")
194+
if displayMask != 0 {
195+
pageData.UrlParams["d"] = fmt.Sprintf("0x%x", displayMask)
203196
}
204197
pageData.MaxSlot = uint64(maxSlot)
205198

handlers/slots_filtered.go

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55
"net/http"
66
"net/url"
7-
"sort"
87
"strconv"
98
"strings"
109

@@ -38,9 +37,9 @@ func SlotsFiltered(w http.ResponseWriter, r *http.Request) {
3837
if urlArgs.Has("s") {
3938
pageIdx, _ = strconv.ParseUint(urlArgs.Get("s"), 10, 64)
4039
}
41-
var displayColumns string = ""
40+
var displayColumns uint64 = 0
4241
if urlArgs.Has("d") {
43-
displayColumns = urlArgs.Get("d")
42+
displayColumns = utils.DecodeUint64BitfieldFromQuery(r.URL.RawQuery, "d")
4443
}
4544

4645
var graffiti string
@@ -136,7 +135,7 @@ func SlotsFiltered(w http.ResponseWriter, r *http.Request) {
136135
}
137136
}
138137

139-
func getFilteredSlotsPageData(pageIdx uint64, pageSize uint64, graffiti string, invertgraffiti bool, extradata string, invertextradata bool, proposer string, pname string, invertproposer bool, withOrphaned uint8, withMissing uint8, minSyncAgg string, maxSyncAgg string, minExecTime string, maxExecTime string, minTxCount string, maxTxCount string, minBlobCount string, maxBlobCount string, forkIds string, displayColumns string) (*models.SlotsFilteredPageData, error) {
138+
func getFilteredSlotsPageData(pageIdx uint64, pageSize uint64, graffiti string, invertgraffiti bool, extradata string, invertextradata bool, proposer string, pname string, invertproposer bool, withOrphaned uint8, withMissing uint8, minSyncAgg string, maxSyncAgg string, minExecTime string, maxExecTime string, minTxCount string, maxTxCount string, minBlobCount string, maxBlobCount string, forkIds string, displayColumns uint64) (*models.SlotsFilteredPageData, error) {
140139
pageData := &models.SlotsFilteredPageData{}
141140
pageCacheKey := fmt.Sprintf("slots_filtered:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v:%v", pageIdx, pageSize, graffiti, invertgraffiti, extradata, invertextradata, proposer, pname, invertproposer, withOrphaned, withMissing, minSyncAgg, maxSyncAgg, minExecTime, maxExecTime, minTxCount, maxTxCount, minBlobCount, maxBlobCount, forkIds, displayColumns)
142141
pageRes, pageErr := services.GlobalFrontendCache.ProcessCachedPage(pageCacheKey, true, pageData, func(_ *services.FrontendCacheProcessingPage) interface{} {
@@ -152,7 +151,7 @@ func getFilteredSlotsPageData(pageIdx uint64, pageSize uint64, graffiti string,
152151
return pageData, pageErr
153152
}
154153

155-
func buildFilteredSlotsPageData(pageIdx uint64, pageSize uint64, graffiti string, invertgraffiti bool, extradata string, invertextradata bool, proposer string, pname string, invertproposer bool, withOrphaned uint8, withMissing uint8, minSyncAgg string, maxSyncAgg string, minExecTime string, maxExecTime string, minTxCount string, maxTxCount string, minBlobCount string, maxBlobCount string, forkIds string, displayColumns string) *models.SlotsFilteredPageData {
154+
func buildFilteredSlotsPageData(pageIdx uint64, pageSize uint64, graffiti string, invertgraffiti bool, extradata string, invertextradata bool, proposer string, pname string, invertproposer bool, withOrphaned uint8, withMissing uint8, minSyncAgg string, maxSyncAgg string, minExecTime string, maxExecTime string, minTxCount string, maxTxCount string, minBlobCount string, maxBlobCount string, forkIds string, displayColumns uint64) *models.SlotsFilteredPageData {
156155
chainState := services.GlobalBeaconService.GetChainState()
157156
filterArgs := url.Values{}
158157
if graffiti != "" {
@@ -217,17 +216,14 @@ func buildFilteredSlotsPageData(pageIdx uint64, pageSize uint64, graffiti string
217216
}
218217

219218
displayMap := map[uint64]bool{}
220-
if displayColumns != "" {
221-
for _, col := range strings.Split(displayColumns, " ") {
222-
colNum, err := strconv.ParseUint(col, 10, 64)
223-
if err != nil {
224-
continue
219+
if displayColumns != 0 {
220+
for i := 0; i < 64; i++ {
221+
if displayColumns&(1<<i) != 0 {
222+
displayMap[uint64(i+1)] = true
225223
}
226-
displayMap[colNum] = true
227224
}
228225
}
229226
if len(displayMap) == 0 {
230-
231227
displayMap = map[uint64]bool{
232228
1: true,
233229
2: true,
@@ -249,20 +245,14 @@ func buildFilteredSlotsPageData(pageIdx uint64, pageSize uint64, graffiti string
249245
18: hasSnooperClients, // Enable exec time if snooper clients exist
250246
}
251247
} else {
252-
displayList := make([]uint64, len(displayMap))
253-
displayIdx := 0
248+
displayMask := uint64(0)
254249
for col := range displayMap {
255-
displayList[displayIdx] = col
256-
displayIdx++
257-
}
258-
sort.Slice(displayList, func(a, b int) bool {
259-
return displayList[a] < displayList[b]
260-
})
261-
displayStr := make([]string, len(displayMap))
262-
for idx, col := range displayList {
263-
displayStr[idx] = fmt.Sprintf("%v", col)
250+
if col == 0 || col > 64 {
251+
continue
252+
}
253+
displayMask |= 1 << (col - 1)
264254
}
265-
filterArgs.Add("d", strings.Join(displayStr, " "))
255+
filterArgs.Add("d", fmt.Sprintf("%v", displayMask))
266256
}
267257

268258
pageData := &models.SlotsFilteredPageData{

templates/blocks/blocks.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ <h1 class="h4 mb-1 mb-md-0"><i class="fas fa-cube mx-2"></i>Blocks</h1>
5151
<option value="12" {{ if .DisplayGraffiti }}selected{{ end }}>Graffiti</option>
5252
<option value="13" {{ if .DisplayElExtraData }}selected{{ end }}>Extra Data</option>
5353
</select>
54+
<noscript>
55+
<button type="submit" class="btn btn-outline-secondary" style="height: 38px;">
56+
Apply
57+
</button>
58+
</noscript>
5459
</div>
5560
</div>
5661
<div class="col-3 col-md-3 text-end">
@@ -273,9 +278,13 @@ <h1 class="h4 mb-1 mb-md-0"><i class="fas fa-cube mx-2"></i>Blocks</h1>
273278
return el.selected;
274279
}).map(function(el) {
275280
return el.value;
276-
}).join(" ");
281+
});
277282
if(displayColumns.length > 0) {
278-
$(this).find("#displayColumnsField").prop('name', 'd').val(displayColumns);
283+
var displayMask = 0;
284+
displayColumns.forEach(function(col) {
285+
displayMask |= 1 << (parseInt(col) - 1);
286+
});
287+
$(this).find("#displayColumnsField").prop('name', 'd').val("0x" + displayMask.toString(16));
279288
}
280289
});
281290
$(function() {

templates/slots/slots.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ <h1 class="h4 mb-1 mb-md-0"><i class="fas fa-table-list mx-2"></i>Slots</h1>
1414
<div class="card-body px-0 py-3">
1515
<form action="/slots" method="get" id="slotsForm">
1616
<div class="row">
17-
<div class="col-9 col-md-9">
17+
<div class="col-8 col-md-8">
1818
{{ if not .IsDefaultPage }}
1919
<input name="s" type="hidden" value="{{ .CurrentPageSlot }}">
2020
{{ end }}
@@ -51,6 +51,11 @@ <h1 class="h4 mb-1 mb-md-0"><i class="fas fa-table-list mx-2"></i>Slots</h1>
5151
<option value="12" {{ if .DisplayGraffiti }}selected{{ end }}>Graffiti</option>
5252
<option value="13" {{ if .DisplayElExtraData }}selected{{ end }}>Extra Data</option>
5353
</select>
54+
<noscript>
55+
<button type="submit" class="btn btn-outline-secondary" style="height: 38px;">
56+
Apply
57+
</button>
58+
</noscript>
5459
</div>
5560
</div>
5661
<div class="col-3 col-md-3 text-end">
@@ -273,9 +278,13 @@ <h1 class="h4 mb-1 mb-md-0"><i class="fas fa-table-list mx-2"></i>Slots</h1>
273278
return el.selected;
274279
}).map(function(el) {
275280
return el.value;
276-
}).join(" ");
281+
});
277282
if(displayColumns.length > 0) {
278-
$(this).find("#displayColumnsField").prop('name', 'd').val(displayColumns);
283+
var displayMask = 0;
284+
displayColumns.forEach(function(col) {
285+
displayMask |= 1 << (parseInt(col) - 1);
286+
});
287+
$(this).find("#displayColumnsField").prop('name', 'd').val("0x" + displayMask.toString(16));
279288
}
280289
});
281290
$(function() {

templates/slots_filtered/slots_filtered.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,13 @@ <h1 class="h4 mb-1 mb-md-0"><i class="fas fa-cube mx-2"></i>Filtered Slots</h1>
448448
return el.selected;
449449
}).map(function(el) {
450450
return el.value;
451-
}).join(" ");
451+
});
452452
if(displayColumns.length > 0) {
453-
$(this).find("#displayColumnsField").prop('name', 'd').val(displayColumns);
453+
var displayMask = 0;
454+
displayColumns.forEach(function(col) {
455+
displayMask |= 1 << (parseInt(col) - 1);
456+
});
457+
$(this).find("#displayColumnsField").prop('name', 'd').val("0x" + displayMask.toString(16));
454458
}
455459
});
456460
$(function() {

0 commit comments

Comments
 (0)