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

Commit 9acf640

Browse files
authored
[trivial] Parameterize greedy-buckets price cutoff percent & update bundle profit to coinbase delta (#83)
* Parameterize greedy-buckets price cutoff percent to support dynamic bucket sizes * Update profit function to use coinbase difference for bundles instead of total eth * Update CLI to use default pirce cutoff percent
1 parent 44debde commit 9acf640

File tree

8 files changed

+61
-29
lines changed

8 files changed

+61
-29
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ $ geth --help
130130
--miner.extradata value
131131
Block extra data set by the miner (default = client version)
132132
133+
--miner.price_cutoff_percent value (default: 50)
134+
flashbots - The minimum effective gas price threshold used for bucketing
135+
transactions by price. For example if the top transaction in a list has an
136+
effective gas price of 1000 wei and price_cutoff_percent is 10 (i.e. 10%), then
137+
the minimum effective gas price included in the same bucket as the top
138+
transaction is (1000 * 10%) = 100 wei.
139+
NOTE: This flag is only used when
140+
miner.algotype=greedy-buckets
141+
133142
METRICS
134143
135144
--metrics.builder value (default: false)

cmd/geth/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ var (
133133
utils.MinerMaxMergedBundlesFlag,
134134
utils.MinerBlocklistFileFlag,
135135
utils.MinerNewPayloadTimeout,
136+
utils.MinerPriceCutoffPercentFlag,
136137
utils.NATFlag,
137138
utils.NoDiscoverFlag,
138139
utils.DiscoveryV5Flag,

cmd/utils/flags.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ var (
548548
}
549549
MinerAlgoTypeFlag = &cli.StringFlag{
550550
Name: "miner.algotype",
551-
Usage: "Block building algorithm to use [=mev-geth] (mev-geth, greedy)",
551+
Usage: "Block building algorithm to use [=mev-geth] (mev-geth, greedy, greedy-buckets)",
552552
Value: "mev-geth",
553553
Category: flags.MinerCategory,
554554
}
@@ -591,6 +591,17 @@ var (
591591
Value: ethconfig.Defaults.Miner.NewPayloadTimeout,
592592
Category: flags.MinerCategory,
593593
}
594+
MinerPriceCutoffPercentFlag = &cli.IntFlag{
595+
Name: "miner.price_cutoff_percent",
596+
Usage: "flashbots - The minimum effective gas price threshold used for bucketing transactions by price. " +
597+
"For example if the top transaction in a list has an effective gas price of 1000 wei and price_cutoff_percent " +
598+
"is 10 (i.e. 10%), then the minimum effective gas price included in the same bucket as the top transaction " +
599+
"is (1000 * 10%) = 100 wei.\n" +
600+
"NOTE: This flag is only used when miner.algotype=greedy-buckets",
601+
Value: ethconfig.Defaults.Miner.PriceCutoffPercent,
602+
Category: flags.MinerCategory,
603+
EnvVars: []string{"FLASHBOTS_MINER_PRICE_CUTOFF_PERCENT"},
604+
}
594605

595606
// Account settings
596607
UnlockedAccountFlag = &cli.StringFlag{
@@ -1893,6 +1904,8 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
18931904
Fatalf("Failed to parse blocklist: %s", err)
18941905
}
18951906
}
1907+
1908+
cfg.PriceCutoffPercent = ctx.Int(MinerPriceCutoffPercentFlag.Name)
18961909
}
18971910

