mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-08 07:58:40 +00:00
miner: supply a slot number when synthesising pending block post-Amsterdam
getPending builds the pending block on demand via generateWork, but after EIP-7843 (#33589) prepareWork rejects the call unless generateParams.slotNum is non-nil once Amsterdam is active: if miner.chainConfig.IsAmsterdam(header.Number, header.Time) { if genParams.slotNum == nil { return nil, errors.New("no slot number set post-amsterdam") } header.SlotNumber = genParams.slotNum } getPending never populated slotNum, so on any Amsterdam-activated chain eth_getBalance(addr, "pending") (and every other RPC that resolves through the pending state) fails with "pending state is not available", breaking faucets and nonce trackers that poll pending. Fix by synthesising a slot number from the parent header when available, mirroring how the Shanghai branch above already conditionally populates withdrawals. The pending block is empty post-merge so the exact slot value is not user-visible; SlotNumber+1 (or zero) is sufficient to satisfy the prepareWork invariant. Observed on a bal-devnet-3 Geth build: every eth_getBalance(...,"pending") returned -32000 "pending state is not available" until the faucet was repointed at a non-Geth EL. Other clients (Nethermind, Besu, Reth, Erigon, Ethrex) serve pending on the same chain without issue.
This commit is contained in:
parent
4e6c9ec825
commit
73b84bb822
1 changed files with 16 additions and 3 deletions
|
|
@ -151,12 +151,24 @@ func (miner *Miner) getPending() *newPayloadResult {
|
|||
return cached
|
||||
}
|
||||
var (
|
||||
timestamp = uint64(time.Now().Unix())
|
||||
withdrawal types.Withdrawals
|
||||
timestamp = uint64(time.Now().Unix())
|
||||
childNumber = new(big.Int).Add(header.Number, big.NewInt(1))
|
||||
withdrawal types.Withdrawals
|
||||
slotNum *uint64
|
||||
)
|
||||
if miner.chainConfig.IsShanghai(new(big.Int).Add(header.Number, big.NewInt(1)), timestamp) {
|
||||
if miner.chainConfig.IsShanghai(childNumber, timestamp) {
|
||||
withdrawal = []*types.Withdrawal{}
|
||||
}
|
||||
// Post-Amsterdam, prepareWork requires a slot number (EIP-7843). The pending
|
||||
// block is synthetic and has no canonical slot, so derive one from the parent
|
||||
// when available and fall back to zero otherwise.
|
||||
if miner.chainConfig.IsAmsterdam(childNumber, timestamp) {
|
||||
var n uint64
|
||||
if header.SlotNumber != nil {
|
||||
n = *header.SlotNumber + 1
|
||||
}
|
||||
slotNum = &n
|
||||
}
|
||||
ret := miner.generateWork(context.Background(),
|
||||
&generateParams{
|
||||
timestamp: timestamp,
|
||||
|
|
@ -166,6 +178,7 @@ func (miner *Miner) getPending() *newPayloadResult {
|
|||
random: common.Hash{},
|
||||
withdrawals: withdrawal,
|
||||
beaconRoot: nil,
|
||||
slotNum: slotNum,
|
||||
noTxs: false,
|
||||
}, false) // we will never make a witness for a pending block
|
||||
if ret.err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue