Skip to content

Commit

Permalink
start implementation of submit consolidations page
Browse files Browse the repository at this point in the history
  • Loading branch information
pk910 committed Oct 31, 2024
1 parent 68e31f8 commit 856d4ce
Show file tree
Hide file tree
Showing 19 changed files with 945 additions and 19 deletions.
1 change: 1 addition & 0 deletions .hack/devnet/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ frontend:
validatorNamesYaml: "${__dir}/generated-validator-ranges.yaml"
showSensitivePeerInfos: true
showSubmitDeposit: true
showSubmitConsolidation: true
beaconapi:
localCacheSize: 10
redisCacheAddr: ""
Expand Down
1 change: 1 addition & 0 deletions cmd/dora-explorer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ func startFrontend(webserver *http.Server) {
router.HandleFunc("/validators/slashings", handlers.Slashings).Methods("GET")
router.HandleFunc("/validators/el_withdrawals", handlers.ElWithdrawals).Methods("GET")
router.HandleFunc("/validators/el_consolidations", handlers.ElConsolidations).Methods("GET")
router.HandleFunc("/validators/submit_consolidations", handlers.SubmitConsolidation).Methods("GET")
router.HandleFunc("/validator/{idxOrPubKey}", handlers.Validator).Methods("GET")
router.HandleFunc("/validator/{index}/slots", handlers.ValidatorSlots).Methods("GET")

Expand Down
1 change: 1 addition & 0 deletions config/default.config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ frontend:
showSensitivePeerInfos: false
showPeerDASInfos: false
showSubmitDeposit: false
showSubmitConsolidation: false

beaconapi:
# beacon node rpc endpoints
Expand Down
25 changes: 18 additions & 7 deletions handlers/pageData.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,26 @@ func createMenuItems(active string) []types.MainMenuItem {
},
})

submitLinks := []types.NavigationLink{}
if utils.Config.Frontend.ShowSubmitDeposit {
submitLinks = append(submitLinks, types.NavigationLink{
Label: "Submit Deposits",
Path: "/validators/deposits/submit",
Icon: "fa-file-import",
})
}

if utils.Config.Frontend.ShowSubmitConsolidation {
submitLinks = append(submitLinks, types.NavigationLink{
Label: "Submit Consolidations",
Path: "/validators/submit_consolidations",
Icon: "fa-square-plus",
})
}

if len(submitLinks) > 0 {
validatorMenu = append(validatorMenu, types.NavigationGroup{
Links: []types.NavigationLink{
{
Label: "Submit Deposits",
Path: "/validators/deposits/submit",
Icon: "fa-file-import",
},
},
Links: submitLinks,
})
}

Expand Down
159 changes: 159 additions & 0 deletions handlers/submit_consolidation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package handlers

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"time"

v1 "github.com/attestantio/go-eth2-client/api/v1"
"github.com/ethereum/go-ethereum/common"
"github.com/sirupsen/logrus"

"github.com/ethpandaops/dora/indexer/execution"
"github.com/ethpandaops/dora/services"
"github.com/ethpandaops/dora/templates"
"github.com/ethpandaops/dora/types/models"
"github.com/ethpandaops/dora/utils"
)

// SubmitConsolidation will submit a consolidation request
func SubmitConsolidation(w http.ResponseWriter, r *http.Request) {
var submitConsolidationTemplateFiles = append(layoutTemplateFiles,
"submit_consolidation/submit_consolidation.html",
)
var pageTemplate = templates.GetTemplate(submitConsolidationTemplateFiles...)

if !utils.Config.Frontend.ShowSubmitConsolidation {
handlePageError(w, r, errors.New("submit consolidation is not enabled"))
return
}

query := r.URL.Query()
if query.Has("ajax") {
err := handleSubmitConsolidationPageDataAjax(w, r)
if err != nil {
handlePageError(w, r, err)
}
return
}

pageData, pageError := getSubmitConsolidationPageData()
if pageError != nil {
handlePageError(w, r, pageError)
return
}
if pageData == nil {
data := InitPageData(w, r, "blockchain", "/submit_consolidation", "Submit Consolidation", submitConsolidationTemplateFiles)
w.Header().Set("Content-Type", "text/html")
if handleTemplateError(w, r, "submit_consolidation.go", "Submit Consolidation", "", pageTemplate.ExecuteTemplate(w, "layout", data)) != nil {
return // an error has occurred and was processed
}
return
}

data := InitPageData(w, r, "blockchain", "/submit_consolidation", "Submit Consolidation", submitConsolidationTemplateFiles)
data.Data = pageData
w.Header().Set("Content-Type", "text/html")
if handleTemplateError(w, r, "submit_consolidation.go", "Submit Consolidation", "", pageTemplate.ExecuteTemplate(w, "layout", data)) != nil {
return // an error has occurred and was processed
}
}

