diff --git a/cmd/root.go b/cmd/root.go index 7e9d6778..40eee730 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -82,7 +82,7 @@ func init() { // ePBS time-based flags (0 = auto from slot time, scaled from the 12s value) rootCmd.PersistentFlags().Int64("epbs-bid-start", 0, "First bid time in ms relative to slot start (0 = auto: -400ms @12s, scaled to slot time)") rootCmd.PersistentFlags().Int64("epbs-bid-end", 0, "Last bid time in ms relative to slot start (0 = auto: -100ms @12s, scaled to slot time)") - rootCmd.PersistentFlags().Int64("epbs-reveal-time", 0, "Reveal time in ms relative to slot start (0 = auto: 7000ms @12s, scaled to slot time)") + rootCmd.PersistentFlags().Int64("epbs-reveal-time", 0, "Reveal time in ms relative to slot start (0 = auto: 5000ms @12s, scaled to slot time)") rootCmd.PersistentFlags().Uint64("epbs-bid-min", defaults.EPBS.BidMinAmount, "Minimum bid amount in gwei") rootCmd.PersistentFlags().Uint64("epbs-bid-increase", defaults.EPBS.BidIncrease, "Bid increase per subsequent bid in gwei") rootCmd.PersistentFlags().Int64("epbs-bid-interval", defaults.EPBS.BidInterval, "Interval between bids in ms (0 = single bid)") diff --git a/go.mod b/go.mod index 51d585a4..1e021575 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/OffchainLabs/go-bitfield v0.0.0-20251031151322-f427d04d8506 github.com/ethereum/go-ethereum v1.17.4 github.com/ethpandaops/go-eth-engine-client v0.0.2-0.20260703151703-9761c6187b28 - github.com/ethpandaops/go-eth2-client v0.1.6-0.20260703151911-3063991fb1e0 + github.com/ethpandaops/go-eth2-client v0.1.6 github.com/ethpandaops/service-authenticatoor v0.0.2 github.com/glebarez/go-sqlite v1.22.0 github.com/goccy/go-yaml v1.19.2 diff --git a/go.sum b/go.sum index 12778802..0641453d 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,8 @@ github.com/ethereum/go-ethereum v1.17.4 h1:uA4q+qiLp7QImBsjdRbINu8iX6OEVmj4DPc5/ github.com/ethereum/go-ethereum v1.17.4/go.mod h1:qMdgwqqRAen+aT8P7KKQKi0Qt6RzG4cfejVAbCpJgqA= github.com/ethpandaops/go-eth-engine-client v0.0.2-0.20260703151703-9761c6187b28 h1:zPciPcZHSMqL3pJRooPVIVTVAo51PjDX6rYZ6gNJGlU= github.com/ethpandaops/go-eth-engine-client v0.0.2-0.20260703151703-9761c6187b28/go.mod h1:ggCXJgxLFNGpC+DkgNQkeTr3dXRQDb0+9niNmaJWAgM= -github.com/ethpandaops/go-eth2-client v0.1.6-0.20260703151911-3063991fb1e0 h1:Ev0wM6ZRbNWEPJ+GXYfAmUz9FWAoNErAnWU60DiouIs= -github.com/ethpandaops/go-eth2-client v0.1.6-0.20260703151911-3063991fb1e0/go.mod h1:97Oq3omOQSGPPYgrbsOIIw2Pc4T5Ph21f8ZRyHJQBHU= +github.com/ethpandaops/go-eth2-client v0.1.6 h1:lG7Xz767YQQ+mN1ldzqJlj9Klg6zOElcemjXbCgJV5o= +github.com/ethpandaops/go-eth2-client v0.1.6/go.mod h1:97Oq3omOQSGPPYgrbsOIIw2Pc4T5Ph21f8ZRyHJQBHU= github.com/ethpandaops/service-authenticatoor v0.0.2 h1:0rqHA2Rw64+NG0HVGRfqVhJEkRZRzH3qhX2SkBr2u+w= github.com/ethpandaops/service-authenticatoor v0.0.2/go.mod h1:nIInMlq5O7YQDLVCL5gf0TeVAvVd9Q50k3sm3abTeG0= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= diff --git a/pkg/builderapi/epbs/handler_test.go b/pkg/builderapi/epbs/handler_test.go index d6f2d2ed..c39fa9d0 100644 --- a/pkg/builderapi/epbs/handler_test.go +++ b/pkg/builderapi/epbs/handler_test.go @@ -21,7 +21,6 @@ import ( "github.com/ethpandaops/go-eth2-client/spec/bellatrix" "github.com/ethpandaops/go-eth2-client/spec/capella" "github.com/ethpandaops/go-eth2-client/spec/deneb" - "github.com/ethpandaops/go-eth2-client/spec/electra" gloasspec "github.com/ethpandaops/go-eth2-client/spec/gloas" "github.com/ethpandaops/go-eth2-client/spec/phase0" "github.com/ethpandaops/go-eth2-client/spec/version" @@ -255,8 +254,8 @@ func signedBeaconBlockJSON(t *testing.T, slot phase0.Slot, blockHash phase0.Hash BlockHash: make([]byte, 32), }, ProposerSlashings: []*phase0.ProposerSlashing{}, - AttesterSlashings: []*electra.AttesterSlashing{}, - Attestations: []*electra.Attestation{}, + AttesterSlashings: []*gloasspec.AttesterSlashing{}, + Attestations: []*gloasspec.Attestation{}, Deposits: []*phase0.Deposit{}, VoluntaryExits: []*phase0.SignedVoluntaryExit{}, SyncAggregate: &altair.SyncAggregate{ diff --git a/pkg/config/default.go b/pkg/config/default.go index a95abe78..4e188c7f 100644 --- a/pkg/config/default.go +++ b/pkg/config/default.go @@ -48,15 +48,15 @@ const referenceSlotTimeMs = 12000 // PayloadBuildTime: 2100ms @12s (e.g. 1050ms @6s) // BidStartTime: -400ms @12s (e.g. -200ms @6s) // BidEndTime: -100ms @12s (e.g. -50ms @6s) -// RevealTime: 7000ms @12s (e.g. 3500ms @6s) +// RevealTime: 5000ms @12s (e.g. 2500ms @6s) // -// RevealTime (58.3% of the slot) is anchored to the Gloas/EIP-7732 deadlines: -// it sits after the attestation-aggregate deadline (AGGREGATE_DUE_BPS_GLOAS, -// 50%) — so the builder has seen enough attestation weight to know the block is -// the canonical head before committing to reveal — and comfortably before the -// hard payload deadline (PAYLOAD_DUE_BPS / PAYLOAD_ATTESTATION_DUE_BPS, 75%), -// after which the PTC votes the payload absent. The ~17% (2s @12s) margin lets -// the envelope gossip to PTC members before they attest at 75%. +// RevealTime (41.7% of the slot) is anchored to the Gloas/EIP-7732 deadlines: +// it sits after the attestation deadline (ATTESTATION_DUE_BPS_GLOAS, 25%) — so +// the builder has seen attestation weight on the block before committing to +// reveal — and comfortably before the hard payload deadline (PAYLOAD_DUE_BPS, +// 50% since consensus-specs#5414), after which the PTC votes the payload +// absent. The ~8% (1s @12s) margin before that deadline lets the envelope +// gossip to PTC members, who attest at 75% (PAYLOAD_ATTESTATION_DUE_BPS). func (c *Config) ApplySlotDefaults(slotTimeMs int64) { if c.EPBS.BuildStartTime == 0 { c.EPBS.BuildStartTime = -2900 * slotTimeMs / referenceSlotTimeMs @@ -75,6 +75,6 @@ func (c *Config) ApplySlotDefaults(slotTimeMs int64) { } if c.EPBS.RevealTime == 0 { - c.EPBS.RevealTime = 7000 * slotTimeMs / referenceSlotTimeMs + c.EPBS.RevealTime = 5000 * slotTimeMs / referenceSlotTimeMs } } diff --git a/pkg/lifecycle/contract.go b/pkg/lifecycle/contract.go index 4690f26e..cca87602 100644 --- a/pkg/lifecycle/contract.go +++ b/pkg/lifecycle/contract.go @@ -24,7 +24,7 @@ import ( // canonical addresses and match dora's DefaultSystemContractAddresses. var ( // BuilderDepositContractAddress is the EIP-8282 builder deposit predeploy. - BuilderDepositContractAddress = common.HexToAddress("0x0000884d2AA32eAa155F59A2f24eFa73D9008282") + BuilderDepositContractAddress = common.HexToAddress("0x00006AE84ed173D4394de5E28F9ED56b28008282") // BuilderExitContractAddress is the EIP-8282 builder exit predeploy. BuilderExitContractAddress = common.HexToAddress("0x000014574A74c805590AFF9499fc7A690f008282") ) @@ -42,12 +42,15 @@ const ( queueFeeHeadroom = 3 // builderWithdrawalPrefix is the withdrawal-credential prefix for builder - // deposits submitted via the EIP-8282 builder deposit contract. - builderWithdrawalPrefix = 0x00 + // deposits submitted via the EIP-8282 builder deposit contract. Must be + // BUILDER_WITHDRAWAL_PREFIX (0xB0): since consensus-specs#5439 (alpha.12), + // process_builder_deposit_request silently ignores deposits with any other + // prefix. + builderWithdrawalPrefix = 0xB0 // validatorWithdrawalPrefix is the withdrawal-credential prefix used for the // pre-Gloas early-onboarding deposit, which goes through the regular validator - // deposit contract (execution-address / 0x03-style credentials). - validatorWithdrawalPrefix = 0x03 + // deposit contract (builder-prefix / 0xB0 credentials). + validatorWithdrawalPrefix = 0xB0 ) // excessInhibitor is the EXCESS_INHIBITOR (2^256-1) stored in slot 0 of the @@ -167,14 +170,14 @@ func buildWithdrawalCredentials(prefix byte, walletAddress common.Address) [32]b } // BuilderWithdrawalCredentials builds the withdrawal credentials for an EIP-8282 -// builder deposit. Format: 0x00 + 00...00 (11 zero bytes) + wallet_address (20 bytes). +// builder deposit. Format: 0xB0 + 00...00 (11 zero bytes) + wallet_address (20 bytes). func BuilderWithdrawalCredentials(walletAddress common.Address) [32]byte { return buildWithdrawalCredentials(builderWithdrawalPrefix, walletAddress) } // ValidatorWithdrawalCredentials builds the withdrawal credentials for the pre-Gloas // early-onboarding deposit, which is submitted through the regular validator deposit -// contract. Format: 0x03 + 00...00 (11 zero bytes) + wallet_address (20 bytes). +// contract. Format: 0xB0 + 00...00 (11 zero bytes) + wallet_address (20 bytes). func ValidatorWithdrawalCredentials(walletAddress common.Address) [32]byte { return buildWithdrawalCredentials(validatorWithdrawalPrefix, walletAddress) } diff --git a/pkg/lifecycle/contract_test.go b/pkg/lifecycle/contract_test.go index 3d536d0b..b35f378c 100644 --- a/pkg/lifecycle/contract_test.go +++ b/pkg/lifecycle/contract_test.go @@ -38,7 +38,7 @@ func TestBuildBuilderDepositCalldata(t *testing.T) { } var wc [32]byte - wc[0] = 0x03 + wc[0] = 0xB0 sig := make([]byte, 96) for i := range sig { @@ -94,8 +94,8 @@ func TestWithdrawalCredentials(t *testing.T) { creds [32]byte wantPrefix byte }{ - {"builder uses 0x00 prefix", BuilderWithdrawalCredentials(addr), 0x00}, - {"validator uses 0x03 prefix", ValidatorWithdrawalCredentials(addr), 0x03}, + {"builder uses 0xB0 prefix", BuilderWithdrawalCredentials(addr), 0xB0}, + {"validator uses 0xB0 prefix", ValidatorWithdrawalCredentials(addr), 0xB0}, } for _, tt := range tests { diff --git a/pkg/lifecycle/early_deposit.go b/pkg/lifecycle/early_deposit.go index f6cf8016..f5f854ef 100644 --- a/pkg/lifecycle/early_deposit.go +++ b/pkg/lifecycle/early_deposit.go @@ -30,9 +30,9 @@ const depositContractABI = `[{"name":"deposit","type":"function","stateMutabilit `{"name":"deposit_data_root","type":"bytes32"}]}]` // EarlyDepositService submits a pre-Gloas builder onboarding deposit via the regular -// validator deposit contract. Unlike the post-fork builder deposit (EIP-8282 predeploy, -// 0x00 withdrawal prefix, DOMAIN_BUILDER_DEPOSIT), an early deposit uses 0x03 withdrawal -// credentials and is signed with the validator deposit domain — i.e. it is an ordinary +// validator deposit contract. Both paths use 0xB0 withdrawal credentials, but unlike +// the post-fork builder deposit (EIP-8282 predeploy, DOMAIN_BUILDER_DEPOSIT), an early +// deposit is signed with the validator deposit domain — i.e. it is an ordinary // validator deposit that sits in the beacon state's pending_deposits queue and is // converted into a builder at the Gloas fork boundary. type EarlyDepositService struct { @@ -87,7 +87,7 @@ func (s *EarlyDepositService) HasPendingDeposit() bool { } // CreateEarlyDeposit builds, signs and sends a validator deposit for this builder via -// the regular deposit contract. The deposit uses 0x03 (execution-address) withdrawal +// the regular deposit contract. The deposit uses 0xB0 (BUILDER_WITHDRAWAL_PREFIX) withdrawal // credentials pointing at the funding wallet and is signed with the validator deposit // domain over GENESIS_FORK_VERSION. func (s *EarlyDepositService) CreateEarlyDeposit(ctx context.Context, amountGwei uint64) error { diff --git a/pkg/signer/bls.go b/pkg/signer/bls.go index 3dddca76..4c24a9e0 100644 --- a/pkg/signer/bls.go +++ b/pkg/signer/bls.go @@ -22,7 +22,7 @@ var ( // DomainDeposit is the standard domain for validator deposit signatures, and for // the genesis builder-onboarding path (a pre-fork deposit to the validator deposit - // contract with a 0x03 credential, per the Gloas spec). + // contract with a 0xB0 credential, per the Gloas spec). DomainDeposit = phase0.DomainType{0x03, 0x00, 0x00, 0x00} // DomainBuilderDeposit is DOMAIN_BUILDER_DEPOSIT (Gloas, 0x0E000000): the dedicated diff --git a/pkg/signer/bls_test.go b/pkg/signer/bls_test.go index 3ff8228c..e995eb8e 100644 --- a/pkg/signer/bls_test.go +++ b/pkg/signer/bls_test.go @@ -18,7 +18,7 @@ func TestDepositRootComputation(t *testing.T) { } var wc [32]byte - wc[0] = 0x03 + wc[0] = 0xB0 for i := 12; i < 32; i++ { wc[i] = byte(i) }