Skip to content
This repository has been archived by the owner on Oct 25, 2024. It is now read-only.

Commit

Permalink
Improvements from greedy improve algo (#41)
Browse files Browse the repository at this point in the history
* Backport improvements to the builder from incremental improvements
* Make linter happy
  • Loading branch information
Ruteri authored and avalonche committed Jul 6, 2023
1 parent 0c567ab commit ab35c21
Show file tree
Hide file tree
Showing 20 changed files with 276 additions and 96 deletions.
5 changes: 3 additions & 2 deletions builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package builder
import (
"context"
"errors"
blockvalidation "github.com/ethereum/go-ethereum/eth/block-validation"
"golang.org/x/time/rate"
"math/big"
_ "os"
"sync"
"time"

blockvalidation "github.com/ethereum/go-ethereum/eth/block-validation"
"golang.org/x/time/rate"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/beacon"
"github.com/ethereum/go-ethereum/core/types"
Expand Down
3 changes: 2 additions & 1 deletion builder/local_relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import (
"bytes"
"encoding/json"
"fmt"
"golang.org/x/time/rate"
"math/big"
"net/http"
"net/http/httptest"
"testing"
"time"

"golang.org/x/time/rate"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/beacon"
Expand Down
2 changes: 0 additions & 2 deletions builder/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ func (r *testRelay) GetValidatorForSlot(nextSlot uint64) (ValidatorData, error)
r.requestedSlot = nextSlot
return r.validator, nil
}
func (r *testRelay) handleRegisterValidator(w http.ResponseWriter, req *http.Request) {
}

type RemoteRelay struct {
endpoint string
Expand Down
3 changes: 2 additions & 1 deletion builder/resubmit_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package builder

import (
"context"
"time"

"github.com/ethereum/go-ethereum/log"
"golang.org/x/time/rate"
"time"
)

// runResubmitLoop checks for update signal and calls submit respecting provided rate limiter and context
Expand Down
3 changes: 2 additions & 1 deletion builder/resubmit_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package builder

import (
"context"
"golang.org/x/time/rate"
"math/rand"
"sort"
"sync"
"testing"
"time"

"golang.org/x/time/rate"
)

type submission struct {
Expand Down
3 changes: 2 additions & 1 deletion builder/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package builder
import (
"errors"
"fmt"
blockvalidation "github.com/ethereum/go-ethereum/eth/block-validation"
"net/http"
"os"

blockvalidation "github.com/ethereum/go-ethereum/eth/block-validation"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
Expand Down
9 changes: 3 additions & 6 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1641,14 +1641,11 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
cfg.GasPrice = flags.GlobalBig(ctx, MinerGasPriceFlag.Name)
}
if ctx.IsSet(MinerAlgoTypeFlag.Name) {
switch ctx.String(MinerAlgoTypeFlag.Name) {
case "greedy":
cfg.AlgoType = miner.ALGO_GREEDY
case "mev-geth":
cfg.AlgoType = miner.ALGO_MEV_GETH
default:
algoType, err := miner.AlgoTypeFlagToEnum(ctx.String(MinerAlgoTypeFlag.Name))
if err != nil {
Fatalf("Invalid algo in --miner.algotype: %s", ctx.String(MinerAlgoTypeFlag.Name))
}
cfg.AlgoType = algoType
}
if ctx.IsSet(MinerRecommitIntervalFlag.Name) {
cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name)
Expand Down
13 changes: 13 additions & 0 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,19 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa
}
}

func (t *TransactionsByPriceAndNonce) DeepCopy() *TransactionsByPriceAndNonce {
newT := &TransactionsByPriceAndNonce{
txs: make(map[common.Address]Transactions),
heads: append(TxByPriceAndTime{}, t.heads...),
signer: t.signer,
baseFee: new(big.Int).Set(t.baseFee),
}
for k, v := range t.txs {
newT.txs[k] = v
}
return newT
}

// Peek returns the next transaction by price.
func (t *TransactionsByPriceAndNonce) Peek() *TxWithMinerFee {
if len(t.heads) == 0 {
Expand Down
7 changes: 2 additions & 5 deletions eth/block-validation/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ var (
testValidatorKey, _ = crypto.HexToECDSA("28c3cd61b687fdd03488e167a5d84f50269df2a4c29a2cfb1390903aa775c5d0")
testValidatorAddr = crypto.PubkeyToAddress(testValidatorKey.PublicKey)

testMinerKey, _ = crypto.HexToECDSA("28c3cd61b687fdd03488e167a5d84f50269df2a4c29a2cfb1390903aa775c5d0")
testMinerAddr = crypto.PubkeyToAddress(testValidatorKey.PublicKey)

testBalance = big.NewInt(2e18)
)

Expand All @@ -57,7 +54,7 @@ func TestValidateBuilderSubmissionV1(t *testing.T) {
api := NewBlockValidationAPI(ethservice, nil)
parent := preMergeBlocks[len(preMergeBlocks)-1]

api.eth.APIBackend.Miner().SetEtherbase(testMinerAddr)
api.eth.APIBackend.Miner().SetEtherbase(testValidatorAddr)

// This EVM code generates a log when the contract is created.
logCode := common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
Expand Down Expand Up @@ -142,7 +139,7 @@ func TestValidateBuilderSubmissionV1(t *testing.T) {
invalidPayload.LogsBloom = boostTypes.Bloom{}
copy(invalidPayload.ReceiptsRoot[:], hexutil.MustDecode("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")[:32])
blockRequest.ExecutionPayload = invalidPayload
copy(blockRequest.Message.BlockHash[:], hexutil.MustDecode("0x272872d14b2a8a0454e747ed472d82d8d5ce342cfafd65fa7b77aa6de1c061d4")[:32])
copy(blockRequest.Message.BlockHash[:], hexutil.MustDecode("0x2ff468dee2e05f1f58744d5496f3ab22fdc23c8141f86f907b4b0f2c8e22afc4")[:32])
require.ErrorContains(t, api.ValidateBuilderSubmissionV1(blockRequest), "could not apply tx 3", "insufficient funds for gas * price + value")
}

Expand Down
5 changes: 3 additions & 2 deletions eth/tracers/logger/account_touch_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
package logger

import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"math/big"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)

type AccountTouchTracer struct {
Expand Down
8 changes: 7 additions & 1 deletion miner/algo_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ var emptyCodeHash = common.HexToHash("c5d2460186f7233c927e7db2dcc703c0e500b653ca

var errInterrupt = errors.New("miner worker interrupted")

type chainData struct {
chainConfig *params.ChainConfig
chain *core.BlockChain
blacklist map[common.Address]struct{}
}

type environmentDiff struct {
baseEnvironment *environment
header *types.Header
Expand All @@ -51,7 +57,7 @@ func (e *environmentDiff) copy() *environmentDiff {
gasPool := new(core.GasPool).AddGas(e.gasPool.Gas())

return &environmentDiff{
baseEnvironment: e.baseEnvironment,
baseEnvironment: e.baseEnvironment.copy(),
header: types.CopyHeader(e.header),
gasPool: gasPool,
state: e.state.Copy(),
Expand Down
39 changes: 34 additions & 5 deletions miner/algo_common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"crypto/ecdsa"
"errors"
"fmt"
"github.com/stretchr/testify/require"
"math/big"
"testing"

"github.com/stretchr/testify/require"

mapset "github.com/deckarep/golang-set"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -366,10 +367,8 @@ func TestCommitTxOverGasLimit(t *testing.T) {
t.Fatal("Env diff gas pool is not drained")
}

receipt, i, err = envDiff.commitTx(tx2, chData)
if err == nil {
t.Fatal("committed tx over gas limit")
}
_, _, err = envDiff.commitTx(tx2, chData)
require.Error(t, err, "committed tx over gas limit")
}

func TestErrorBundleCommit(t *testing.T) {
Expand Down Expand Up @@ -497,6 +496,36 @@ func TestBlacklist(t *testing.T) {
}
}

func TestGetSealingWorkAlgos(t *testing.T) {
t.Cleanup(func() {
testConfig.AlgoType = ALGO_MEV_GETH
})

for _, algoType := range []AlgoType{ALGO_MEV_GETH, ALGO_GREEDY} {
local := new(params.ChainConfig)
*local = *ethashChainConfig
local.TerminalTotalDifficulty = big.NewInt(0)
testConfig.AlgoType = algoType
testGetSealingWork(t, local, ethash.NewFaker(), true)
}
}

func TestGetSealingWorkAlgosWithProfit(t *testing.T) {
t.Cleanup(func() {
testConfig.AlgoType = ALGO_MEV_GETH
testConfig.BuilderTxSigningKey = nil
})

for _, algoType := range []AlgoType{ALGO_GREEDY} {
var err error
testConfig.BuilderTxSigningKey, err = crypto.GenerateKey()
require.NoError(t, err)
testConfig.AlgoType = algoType
t.Logf("running for %d", algoType)
testBundles(t)
}
}

func TestPayoutTxUtils(t *testing.T) {
availableFunds := big.NewInt(50000000000000000) // 0.05 eth

Expand Down
31 changes: 11 additions & 20 deletions miner/algo_greedy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,6 @@ import (
"github.com/ethereum/go-ethereum/params"
)

type chainData struct {
chainConfig *params.ChainConfig
chain *core.BlockChain
blacklist map[common.Address]struct{}
}

type IBuilder interface {
buildBlock(simBundles []types.SimulatedBundle, transactions map[common.Address]types.Transactions) (*environment, []types.SimulatedBundle)
}

// / To use it:
// / 1. Copy relevant data from the worker
// / 2. Call buildBlock
Expand All @@ -37,14 +27,8 @@ func newGreedyBuilder(chain *core.BlockChain, chainConfig *params.ChainConfig, b
}
}

func (b *greedyBuilder) buildBlock(simBundles []types.SimulatedBundle, transactions map[common.Address]types.Transactions) (*environment, []types.SimulatedBundle) {

env := b.inputEnvironment.copy()

orders := types.NewTransactionsByPriceAndNonce(env.signer, transactions, simBundles, env.header.BaseFee)
envDiff := newEnvironmentDiff(env)

usedBundles := make([]types.SimulatedBundle, 0)
func (b *greedyBuilder) mergeOrdersIntoEnvDiff(envDiff *environmentDiff, orders *types.TransactionsByPriceAndNonce) []types.SimulatedBundle {
usedBundles := []types.SimulatedBundle{}

for {
order := orders.Peek()
Expand All @@ -65,7 +49,7 @@ func (b *greedyBuilder) buildBlock(simBundles []types.SimulatedBundle, transacti
log.Trace("could not apply tx", "hash", order.Tx.Hash(), "err", err)
continue
}
effGapPrice, err := order.Tx.EffectiveGasTip(env.header.BaseFee)
effGapPrice, err := order.Tx.EffectiveGasTip(envDiff.baseEnvironment.header.BaseFee)
if err == nil {
log.Trace("Included tx", "EGP", effGapPrice.String(), "gasUsed", receipt.GasUsed)
}
Expand All @@ -84,6 +68,13 @@ func (b *greedyBuilder) buildBlock(simBundles []types.SimulatedBundle, transacti
}
}

return usedBundles
}

func (b *greedyBuilder) buildBlock(simBundles []types.SimulatedBundle, transactions map[common.Address]types.Transactions) (*environment, []types.SimulatedBundle) {
orders := types.NewTransactionsByPriceAndNonce(b.inputEnvironment.signer, transactions, simBundles, b.inputEnvironment.header.BaseFee)
envDiff := newEnvironmentDiff(b.inputEnvironment.copy())
usedBundles := b.mergeOrdersIntoEnvDiff(envDiff, orders)
envDiff.applyToBaseEnv()
return env, usedBundles
return envDiff.baseEnvironment, usedBundles
}
6 changes: 3 additions & 3 deletions miner/algo_greedy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package miner

import (
"fmt"
"math/big"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"math/big"
"testing"
)

func TestBuildBlockGasLimit(t *testing.T) {
Expand Down Expand Up @@ -65,5 +66,4 @@ func TestTxWithMinerFeeHeap(t *testing.T) {
orders.Pop()
}
}

}
3 changes: 2 additions & 1 deletion miner/bundle_cache.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package miner

import (
"sync"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"sync"
)

const (
Expand Down
3 changes: 2 additions & 1 deletion miner/bundle_cache_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package miner

import (
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"testing"
)

func TestBundleCacheEntry(t *testing.T) {
Expand Down
14 changes: 13 additions & 1 deletion miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ package miner

import (
"crypto/ecdsa"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
"math/big"
"os"
"strings"
Expand All @@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
Expand All @@ -54,6 +55,17 @@ const (
ALGO_GREEDY
)

func AlgoTypeFlagToEnum(algoString string) (AlgoType, error) {
switch algoString {
case "mev-geth":
return ALGO_MEV_GETH, nil
case "greedy":
return ALGO_GREEDY, nil
default:
return ALGO_MEV_GETH, errors.New("algo not recognized")
}
}

// Config is the configuration parameters of mining.
type Config struct {
Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards
Expand Down
Loading

0 comments on commit ab35c21

Please sign in to comment.