18981911
func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) {

core/types/transaction.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ func (t *TxWithMinerFee) Profit(baseFee *big.Int, gasUsed uint64) *big.Int {
535535
}
536536
return profit
537537
} else if bundle := t.Bundle(); bundle != nil {
538-
return bundle.TotalEth
538+
return bundle.EthSentToCoinbase
539539
} else if sbundle := t.SBundle(); sbundle != nil {
540540
return sbundle.Profit
541541
} else {

miner/algo_common.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@ const (
2222
popTx = 2
2323
)
2424

25-
// defaultProfitPercentMinimum is to ensure committed transactions, bundles, sbundles don't fall below this threshold
26-
// when profit is enforced
27-
const defaultProfitPercentMinimum = 70
25+
const (
26+
// defaultProfitPercentMinimum is to ensure committed transactions, bundles, sbundles don't fall below this threshold
27+
// when profit is enforced
28+
defaultProfitPercentMinimum = 70
29+
30+
// defaultPriceCutoffPercent is for bucketing transactions by price, used for greedy buckets algorithm
31+
defaultPriceCutoffPercent = 50
32+
)
2833

2934
var (
3035
defaultProfitThreshold = big.NewInt(defaultProfitPercentMinimum)
@@ -63,6 +68,11 @@ type algorithmConfig struct {
6368
ExpectedProfit *big.Int
6469
// ProfitThresholdPercent is the minimum profit threshold for committing a transaction
6570
ProfitThresholdPercent *big.Int
71+
// PriceCutoffPercent is the minimum effective gas price threshold used for bucketing transactions by price.
72+
// For example if the top transaction in a list has an effective gas price of 1000 wei and PriceCutoffPercent
73+
// is 10 (i.e. 10%), then the minimum effective gas price included in the same bucket as the top transaction
74+
// is (1000 * 10%) = 100 wei.
75+
PriceCutoffPercent int
6676
}
6777

6878
type chainData struct {

miner/algo_greedy_buckets.go

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,9 @@ func newGreedyBucketsBuilder(
4949
}
5050

5151
// CutoffPriceFromOrder returns the cutoff price for a given order based on the cutoff percent.
52-
// For example, if the cutoff percent is 0.9, the cutoff price will be 90% of the order price, rounded down to the nearest integer.
53-
func CutoffPriceFromOrder(order *types.TxWithMinerFee, cutoffPercent *big.Float) *big.Int {
54-
floorPrice := new(big.Float).
55-
Mul(
56-
new(big.Float).SetInt(order.Price()),
57-
cutoffPercent,
58-
)
59-
round, _ := floorPrice.Int64()
60-
return big.NewInt(round)
52+
// For example, if the cutoff percent is 90, the cutoff price will be 90% of the order price, rounded down to the nearest integer.
53+
func CutoffPriceFromOrder(order *types.TxWithMinerFee, cutoffPercent int) *big.Int {
54+
return common.PercentOf(order.Price(), cutoffPercent)
6155
}
6256

6357
// IsOrderInPriceRange returns true if the order price is greater than or equal to the minPrice.
@@ -196,15 +190,12 @@ func (b *greedyBucketsBuilder) mergeOrdersIntoEnvDiff(
196190
const retryLimit = 1
197191

198192
var (
199-
baseFee = envDiff.baseEnvironment.header.BaseFee
200-
retryMap = make(map[*types.TxWithMinerFee]int)
201-
usedBundles []types.SimulatedBundle
202-
usedSbundles []types.UsedSBundle
203-
transactions []*types.TxWithMinerFee
204-
percent = new(big.Float).Quo(
205-
new(big.Float).SetInt(b.algoConf.ProfitThresholdPercent),
206-
new(big.Float).SetInt(common.Big100),
207-
)
193+
baseFee = envDiff.baseEnvironment.header.BaseFee
194+
retryMap = make(map[*types.TxWithMinerFee]int)
195+
usedBundles []types.SimulatedBundle
196+
usedSbundles []types.UsedSBundle
197+
transactions []*types.TxWithMinerFee
198+
priceCutoffPercent = b.algoConf.PriceCutoffPercent
208199

209200
SortInPlaceByProfit = func(baseFee *big.Int, transactions []*types.TxWithMinerFee, gasUsedMap map[*types.TxWithMinerFee]uint64) {
210201
sort.SliceStable(transactions, func(i, j int) bool {
@@ -213,7 +204,7 @@ func (b *greedyBucketsBuilder) mergeOrdersIntoEnvDiff(
213204
}
214205
)
215206

216-
minPrice := CutoffPriceFromOrder(orders.Peek(), percent)
207+
minPrice := CutoffPriceFromOrder(orders.Peek(), priceCutoffPercent)
217208
for {
218209
order := orders.Peek()
219210
if order == nil {
@@ -241,7 +232,7 @@ func (b *greedyBucketsBuilder) mergeOrdersIntoEnvDiff(
241232
usedSbundles = append(usedSbundles, sbundles...)
242233
transactions = nil
243234
}
244-
minPrice = CutoffPriceFromOrder(order, percent)
235+
minPrice = CutoffPriceFromOrder(order, priceCutoffPercent)
245236
}
246237
}
247238

miner/miner.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ type Config struct {
9898
MaxMergedBundles int
9999
Blocklist []common.Address `toml:",omitempty"`
100100
NewPayloadTimeout time.Duration // The maximum time allowance for creating a new payload
101+
PriceCutoffPercent int // Effective gas price cutoff % used for bucketing transactions by price (only useful in greedy-buckets AlgoType)
101102
}
102103

103104
// DefaultConfig contains default settings for miner.
@@ -109,8 +110,9 @@ var DefaultConfig = Config{
109110
// consensus-layer usually will wait a half slot of time(6s)
110111
// for payload generation. It should be enough for Geth to
111112
// run 3 rounds.
112-
Recommit: 2 * time.Second,
113-
NewPayloadTimeout: 2 * time.Second,
113+
Recommit: 2 * time.Second,
114+
NewPayloadTimeout: 2 * time.Second,
115+
PriceCutoffPercent: defaultPriceCutoffPercent,
114116
}
115117

116118
// Miner creates blocks and searches for proof-of-work values.

miner/worker.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,13 +1405,19 @@ func (w *worker) fillTransactionsAlgoWorker(interrupt *int32, env *environment)
14051405

14061406
switch w.flashbots.algoType {
14071407
case ALGO_GREEDY_BUCKETS:
1408-
validationConf := &algorithmConfig{
1408+
priceCutoffPercent := w.config.PriceCutoffPercent
1409+
if !(priceCutoffPercent >= 0 && priceCutoffPercent <= 100) {
1410+
return nil, nil, nil, errors.New("invalid price cutoff percent - must be between 0 and 100")
1411+
}
1412+
1413+
algoConf := &algorithmConfig{
14091414
EnforceProfit: true,
14101415
ExpectedProfit: nil,
14111416
ProfitThresholdPercent: defaultProfitThreshold,
1417+
PriceCutoffPercent: priceCutoffPercent,
14121418
}
14131419
builder := newGreedyBucketsBuilder(
1414-
w.chain, w.chainConfig, validationConf, w.blockList, env,
1420+
w.chain, w.chainConfig, algoConf, w.blockList, env,
14151421
w.config.BuilderTxSigningKey, interrupt,
14161422
)
14171423

0 commit comments

Comments
 (0)