Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions miner/bid_simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ type bidSimulator struct {
simBidCh chan *simBidReq
newBidCh chan newBidPackage

pendingMu sync.RWMutex
pending map[uint64]map[common.Address]map[common.Hash]struct{} // blockNumber -> builder -> bidHash -> struct{}
pendingMu sync.RWMutex
pending map[uint64]map[common.Address]map[common.Hash]struct{} // blockNumber -> builder -> bidHash -> struct{}
pendingByName map[uint64]map[string]map[common.Hash]struct{} // blockNumber -> builderName -> bidHash -> struct{}

bestBidMu sync.RWMutex
bestBid map[common.Hash]*BidRuntime // prevBlockHash -> bidRuntime
Expand All @@ -128,7 +129,7 @@ type bidSimulator struct {
simulatingBid map[common.Hash]*BidRuntime // prevBlockHash -> bidRuntime, in the process of simulation
bidsToSim map[uint64][]*BidRuntime // blockNumber --> bidRuntime list, used to discard envs

maxBidsPerBuilder uint32 // Maximum number of bids allowed per builder per block
maxBidsPerBuilder uint32 // Maximum number of bids allowed per builder per block (now used for builder name)
}

func newBidSimulator(
Expand All @@ -154,6 +155,7 @@ func newBidSimulator(
simBidCh: make(chan *simBidReq),
newBidCh: make(chan newBidPackage, 100),
pending: make(map[uint64]map[common.Address]map[common.Hash]struct{}),
pendingByName: make(map[uint64]map[string]map[common.Hash]struct{}),
bestBid: make(map[common.Hash]*BidRuntime),
bestBidToRun: make(map[common.Hash]*types.Bid),
simulatingBid: make(map[common.Hash]*BidRuntime),
Expand Down Expand Up @@ -184,6 +186,11 @@ func newBidSimulator(
return b
}

// getBuilderName returns the builder name for the given address
func (b *bidSimulator) getBuilderName(builder common.Address) string {
return b.config.GetBuilderName(builder)
}

func (b *bidSimulator) dialSentryAndBuilders() {
var sentryCli *builderclient.Client
var err error
Expand Down Expand Up @@ -529,6 +536,7 @@ func (b *bidSimulator) clearLoop() {
clearFn := func(parentHash common.Hash, blockNumber uint64) {
b.pendingMu.Lock()
delete(b.pending, blockNumber)
delete(b.pendingByName, blockNumber)
b.pendingMu.Unlock()

// clearThreshold := b.chain.GetFinalizedNumber(b.chain.GetHeaderByHash(parentHash))
Expand Down Expand Up @@ -630,6 +638,20 @@ func (b *bidSimulator) CheckPending(blockNumber uint64, builder common.Address,
return fmt.Errorf("too many bids: exceeded limit of %d bids per builder per block", b.maxBidsPerBuilder)
}

// Check builder name limit
builderName := b.getBuilderName(builder)
if _, ok := b.pendingByName[blockNumber]; !ok {
b.pendingByName[blockNumber] = make(map[string]map[common.Hash]struct{})
}

if _, ok := b.pendingByName[blockNumber][builderName]; !ok {
b.pendingByName[blockNumber][builderName] = make(map[common.Hash]struct{})
}

if len(b.pendingByName[blockNumber][builderName]) >= int(b.maxBidsPerBuilder) {
return fmt.Errorf("too many bids: exceeded limit of %d bids per builder name (%s) per block", b.maxBidsPerBuilder, builderName)
}

return nil
}

Expand All @@ -638,6 +660,10 @@ func (b *bidSimulator) AddPending(blockNumber uint64, builder common.Address, bi
defer b.pendingMu.Unlock()

b.pending[blockNumber][builder][bidHash] = struct{}{}

// Also add to pendingByName
builderName := b.getBuilderName(builder)
b.pendingByName[blockNumber][builderName][bidHash] = struct{}{}
}

// simBid simulates a newBid with txs.
Expand Down
56 changes: 56 additions & 0 deletions miner/minerconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package minerconfig

import (
"math/big"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -86,6 +87,50 @@ var DefaultConfig = Config{
type BuilderConfig struct {
Address common.Address
URL string
Name string `toml:",omitempty"` // Builder name, if empty will use domain suffix from URL
}

// GetBuilderName returns the builder name for this config
// If Name is set, use it; otherwise extract from URL domain
func (bc *BuilderConfig) GetBuilderName() string {
if bc.Name != "" {
return bc.Name
}
if bc.URL != "" {
return extractDomainSuffix(bc.URL)
}
// If no URL, return address as string
return bc.Address.Hex()
}

// extractDomainSuffix extracts the domain suffix from a URL
// e.g., "https://tokyo.builder.blockrazor.io" -> "blockrazor"
func extractDomainSuffix(url string) string {
// Remove protocol
if idx := strings.Index(url, "://"); idx != -1 {
url = url[idx+3:]
}

// Remove port if present
if idx := strings.Index(url, ":"); idx != -1 {
url = url[:idx]
}

// Remove path
if idx := strings.Index(url, "/"); idx != -1 {
url = url[:idx]
}

// Split by dots
parts := strings.Split(url, ".")

// If length >= 2, return the second to last part
if len(parts) >= 2 {
return parts[len(parts)-2]
}

// For invalid formats, return the original URL
return url
}

type MevConfig struct {
Expand All @@ -100,6 +145,17 @@ type MevConfig struct {
MaxBidsPerBuilder *uint32 `toml:",omitempty"` // Maximum number of bids allowed per builder per block
}

// GetBuilderName returns the builder name for the given address
func (mc *MevConfig) GetBuilderName(builder common.Address) string {
for _, builderConfig := range mc.Builders {
if builderConfig.Address == builder {
return builderConfig.GetBuilderName()
}
}
// If no mapping found, return the address as string
return builder.Hex()
}

var DefaultMevConfig = MevConfig{
Enabled: &defaultMevEnabled,
GreedyMergeTx: &defaultGreedyMergeTx,
Expand Down
Loading