Merge pull request #26 from astriaorg/payload-building

Payload building
This commit is contained in:
Jordan Oroshiba 2023-07-19 19:10:58 +02:00 committed by GitHub
commit fb7b65c6b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 40 deletions

View file

@ -169,6 +169,7 @@ func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
// If there are payloadAttributes: we try to assemble a block with the payloadAttributes // If there are payloadAttributes: we try to assemble a block with the payloadAttributes
// and return its payloadID. // and return its payloadID.
func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
log.Info("ForkchoiceUpdatedV1 called")
if payloadAttributes != nil { if payloadAttributes != nil {
if payloadAttributes.Withdrawals != nil { if payloadAttributes.Withdrawals != nil {
return engine.STATUS_INVALID, engine.InvalidParams.With(fmt.Errorf("withdrawals not supported in V1")) return engine.STATUS_INVALID, engine.InvalidParams.With(fmt.Errorf("withdrawals not supported in V1"))
@ -398,6 +399,7 @@ func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config engine.Transit
// GetPayloadV1 returns a cached payload by id. // GetPayloadV1 returns a cached payload by id.
func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.ExecutableData, error) { func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.ExecutableData, error) {
log.Info("GetPayloadV1 called")
data, err := api.getPayload(payloadID) data, err := api.getPayload(payloadID)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -7,7 +7,6 @@ package execution
import ( import (
"context" "context"
"fmt" "fmt"
"time"
"github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/beacon/engine"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -62,14 +61,13 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D
Random: common.Hash{}, Random: common.Hash{},
SuggestedFeeRecipient: common.Address{}, SuggestedFeeRecipient: common.Address{},
} }
fcStartResp, err := s.consensus.ForkchoiceUpdatedV1(*startForkChoice, payloadAttributes) fcStartResp, err := s.consensus.ForkchoiceUpdatedV1(*startForkChoice, payloadAttributes)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// super janky but this is what the payload builder requires :/ (miner.worker.buildPayload()) // TODO: we should probably just execute + store the block directly instead of using the engine api.
// we should probably just execute + store the block directly instead of using the engine api.
time.Sleep(time.Second)
payloadResp, err := s.consensus.GetPayloadV1(*fcStartResp.PayloadID) payloadResp, err := s.consensus.GetPayloadV1(*fcStartResp.PayloadID)
if err != nil { if err != nil {
log.Error("failed to call GetPayloadV1", "err", err) log.Error("failed to call GetPayloadV1", "err", err)

View file

@ -21,7 +21,6 @@ import (
"encoding/binary" "encoding/binary"
"math/big" "math/big"
"sync" "sync"
"time"
"github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/beacon/engine"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -84,7 +83,7 @@ func newPayload(empty *types.Block, id engine.PayloadID) *Payload {
} }
// update updates the full-block with latest built version. // update updates the full-block with latest built version.
func (payload *Payload) update(block *types.Block, fees *big.Int, elapsed time.Duration) { func (payload *Payload) update(block *types.Block, fees *big.Int) {
payload.lock.Lock() payload.lock.Lock()
defer payload.lock.Unlock() defer payload.lock.Unlock()
@ -103,7 +102,7 @@ func (payload *Payload) update(block *types.Block, fees *big.Int, elapsed time.D
feesInEther := new(big.Float).Quo(new(big.Float).SetInt(fees), big.NewFloat(params.Ether)) feesInEther := new(big.Float).Quo(new(big.Float).SetInt(fees), big.NewFloat(params.Ether))
log.Info("Updated payload", "id", payload.id, "number", block.NumberU64(), "hash", block.Hash(), log.Info("Updated payload", "id", payload.id, "number", block.NumberU64(), "hash", block.Hash(),
"txs", len(block.Transactions()), "gas", block.GasUsed(), "fees", feesInEther, "txs", len(block.Transactions()), "gas", block.GasUsed(), "fees", feesInEther,
"root", block.Root(), "elapsed", common.PrettyDuration(elapsed)) "root", block.Root())
} }
payload.cond.Broadcast() // fire signal for notifying full block payload.cond.Broadcast() // fire signal for notifying full block
} }
@ -160,39 +159,17 @@ func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Construct a payload object for return. // Construct a payload object for updating the block.
payload := newPayload(empty, args.Id()) payload := newPayload(empty, args.Id())
// Spin up a routine for updating the payload in background. This strategy // Get the block to update with the payload
// can maximum the revenue for including transactions with highest fee. block, fees, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, args.Withdrawals, false)
go func() { if err == nil {
// Setup the timer for re-building the payload. The initial clock is kept payload.update(block, fees)
// for triggering process immediately. log.Info("Stopping work on payload", "id", payload.id, "reason", "delivery")
timer := time.NewTimer(0) return payload, nil
defer timer.Stop() } else {
log.Info("Stopping work on payload", "id", payload.id, "reason", "failed to retrieve payload")
// Setup the timer for terminating the process if SECONDS_PER_SLOT (12s in return payload, nil
// the Mainnet configuration) have passed since the point in time identified }
// by the timestamp parameter.
endTimer := time.NewTimer(time.Second * 12)
for {
select {
case <-timer.C:
start := time.Now()
block, fees, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, args.Withdrawals, false)
if err == nil {
payload.update(block, fees, time.Since(start))
}
timer.Reset(w.recommit)
case <-payload.stop:
log.Info("Stopping work on payload", "id", payload.id, "reason", "delivery")
return
case <-endTimer.C:
log.Info("Stopping work on payload", "id", payload.id, "reason", "timeout")
return
}
}
}()
return payload, nil
} }