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)
|
NewSession(ctx context.Context, args *BuildBlockArgs) (string, error)
|
||||||
AddTransaction(ctx context.Context, sessionId string, tx *types.Transaction) (*types.SimulateTransactionResult, error)
|
AddTransaction(ctx context.Context, sessionId string, tx *types.Transaction) (*types.SimulateTransactionResult, error)
|
||||||
AddBundle(ctx context.Context, sessionId string, bundle Bundle) 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 {
|
func (a *APIClient) AddBundle(ctx context.Context, sessionId string, bundle Bundle) error {
|
||||||
return a.rpc.CallContext(ctx, nil, "suavex_addBundle", sessionId, bundle)
|
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)
|
NewSession(context.Context, *BuildBlockArgs) (string, error)
|
||||||
AddTransaction(sessionId string, tx *types.Transaction) (*types.SimulateTransactionResult, error)
|
AddTransaction(sessionId string, tx *types.Transaction) (*types.SimulateTransactionResult, error)
|
||||||
AddBundle(sessionId string, bundle Bundle) error
|
AddBundle(sessionId string, bundle Bundle) error
|
||||||
|
BuildBlock(sessionId string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(s SessionManager) *Server {
|
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)
|
return s.sessionMngr.AddBundle(sessionId, bundle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) BuildBlock(ctx context.Context, sessionId string) error {
|
||||||
|
return s.sessionMngr.BuildBlock(sessionId)
|
||||||
|
}
|
||||||
|
|
||||||
type MockServer struct {
|
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 {
|
func (s *MockServer) AddBundle(ctx context.Context, sessionId string, bundle Bundle) error {
|
||||||
return nil
|
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 {
|
func (nullSessionManager) AddBundle(sessionId string, bundle Bundle) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (nullSessionManager) BuildBlock(sessionId string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
package builder
|
package builder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
@ -21,6 +25,9 @@ type builder struct {
|
||||||
gasPool *core.GasPool
|
gasPool *core.GasPool
|
||||||
gasUsed *uint64
|
gasUsed *uint64
|
||||||
signer types.Signer
|
signer types.Signer
|
||||||
|
args api.BuildBlockArgs
|
||||||
|
coinbasePreBalance *big.Int
|
||||||
|
engine consensus.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
type builderConfig struct {
|
type builderConfig struct {
|
||||||
|
|
@ -28,6 +35,14 @@ type builderConfig struct {
|
||||||
header *types.Header
|
header *types.Header
|
||||||
config *params.ChainConfig
|
config *params.ChainConfig
|
||||||
context core.ChainContext
|
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 {
|
func newBuilder(config *builderConfig) *builder {
|
||||||
|
|
@ -40,6 +55,7 @@ func newBuilder(config *builderConfig) *builder {
|
||||||
gasPool: &gp,
|
gasPool: &gp,
|
||||||
gasUsed: &gasUsed,
|
gasUsed: &gasUsed,
|
||||||
signer: types.MakeSigner(config.config, config.header.Number, config.header.Time),
|
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
|
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)
|
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.
|
// CalcBaseFee calculates the basefee of the header.
|
||||||
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
|
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
|
||||||
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
|
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue