mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Build block?
This commit is contained in:
parent
7d72612dbb
commit
733df027e9
6 changed files with 144 additions and 16 deletions
|
|
@ -33,4 +33,5 @@ type API interface {
|
|||
NewSession(ctx context.Context, args *BuildBlockArgs) (string, error)
|
||||
AddTransaction(ctx context.Context, sessionId string, tx *types.Transaction) (*types.SimulateTransactionResult, error)
|
||||
AddBundle(ctx context.Context, sessionId string, bundle Bundle) error
|
||||
BuildBlock(ctx context.Context, sessionId string) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,3 +44,7 @@ func (a *APIClient) AddTransaction(ctx context.Context, sessionId string, tx *ty
|
|||
func (a *APIClient) AddBundle(ctx context.Context, sessionId string, bundle Bundle) error {
|
||||
return a.rpc.CallContext(ctx, nil, "suavex_addBundle", sessionId, bundle)
|
||||
}
|
||||
|
||||
func (a *APIClient) BuildBlock(ctx context.Context, sessionId string) error {
|
||||
return a.rpc.CallContext(ctx, nil, "suavex_buildBlock", sessionId)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ type SessionManager interface {
|
|||
NewSession(context.Context, *BuildBlockArgs) (string, error)
|
||||
AddTransaction(sessionId string, tx *types.Transaction) (*types.SimulateTransactionResult, error)
|
||||
AddBundle(sessionId string, bundle Bundle) error
|
||||
BuildBlock(sessionId string) error
|
||||
}
|
||||
|
||||
func NewServer(s SessionManager) *Server {
|
||||
|
|
@ -36,6 +37,10 @@ func (s *Server) AddBundle(ctx context.Context, sessionId string, bundle Bundle)
|
|||
return s.sessionMngr.AddBundle(sessionId, bundle)
|
||||
}
|
||||
|
||||
func (s *Server) BuildBlock(ctx context.Context, sessionId string) error {
|
||||
return s.sessionMngr.BuildBlock(sessionId)
|
||||
}
|
||||
|
||||
type MockServer struct {
|
||||
}
|
||||
|
||||
|
|
@ -50,3 +55,7 @@ func (s *MockServer) AddTransaction(ctx context.Context, sessionId string, tx *t
|
|||
func (s *MockServer) AddBundle(ctx context.Context, sessionId string, bundle Bundle) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MockServer) BuildBlock(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,3 +41,7 @@ func (nullSessionManager) AddTransaction(sessionId string, tx *types.Transaction
|
|||
func (nullSessionManager) AddBundle(sessionId string, bundle Bundle) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nullSessionManager) BuildBlock(sessionId string) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -21,6 +25,9 @@ type builder struct {
|
|||
gasPool *core.GasPool
|
||||
gasUsed *uint64
|
||||
signer types.Signer
|
||||
args api.BuildBlockArgs
|
||||
coinbasePreBalance *big.Int
|
||||
engine consensus.Engine
|
||||
}
|
||||
|
||||
type builderConfig struct {
|
||||
|
|
@ -28,6 +35,14 @@ type builderConfig struct {
|
|||
header *types.Header
|
||||
config *params.ChainConfig
|
||||
context core.ChainContext
|
||||
chainReader consensus.ChainHeaderReader
|
||||
|
||||
// newpayloadTimeout is the maximum timeout allowance for creating payload.
|
||||
// The default value is 2 seconds but node operator can set it to arbitrary
|
||||
// large value. A large timeout allowance may cause Geth to fail creating
|
||||
// a non-empty payload within the specified time and eventually miss the slot
|
||||
// in case there are some computation expensive transactions in txpool.
|
||||
newpayloadTimeout time.Duration
|
||||
}
|
||||
|
||||
func newBuilder(config *builderConfig) *builder {
|
||||
|
|
@ -40,6 +55,7 @@ func newBuilder(config *builderConfig) *builder {
|
|||
gasPool: &gp,
|
||||
gasUsed: &gasUsed,
|
||||
signer: types.MakeSigner(config.config, config.header.Number, config.header.Time),
|
||||
coinbasePreBalance: config.preState.GetBalance(config.header.Coinbase),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,3 +187,89 @@ func (b *builder) AddTransaction(txn *types.Transaction) (*types.SimulateTransac
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (b *builder) commitPendingTxs() error {
|
||||
interrupt := new(atomic.Int32)
|
||||
timer := time.AfterFunc(b.config.newpayloadTimeout, func() {
|
||||
interrupt.Store(commitInterruptTimeout)
|
||||
})
|
||||
defer timer.Stop()
|
||||
if err := b.fillTransactions(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *builder) fillTransactions() error {
|
||||
// Split the pending transactions into locals and remotes
|
||||
// Fill the block with all available pending transactions.
|
||||
pending := w.eth.TxPool().Pending(true)
|
||||
localTxs, remoteTxs := make(map[common.Address]types.Transactions), pending
|
||||
for _, account := range w.eth.TxPool().Locals() {
|
||||
if txs := remoteTxs[account]; len(txs) > 0 {
|
||||
delete(remoteTxs, account)
|
||||
localTxs[account] = txs
|
||||
}
|
||||
}
|
||||
if len(localTxs) > 0 {
|
||||
txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee)
|
||||
if err := b.commitTransactions(env, txs, interrupt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(remoteTxs) > 0 {
|
||||
txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee)
|
||||
if err := w.commitTransactions(env, txs, interrupt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *builder) BuildBlock() error {
|
||||
if b.args.FillPending {
|
||||
if err := b.commitPendingTxs(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// create ephemeral addr and private key for payment txn
|
||||
ephemeralPrivKey, err := crypto.GenerateKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ephemeralAddr := crypto.PubkeyToAddress(ephemeralPrivKey.PublicKey)
|
||||
|
||||
// Assume static 28000 gas transfers for both mev-share and proposer payments
|
||||
refundTransferCost := new(big.Int).Mul(big.NewInt(28000), b.config.header.BaseFee)
|
||||
|
||||
profitPost := b.state.GetBalance(b.config.header.Coinbase)
|
||||
proposerProfit := new(big.Int).Set(profitPost) // = post-pre-transfer_cost
|
||||
proposerProfit = proposerProfit.Sub(profitPost, b.coinbasePreBalance)
|
||||
proposerProfit = proposerProfit.Sub(proposerProfit, refundTransferCost)
|
||||
|
||||
currNonce := b.state.GetNonce(ephemeralAddr)
|
||||
paymentTx, err := types.SignTx(types.NewTx(&types.LegacyTx{
|
||||
Nonce: currNonce,
|
||||
To: &b.args.FeeRecipient,
|
||||
Value: proposerProfit,
|
||||
Gas: 28000,
|
||||
GasPrice: b.config.header.BaseFee,
|
||||
}), b.signer, ephemeralPrivKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not sign proposer payment: %w", err)
|
||||
}
|
||||
|
||||
// commit payment txn
|
||||
if _, err := b.AddTransaction(paymentTx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
block, err := b.engine.FinalizeAndAssemble(b.config.chainReader, b.config.header, b.state, b.txns, []*types.Header{}, b.receipts, b.args.Withdrawals)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("-- block --", block)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,14 @@ func (s *SessionManager) AddBundle(sessionId string, bundle api.Bundle) error {
|
|||
return builder.AddBundle(bundle)
|
||||
}
|
||||
|
||||
func (s *SessionManager) BuildBlock(sessionId string) error {
|
||||
builder, err := s.getSession(sessionId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return builder.BuildBlock()
|
||||
}
|
||||
|
||||
// CalcBaseFee calculates the basefee of the header.
|
||||
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
|
||||
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
|
||||
|
|
|
|||
Loading…
Reference in a new issue