func getSubmitConsolidationPageData() (*models.SubmitConsolidationPageData, error) {
pageData := &models.SubmitConsolidationPageData{}
pageCacheKey := "submit_consolidation"
pageRes, pageErr := services.GlobalFrontendCache.ProcessCachedPage(pageCacheKey, true, pageData, func(pageCall *services.FrontendCacheProcessingPage) interface{} {
pageData, cacheTimeout := buildSubmitConsolidationPageData()
pageCall.CacheTimeout = cacheTimeout
return pageData
})
if pageErr == nil && pageRes != nil {
resData, resOk := pageRes.(*models.SubmitConsolidationPageData)
if !resOk {
return nil, ErrInvalidPageModel
}
pageData = resData
}
return pageData, pageErr
}

func buildSubmitConsolidationPageData() (*models.SubmitConsolidationPageData, time.Duration) {
logrus.Debugf("submit consolidation page called")

chainState := services.GlobalBeaconService.GetChainState()
specs := chainState.GetSpecs()

pageData := &models.SubmitConsolidationPageData{
NetworkName: specs.ConfigName,
PublicRPCUrl: utils.Config.Frontend.PublicRPCUrl,
RainbowkitProjectId: utils.Config.Frontend.RainbowkitProjectId,
ChainId: specs.DepositChainId,
ConsolidationContract: execution.ConsolidationContractAddr,
}

return pageData, 1 * time.Hour
}

func handleSubmitConsolidationPageDataAjax(w http.ResponseWriter, r *http.Request) error {
query := r.URL.Query()
var pageData interface{}

switch query.Get("ajax") {
case "load_validators":
address := query.Get("address")
addressBytes := common.HexToAddress(address)

validators := services.GlobalBeaconService.GetCachedValidatorSet()
result := []models.SubmitConsolidationPageDataValidator{}
for _, validator := range validators {
if validator.Validator.WithdrawalCredentials[0] == 0x00 && false {
continue
}

if !bytes.Equal(validator.Validator.WithdrawalCredentials[12:], addressBytes[:]) && false {
continue
}

var status string
if strings.HasPrefix(validator.Status.String(), "pending") {
status = "Pending"
} else if validator.Status == v1.ValidatorStateActiveOngoing {
status = "Active"
} else if validator.Status == v1.ValidatorStateActiveExiting {
status = "Exiting"
} else if validator.Status == v1.ValidatorStateActiveSlashed {
status = "Slashed"
} else if validator.Status == v1.ValidatorStateExitedUnslashed {
status = "Exited"
} else if validator.Status == v1.ValidatorStateExitedSlashed {
status = "Slashed"
} else {
status = validator.Status.String()
}

result = append(result, models.SubmitConsolidationPageDataValidator{
Index: uint64(validator.Index),
Pubkey: validator.Validator.PublicKey.String(),
Balance: uint64(validator.Balance),
CredType: fmt.Sprintf("%x", validator.Validator.WithdrawalCredentials[0]),
Status: status,
})
}

pageData = result
default:
return errors.New("invalid ajax request")
}

w.Header().Set("Content-Type", "application/json")
err := json.NewEncoder(w).Encode(pageData)
if err != nil {
logrus.WithError(err).Error("error encoding index data")
http.Error(w, "Internal server error", http.StatusServiceUnavailable)
}
return nil
}
4 changes: 2 additions & 2 deletions indexer/execution/consolidation_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/ethpandaops/dora/utils"
)

const consolidationContractAddr = "0x01aBEa29659e5e97C95107F20bb753cD3e09bBBb"
const ConsolidationContractAddr = "0x01aBEa29659e5e97C95107F20bb753cD3e09bBBb"

