Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions db/deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,15 @@ func GetDepositsFiltered(ctx context.Context, offset uint64, limit uint32, canon
}

if len(txFilter.WithdrawalAddress) > 0 {
// 0x01 = ETH1, 0x02 = compounding, 0x03 = builder deposit
// 0x01 = ETH1, 0x02 = compounding, 0xB0 = builder deposit
wdcreds1 := make([]byte, 32)
wdcreds1[0] = 0x01
copy(wdcreds1[12:], txFilter.WithdrawalAddress)
wdcreds2 := make([]byte, 32)
wdcreds2[0] = 0x02
copy(wdcreds2[12:], txFilter.WithdrawalAddress)
wdcreds3 := make([]byte, 32)
wdcreds3[0] = 0x03
wdcreds3[0] = 0xB0
copy(wdcreds3[12:], txFilter.WithdrawalAddress)
args = append(args, wdcreds1, wdcreds2, wdcreds3)
fmt.Fprintf(&sql, " %v (deposits.withdrawalcredentials = $%v OR deposits.withdrawalcredentials = $%v OR deposits.withdrawalcredentials = $%v)", filterOp, len(args)-2, len(args)-1, len(args))
Expand Down
2 changes: 1 addition & 1 deletion handlers/api/deposits_included_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func APIDepositsIncludedV1(w http.ResponseWriter, r *http.Request) {
seen := map[uint8]bool{}
for _, v := range credVals {
t, err := strconv.ParseUint(v, 10, 8)
if err != nil || t > 3 || seen[uint8(t)] {
if err != nil || (t > 2 && t != 0xB0) || seen[uint8(t)] {
continue
}
seen[uint8(t)] = true
Expand Down
12 changes: 6 additions & 6 deletions handlers/deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ func buildDepositsPageData(ctx context.Context, firstEpoch uint64, pageSize uint
// load initiated deposits
dbDepositTxs := db.GetDepositTxs(ctx, 0, 20)
for _, depositTx := range dbDepositTxs {
// Check if this is a builder deposit (0x03 withdrawal credentials)
isBuilder := len(depositTx.WithdrawalCredentials) > 0 && depositTx.WithdrawalCredentials[0] == 0x03
// Check if this is a builder deposit (0xB0 withdrawal credentials)
isBuilder := len(depositTx.WithdrawalCredentials) > 0 && depositTx.WithdrawalCredentials[0] == 0xB0

depositTxData := &models.DepositsPageDataInitiatedDeposit{
Index: depositTx.Index,
Expand Down Expand Up @@ -251,9 +251,9 @@ func buildDepositsPageData(ctx context.Context, firstEpoch uint64, pageSize uint

dbDeposits, _ := services.GlobalBeaconService.GetDepositRequestsByFilter(ctx, depositFilter, 0, uint32(20))
for _, deposit := range dbDeposits {
// Check if this is a builder deposit (0x03 withdrawal credentials)
// Check if this is a builder deposit (0xB0 withdrawal credentials)
wdCreds := deposit.WithdrawalCredentials()
isBuilder := len(wdCreds) > 0 && wdCreds[0] == 0x03
isBuilder := len(wdCreds) > 0 && wdCreds[0] == 0xB0

depositData := &models.DepositsPageDataIncludedDeposit{
PublicKey: deposit.PublicKey(),
Expand Down Expand Up @@ -376,9 +376,9 @@ func buildDepositsPageData(ctx context.Context, firstEpoch uint64, pageSize uint
}

for _, queueEntry := range queuedDeposits.Queue[:limit] {
// Check if this is a builder deposit (0x03 withdrawal credentials)
// Check if this is a builder deposit (0xB0 withdrawal credentials)
wdCreds := queueEntry.PendingDeposit.WithdrawalCredentials[:]
isBuilder := len(wdCreds) > 0 && wdCreds[0] == 0x03
isBuilder := len(wdCreds) > 0 && wdCreds[0] == 0xB0

// EpochEstimate is the churn-based epoch for normal deposits and the
// validator's withdrawable epoch for postponed ones; 0 means unknown.
Expand Down
4 changes: 2 additions & 2 deletions handlers/included_deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func IncludedDeposits(w http.ResponseWriter, r *http.Request) {
seen := map[uint8]bool{}
for _, v := range vals {
t, err := strconv.ParseUint(v, 10, 8)
if err != nil || t > 3 || seen[uint8(t)] {
if err != nil || (t > 2 && t != 0xB0) || seen[uint8(t)] {
continue
}
seen[uint8(t)] = true
Expand Down Expand Up @@ -222,7 +222,7 @@ func buildFilteredIncludedDepositsPageData(ctx context.Context, pageIdx uint64,

for _, deposit := range dbDeposits {
wdCreds := deposit.WithdrawalCredentials()
isBuilder := len(wdCreds) > 0 && wdCreds[0] == 0x03
isBuilder := len(wdCreds) > 0 && wdCreds[0] == 0xB0

depositData := &models.IncludedDepositsPageDataDeposit{
PublicKey: deposit.PublicKey(),
Expand Down
2 changes: 1 addition & 1 deletion handlers/initiated_deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func buildFilteredInitiatedDepositsPageData(ctx context.Context, pageIdx uint64,
}

for _, depositTx := range dbDepositTxs {
isBuilder := len(depositTx.WithdrawalCredentials) > 0 && depositTx.WithdrawalCredentials[0] == 0x03
isBuilder := len(depositTx.WithdrawalCredentials) > 0 && depositTx.WithdrawalCredentials[0] == 0xB0

depositTxData := &models.InitiatedDepositsPageDataDeposit{
Index: depositTx.Index,
Expand Down
2 changes: 1 addition & 1 deletion handlers/queued_deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func buildQueuedDepositsPageData(ctx context.Context, pageIdx uint64, pageSize u
queueEntry := filteredQueue[i]

wdCreds := queueEntry.PendingDeposit.WithdrawalCredentials[:]
isBuilder := len(wdCreds) > 0 && wdCreds[0] == 0x03
isBuilder := len(wdCreds) > 0 && wdCreds[0] == 0xB0

// EpochEstimate is the churn-based epoch for normal deposits and the validator's
// withdrawable epoch for postponed ones; 0 means unknown.
Expand Down
2 changes: 1 addition & 1 deletion handlers/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func Validators(w http.ResponseWriter, r *http.Request) {
seen := map[uint8]bool{}
for _, v := range vals {
t, err := strconv.ParseUint(v, 10, 8)
if err != nil || t > 3 || seen[uint8(t)] {
if err != nil || (t > 2 && t != 0xB0) || seen[uint8(t)] {
continue
}
seen[uint8(t)] = true
Expand Down
6 changes: 3 additions & 3 deletions indexer/beacon/pendingvalidators.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ func IsProjectedValidator(v *phase0.Validator) bool {
}

// isBuilderWithdrawalCredential reports whether the credentials use the Gloas
// builder prefix (0x03).
// builder prefix (0xB0).
func isBuilderWithdrawalCredential(wc []byte) bool {
return len(wc) > 0 && wc[0] == 0x03
return len(wc) > 0 && wc[0] == 0xB0
}

// depositProcessingEstimator estimates the epoch at which each pending deposit is
Expand Down Expand Up @@ -164,7 +164,7 @@ func newDepositProcessingEstimator(currentEpoch phase0.Epoch, depositBalanceToCo
}

// next returns the estimated processing epoch for a deposit of the given amount and
// advances the estimator. onboarded is true when the deposit is a builder (0x03) that
// advances the estimator. onboarded is true when the deposit is a builder (0xB0) that
// reaches the Gloas fork unprocessed: at the fork such deposits are onboarded as
// builders (onboard_builders_from_pending_deposits), removed from the queue, and never
// become validators — so they consume no further deposit churn, which lets the normal
Expand Down
4 changes: 2 additions & 2 deletions indexer/beacon/pendingvalidators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ func TestProjectOrderingAndGating(t *testing.T) {
}

// TestProjectGloasBuilderFilter verifies that, when a Gloas fork is scheduled, new
// 0x03 (builder) deposits whose estimated processing epoch is at or after the fork
// 0xB0 (builder) deposits whose estimated processing epoch is at or after the fork
// are dropped (they are onboarded as builders at the fork), while those processed
// before the fork — and all non-builder deposits — still project.
func TestProjectGloasBuilderFilter(t *testing.T) {
domain := depositsig.Domain(phase0.Version{})
const amount = phase0.Gwei(32_000_000_000)

builderWc := make([]byte, 32)
builderWc[0] = 0x03
builderWc[0] = 0xB0
execWc := make([]byte, 32)
execWc[0] = 0x01

Expand Down
6 changes: 3 additions & 3 deletions indexer/beacon/statetransition/fork.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import (
"github.com/ethpandaops/dora/indexer/beacon/depositsig"
)

// builderWithdrawalPrefix is BUILDER_WITHDRAWAL_PREFIX (Gloas/EIP-8282): the 0x03
// builderWithdrawalPrefix is BUILDER_WITHDRAWAL_PREFIX (Gloas/EIP-8282): the 0xB0
// withdrawal-credential prefix that marks a deposit as a builder deposit.
const builderWithdrawalPrefix byte = 0x03
const builderWithdrawalPrefix byte = 0xB0

// isBuilderWithdrawalCredential reports whether the credentials use the builder prefix (0x03).
// isBuilderWithdrawalCredential reports whether the credentials use the builder prefix (0xB0).
func isBuilderWithdrawalCredential(wc []byte) bool {
return len(wc) > 0 && wc[0] == builderWithdrawalPrefix
}
Expand Down
2 changes: 1 addition & 1 deletion indexer/beacon/statetransition/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func applyExecutionRequests(s *stateAccessor, requests *all.ExecutionRequests) {
// The request is appended to the pending_deposits queue. Gloas (EIP-8282)
// removed the builder branch entirely: builder deposits now arrive via the
// dedicated builder deposit contract (processBuilderDepositRequest), so a
// 0x03-credential deposit via the regular deposit contract is queued as an
// 0xB0-credential deposit via the regular deposit contract is queued as an
// ordinary validator deposit like any other.
//
// https://github.com/ethereum/consensus-specs/pull/5359
Expand Down
6 changes: 3 additions & 3 deletions indexer/beacon/writedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ func (dbw *dbWriter) persistBlockDeposits(tx *sqlx.Tx, block *Block, depositInde
// reconcileOnboardedBuilderDeposits keeps the upgrade_to_gloas onboarded builder deposit copies in
// sync with their source validator deposits. The copies are written once at the fork boundary with
// the then-unfinalized fork id and are not re-persisted per block, so when a source deposit (a
// pre-gloas builder 0x03 deposit) is persisted canonically its matching copy is moved onto the same
// pre-gloas builder 0xB0 deposit) is persisted canonically its matching copy is moved onto the same
// fork id; otherwise the copy keeps its unfinalized fork id and later shows up as orphaned. It only
// runs once the fork has activated (i.e. the copy exists).
func (dbw *dbWriter) reconcileOnboardedBuilderDeposits(tx *sqlx.Tx, deposits []*dbtypes.Deposit, forkId ForkKey) error {
Expand All @@ -708,9 +708,9 @@ func (dbw *dbWriter) reconcileOnboardedBuilderDeposits(tx *sqlx.Tx, deposits []*

onboardingSlot := uint64(chainState.EpochToSlot(phase0.Epoch(*gloasForkEpoch)))
for _, deposit := range deposits {
// only pre-gloas builder (0x03) deposits are onboarded into builder_deposits by the fork
// only pre-gloas builder (0xB0) deposits are onboarded into builder_deposits by the fork
// transition, so only those have a copy to reconcile.
if deposit.CredType != 0x03 || uint64(chainState.EpochOfSlot(phase0.Slot(deposit.SlotNumber))) >= *gloasForkEpoch {
if deposit.CredType != 0xB0 || uint64(chainState.EpochOfSlot(phase0.Slot(deposit.SlotNumber))) >= *gloasForkEpoch {
continue
}

Expand Down
12 changes: 6 additions & 6 deletions services/chainservice_builder_onboarding.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import (
"github.com/ethpandaops/dora/dbtypes"
)

// builderWithdrawalCredType is BUILDER_WITHDRAWAL_PREFIX (Gloas/EIP-8282): the 0x03 withdrawal
// builderWithdrawalCredType is BUILDER_WITHDRAWAL_PREFIX (Gloas/EIP-8282): the 0xB0 withdrawal
// credential prefix that marks a deposit as a builder deposit, onboarded as a builder at the Gloas
// fork transition (onboard_builders_from_pending_deposits).
const builderWithdrawalCredType uint8 = 0x03
const builderWithdrawalCredType uint8 = 0xB0

// isBuilderCredential reports whether the withdrawal credentials use the builder prefix (0x03).
// isBuilderCredential reports whether the withdrawal credentials use the builder prefix (0xB0).
func isBuilderCredential(wc []byte) bool {
return len(wc) > 0 && wc[0] == builderWithdrawalCredType
}
Expand All @@ -25,7 +25,7 @@ func isBuilderCredential(wc []byte) bool {
// far above any realistic count of pre-fork builder deposits; hitting it sets Truncated.
const projectionFetchCap = 10000

// ProjectedBuilderDeposit is one builder-credential (0x03) deposit on chain together with its
// ProjectedBuilderDeposit is one builder-credential (0xB0) deposit on chain together with its
// projected fate at the upcoming Gloas fork transition. When none of the fate flags is set the
// deposit is projected to be onboarded as a builder (Result distinguishes new vs top-up).
type ProjectedBuilderDeposit struct {
Expand Down Expand Up @@ -96,7 +96,7 @@ type BuilderOnboardingProjection struct {
// not scheduled (no finite fork epoch) or the chain head/queue cannot be resolved. It is meant for
// the builder deposits page before the fork, where the real builder_deposits table is still empty.
//
// It enumerates every 0x03-credential deposit and classifies each: deposits already applied or that
// It enumerates every 0xB0-credential deposit and classifies each: deposits already applied or that
// the churn queue would process before the fork become regular validators ("too early"); the rest
// register builders (or top up earlier ones), drop on an invalid proof-of-possession, or stay as
// validator deposits when they share a pubkey with a validator — mirroring
Expand Down Expand Up @@ -162,7 +162,7 @@ func (bs *ChainService) GetBuilderOnboardingProjection(ctx context.Context) *Bui
}
tailEstimate := indexedQueue.EstimateAppendedDepositEpoch(depositAmount)

// Primary source: every builder-credential (0x03) deposit on chain (cache + DB merge). The
// Primary source: every builder-credential (0xB0) deposit on chain (cache + DB merge). The
// credential-type filter lives on the tx filter (both the cache and DB paths apply it there).
depositFilter := &dbtypes.DepositFilter{
WithOrphaned: 1,
Expand Down
6 changes: 3 additions & 3 deletions services/chainservice_deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,8 @@ func (bs *ChainService) GetDepositOperationsByFilter(ctx context.Context, filter

if len(txFilter.WithdrawalAddress) > 0 {
wdcreds := depositWithTx.WithdrawalCredentials
// 0x01 = ETH1, 0x02 = compounding, 0x03 = builder deposit
if wdcreds[0] != 0x01 && wdcreds[0] != 0x02 && wdcreds[0] != 0x03 {
// 0x01 = ETH1, 0x02 = compounding, 0xB0 = builder deposit
if wdcreds[0] != 0x01 && wdcreds[0] != 0x02 && wdcreds[0] != 0xB0 {
continue
}

Expand Down Expand Up @@ -792,7 +792,7 @@ func isSyntheticPendingDeposit(deposit *electra.PendingDeposit) bool {
//
// Post-Gloas (EIP-8282) builder deposits arrive via the dedicated builder deposit contract
// and never appear in the regular deposit stream, so every included regular deposit (any
// credential type, including 0x03) enters the pending_deposits queue and is a valid anchor;
// credential type, including 0xB0) enters the pending_deposits queue and is a valid anchor;
// the EL deposit index sequence stays contiguous with the queue.
func (bs *ChainService) getRecentIncludedDeposits(ctx context.Context, headRoot phase0.Root) *dbtypes.Deposit {
headBlock := bs.beaconIndexer.GetBlockByRoot(headRoot)
Expand Down
2 changes: 1 addition & 1 deletion services/chainservice_deposits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func TestResolveQueueDepositIndexes(t *testing.T) {
wantPostponed: []bool{false, false, false},
},
{
name: "0x03 (builder-cred) regular deposit is indexed contiguously like any validator deposit",
name: "0xB0 (builder-cred) regular deposit is indexed contiguously like any validator deposit",
queue: []*electra.PendingDeposit{regularDeposit(10, 1), regularDeposit(11, 2)},
anchor: anchorAt(8, 11),
wantIndexes: []*uint64{u64p(7), u64p(8)},
Expand Down
2 changes: 1 addition & 1 deletion templates/builder_deposits/builder_deposits.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ <h1 class="h4 mb-1 mb-md-0">
<p class="mb-2">
Gloas activates at epoch <strong>{{ .GloasForkEpoch }}</strong>
(<span data-timer="{{ .GloasForkTime.Unix }}" data-bs-toggle="tooltip" data-bs-title="{{ .GloasForkTime }}">{{ formatRecentTimeShort .GloasForkTime }}</span>).
Builder deposits are not recorded on-chain yet &mdash; the entries below are the actual <strong>0x03-credential deposits</strong>,
Builder deposits are not recorded on-chain yet &mdash; the entries below are the actual <strong>0xB0-credential deposits</strong>,
each annotated with its <strong>projected</strong> fate at the fork (based on the deposit churn limit and pending queue), and may change as deposits are submitted or processed.
{{ if .ProjectionTruncated }}<span class="text-muted">(showing the first {{ len .Deposits }}; older deposits omitted)</span>{{ end }}
</p>
Expand Down
2 changes: 1 addition & 1 deletion templates/included_deposits/included_deposits.html
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ <h1 class="h4 mb-1 mb-md-0">
<option value="0" {{ if index .FilterCredTypes 0 }}selected{{ end }}>0x00 (BLS)</option>
<option value="1" {{ if index .FilterCredTypes 1 }}selected{{ end }}>0x01 (Execution)</option>
<option value="2" {{ if index .FilterCredTypes 2 }}selected{{ end }}>0x02 (Compounding)</option>
<option value="3" {{ if index .FilterCredTypes 3 }}selected{{ end }}>0x03 (Builder)</option>
<option value="176" {{ if index .FilterCredTypes 176 }}selected{{ end }}>0xB0 (Builder)</option>
</select>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/validators/validators.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ <h1 class="h4 mb-1 mb-md-0"><i class="fas fa-table mx-2"></i> Validators Overvie
<option value="0" {{ if index .FilterCredTypes 0 }}selected{{ end }}>0x00 (BLS)</option>
<option value="1" {{ if index .FilterCredTypes 1 }}selected{{ end }}>0x01 (Execution)</option>
<option value="2" {{ if index .FilterCredTypes 2 }}selected{{ end }}>0x02 (Compounding)</option>
<option value="3" {{ if index .FilterCredTypes 3 }}selected{{ end }}>0x03 (Builder)</option>
<option value="176" {{ if index .FilterCredTypes 176 }}selected{{ end }}>0xB0 (Builder)</option>
</select>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ const BuilderDepositsTable = (props: IBuilderDepositsTableProps): React.ReactEle
signingDomain.set(forkDataRoot.slice(0, 28), 4);

return json.map((deposit: IDeposit) => {
const credsOk = deposit.withdrawal_credentials.replace(/^0x/, "").substring(0, 2).toLowerCase() === "03";
const credsOk = deposit.withdrawal_credentials.replace(/^0x/, "").substring(0, 2).toLowerCase() === "b0";
deposit.validity = props.deposits ? credsOk : (credsOk && verifyDeposit(deposit, signingDomain));
return deposit;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const SubmitBuilderDepositsForm = (props: ISubmitBuilderDepositsFormProps): Reac
<div className="row">
<div className="col-12">
<h3>Submit builder deposits</h3>
<p>This tool submits builder deposits to the builder deposit contract. Builder deposits carry a 0x03 withdrawal credential and a proof-of-possession signed under the dedicated builder-deposit domain.</p>
<p>This tool submits builder deposits to the builder deposit contract. Builder deposits carry a 0xB0 withdrawal credential and a proof-of-possession signed under the dedicated builder-deposit domain.</p>
<div className="alert alert-warning">
<b>Don't provide your keystore or mnemonic to us or any other website.</b> The generator below is for devnet testing only.
</div>
Expand Down Expand Up @@ -62,7 +62,7 @@ const SubmitBuilderDepositsForm = (props: ISubmitBuilderDepositsFormProps): Reac
Generate
</button>
</div>
<p className="text-secondary-emphasis mt-2">The deposit data file is a JSON array of builder deposits (pubkey, 0x03 withdrawal_credentials, amount, signature).</p>
<p className="text-secondary-emphasis mt-2">The deposit data file is a JSON array of builder deposits (pubkey, 0xB0 withdrawal_credentials, amount, signature).</p>
</div>

{(file || generatedDeposits) && isConnected && (
Expand Down
Loading