// ConsolidationIndexer is the indexer for the eip-7251 consolidation system contract
type ConsolidationIndexer struct {
Expand Down Expand Up @@ -54,7 +54,7 @@ func NewConsolidationIndexer(indexer *IndexerCtx) *ConsolidationIndexer {
&contractIndexerOptions[dbtypes.ConsolidationRequestTx]{
stateKey: "indexer.consolidationindexer",
batchSize: batchSize,
contractAddress: common.HexToAddress(consolidationContractAddr),
contractAddress: common.HexToAddress(ConsolidationContractAddr),
deployBlock: uint64(utils.Config.ExecutionApi.ElectraDeployBlock),
dequeueRate: specs.MaxConsolidationRequestsPerPayload,

Expand Down
4 changes: 2 additions & 2 deletions indexer/execution/withdrawal_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/ethpandaops/dora/utils"
)

const withdrawalContractAddr = "0x09Fc772D0857550724b07B850a4323f39112aAaA"
const WithdrawalContractAddr = "0x09Fc772D0857550724b07B850a4323f39112aAaA"

// WithdrawalIndexer is the indexer for the eip-7002 consolidation system contract
type WithdrawalIndexer struct {
Expand Down Expand Up @@ -55,7 +55,7 @@ func NewWithdrawalIndexer(indexer *IndexerCtx) *WithdrawalIndexer {
&contractIndexerOptions[dbtypes.WithdrawalRequestTx]{
stateKey: "indexer.withdrawalindexer",
batchSize: batchSize,
contractAddress: common.HexToAddress(withdrawalContractAddr),
contractAddress: common.HexToAddress(WithdrawalContractAddr),
deployBlock: uint64(utils.Config.ExecutionApi.ElectraDeployBlock),
dequeueRate: specs.MaxWithdrawalRequestsPerPayload,

Expand Down
68 changes: 68 additions & 0 deletions templates/submit_consolidation/submit_consolidation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{{ define "page" }}
<div class="container mt-2">
<div class="d-md-flex py-2 justify-content-md-between">
<h1 class="h4 mb-1 mb-md-0">
<i class="fas fa-square-plus mx-2"></i> Submit Consolidation
</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb font-size-1 mb-0" style="padding:0; background-color:transparent;">
<li class="breadcrumb-item"><a href="/" title="Home">Home</a></li>
<li class="breadcrumb-item"><a href="/validators" title="Validators">Validators</a></li>
<li class="breadcrumb-item active" aria-current="page">Submit Consolidation</li>
</ol>
</nav>
</div>

<div id="header-placeholder" style="height:35px;"></div>

<div class="card mt-2">
<div class="card-body">
<noscript>
<div class="alert alert-warning">
<i class="fa fa-exclamation-triangle"></i>
This page requires JavaScript to be enabled.
</div>
</noscript>
<div id="submit-consolidation-container"></div>
</div>
</div>
</div>

{{ end }}
{{ define "js" }}
<script src="/ui-package/react-ui.js"></script>
<script type="text/javascript">
$(function() {
window.doraUiComponents.SubmitConsolidationsForm(
document.getElementById("submit-consolidation-container"),
{
wagmiConfig: {
projectId: "{{ .RainbowkitProjectId }}",
chains: [
{
chainId: {{ .ChainId }},
name: "{{ .NetworkName }}",
rpcUrl: "{{ .PublicRPCUrl }}",
tokenName: "Ethereum",
tokenSymbol: "ETH",
}
]
},
submitConsolidationsConfig: {
consolidationContract: "{{ .ConsolidationContract }}",
loadValidatorsCallback: function(address) {
return fetch(`?ajax=load_validators&address=${address}`)
.then(response => response.json())
.then(data => {
console.log(data);
return data;
});
}
}
}
);
});
</script>
{{ end }}
{{ define "css" }}
{{ end }}
1 change: 1 addition & 0 deletions test-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ frontend:
showSensitivePeerInfos: true
showPeerDASInfos: true
showSubmitDeposit: true
showSubmitConsolidation: true


beaconapi:
Expand Down
7 changes: 4 additions & 3 deletions types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ type Config struct {
HttpIdleTimeout time.Duration `yaml:"httpIdleTimeout" envconfig:"FRONTEND_HTTP_IDLE_TIMEOUT"`
AllowDutyLoading bool `yaml:"allowDutyLoading" envconfig:"FRONTEND_ALLOW_DUTY_LOADING"`

ShowSensitivePeerInfos bool `yaml:"showSensitivePeerInfos" envconfig:"FRONTEND_SHOW_SENSITIVE_PEER_INFOS"`
ShowPeerDASInfos bool `yaml:"showPeerDASInfos" envconfig:"FRONTEND_SHOW_PEER_DAS_INFOS"`
ShowSubmitDeposit bool `yaml:"showSubmitDeposit" envconfig:"FRONTEND_SHOW_SUBMIT_DEPOSIT"`
ShowSensitivePeerInfos bool `yaml:"showSensitivePeerInfos" envconfig:"FRONTEND_SHOW_SENSITIVE_PEER_INFOS"`
ShowPeerDASInfos bool `yaml:"showPeerDASInfos" envconfig:"FRONTEND_SHOW_PEER_DAS_INFOS"`
ShowSubmitDeposit bool `yaml:"showSubmitDeposit" envconfig:"FRONTEND_SHOW_SUBMIT_DEPOSIT"`
ShowSubmitConsolidation bool `yaml:"showSubmitConsolidation" envconfig:"FRONTEND_SHOW_SUBMIT_CONSOLIDATION"`
} `yaml:"frontend"`

RateLimit struct {
Expand Down
17 changes: 17 additions & 0 deletions types/models/submit_consolidation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package models

type SubmitConsolidationPageData struct {
NetworkName string `json:"netname"`
PublicRPCUrl string `json:"pubrpc"`
RainbowkitProjectId string `json:"rainbowkit"`
ChainId uint64 `json:"chainid"`
ConsolidationContract string `json:"consolidationcontract"`
}

type SubmitConsolidationPageDataValidator struct {
Index uint64 `json:"index"`
Pubkey string `json:"pubkey"`
Balance uint64 `json:"balance"`
CredType string `json:"credtype"`
Status string `json:"status"`
}
Loading

0 comments on commit 856d4ce

Please sign in to comment.