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

Increase sync size to 1s to avoid hitting 429 too many requests issue #21

Open
wants to merge 87 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
eb4d322
Implement geth-embedded builder API
Ruteri Apr 28, 2022
3c0d5f1
Adjust transactions root computation (#3)
Ruteri Jun 2, 2022
0211eab
Adjust logsBloom encoding (#4)
Ruteri Jun 2, 2022
6fbef37
Adjust base fee encoding (#5)
Ruteri Jun 3, 2022
b67d952
Allow resending of the same validator registration (#7)
Ruteri Jun 7, 2022
28fd947
Adjust value encoding (#9)
Ruteri Jun 10, 2022
3f12831
Adjust gas limit calculation (#8)
Ruteri Jun 10, 2022
0b356f2
Show builder pubkey on index page (#10)
Ruteri Jun 10, 2022
ab55c8c
Add remote relay connection for getting validator data (#11)
Ruteri Jul 21, 2022
69168ab
Run builder even if cannot connect to remote relay (#12)
Ruteri Jul 25, 2022
2cbfc71
Add GasUsed and GasLimit to bid trace (#13)
Ruteri Jul 29, 2022
1357e20
Upgrade github.com/btcsuite/btcd (#14)
Ruteri Aug 1, 2022
b06509e
Fix lint issues (#15)
Ruteri Aug 1, 2022
74375b1
Update README.md (#16)
thINKoor Aug 2, 2022
32a7206
Add block build trigger from beacon node api (#17)
avalonche Aug 11, 2022
7a6d33d
Addjust profit calculation and use the blocks channel directly
Ruteri Aug 11, 2022
262f18c
Add more explicit builder flags and other QoL improvements (#20)
Ruteri Aug 16, 2022
9d24d68
Resubmit block build job periodically (#22)
Ruteri Aug 25, 2022
f248ccb
Implement proposer payment via transaction (#23)
bhakiyakalimuthu Aug 11, 2022
b87888e
Base block profit on the proposer payment instead of balance differen…
Ruteri Aug 31, 2022
1633a5d
Flashbots change up to v0.3
jparyani Oct 27, 2021
7c424df
Flashbots changes v0.3 to v0.4
bogatyy Oct 27, 2021
4ea7e11
Flashbots changes v0.4 to v0.5
Ruteri Feb 21, 2022
70a26aa
Private Transaction API Sample (v1.10.13)
xcarlo Nov 29, 2021
a3d99c2
Remove private transactions that are confirmed in blocks
Jan 28, 2022
6fe1708
Run private transactions e2e tests in ci
Ruteri Feb 24, 2022
231448f
Discard reverting megabundle blocks and head change interrupted block…
Ruteri Mar 30, 2022
997e95b
Seal the best block available
Ruteri Jul 29, 2022
913a792
Implement block validation API
Ruteri Aug 17, 2022
e16c69e
Add timeout to e2e
Ruteri Aug 11, 2022
d55f648
Upgrade dependencies
Ruteri Aug 30, 2022
1bc67bd
Only submit blocks that improve profit (#19)
Ruteri Aug 31, 2022
6449811
Remove megabundles as they are no longer needed (#20)
Ruteri Aug 31, 2022
9b27c8a
Implement pushing blocks data to the DB (#18)
Ruteri Aug 31, 2022
74b7659
add miner blocklist (#21)
dvush Sep 1, 2022
624b2df
fix statedb copy (#22)
dvush Sep 2, 2022
a39100e
Rate limit blocks submitted to the relay and DB (#25)
Ruteri Sep 7, 2022
39d4fab
fix proposer payout bug with payout tx (#27)
dvush Sep 13, 2022
04d0def
add other state access to touch tracer (#26)
dvush Sep 13, 2022
ae3e497
init bundle fetcher (#24)
bhakiyakalimuthu Sep 13, 2022
47140e7
increase payment tx gas limit
dvush Sep 15, 2022
78b79f6
do not fetch bundle if empty block num during the starup (#29)
bhakiyakalimuthu Sep 19, 2022
4e08119
Update gas limit in api check (#30)
Ruteri Sep 20, 2022
f4fad7d
set proposer payment to 26k (#31)
dvush Sep 21, 2022
2b1d810
Adjust block number for bundle fetching (#32)
Ruteri Sep 21, 2022
97fa9c1
new greedy builder
dvush Sep 8, 2022
982e38f
sim bundles in parallel (new merger) (#33)
dvush Sep 23, 2022
570b42c
Merge new merger algo and mev-geth
Ruteri Sep 23, 2022
ba76641
Enable portable blst
Ruteri Sep 23, 2022
79c9121
Build on multiple tips (#35)
dvush Sep 28, 2022
fade0b7
better logs (#36)
dvush Sep 28, 2022
e5037ec
squash more annoying logs (#37)
dvush Sep 28, 2022
cee22fa
Logs pt 3 (#38)
dvush Sep 28, 2022
c5dae01
New payment tx (#40)
dvush Oct 5, 2022
dbe3dff
Improvements from greedy improve algo (#41)
Ruteri Oct 7, 2022
9a62829
Do not commit failing payment txs (#43)
Ruteri Oct 11, 2022
baf280f
More bundle visibility (#42)
Ruteri Oct 17, 2022
12041db
Cleanup and include old mev geth prs (#45)
Ruteri Oct 25, 2022
a4fd793
Increase submission rate to 2 blocks per second (#47)
Ruteri Oct 25, 2022
6152cfc
Add disable bundle fetcher flag (#48)
Ruteri Nov 3, 2022
5d7d714
update readme (#49)
dvush Nov 18, 2022
a10a730
Update README.md
metachris Nov 18, 2022
a02f4e0
Merge pull request #1 from flashbots/metachris-patch-1
bertmiller Nov 18, 2022
7379542
Merge changes from validation (#4)
Ruteri Nov 22, 2022
4d1b163
Use snapshots for blocklist revert (#5)
dvush Nov 22, 2022
f4d48be
added contributing.md (#8)
metachris Nov 23, 2022
9ca4d16
cleanup cla (#9)
metachris Nov 23, 2022
6cdb430
Add builder config toml support (#2)
refcell Nov 28, 2022
5d25e8b
Add submitting and requesting registrations from multiple relays
Ruteri Oct 18, 2022
2c80489
Refactor relay aggregator registrations and tests, add better logging
avalonche Nov 29, 2022
2456f57
Fix duplicate relay registrations in cache (#15)
avalonche Dec 5, 2022
c216aca
Improve performance of token compilation (#12)
estensen Dec 6, 2022
e7810b5
Increase submission delay from 0.5s to 1s
madjarevicn Dec 7, 2022
8033129
Merge branch 'main' of https://github.com/DcentraLab/builder
madjarevicn Dec 7, 2022
ff77df3
Set rate to 0.6 secs to avoid rate limit.
madjarevicn Dec 7, 2022
33935a5
Fix
madjarevicn Dec 8, 2022
6b30dbb
Update outdated parts of README (#22)
avalonche Dec 8, 2022
d2b1409
Add log for block.profit
madjarevicn Dec 14, 2022
e34a579
Merge branch 'flashbots:main' into main
madjarevicn Dec 14, 2022
78c823d
Create docker-image.yml
madjarevicn Dec 14, 2022
9d84d2d
Update Dockerfile
madjarevicn Dec 14, 2022
9d21297
updated dockerfile
madjarevicn Dec 14, 2022
2a85eb4
Update Dockerfile
madjarevicn Dec 19, 2022
c582dd0
Updated docker file COPY path.
Miljan9602 Dec 20, 2022
879010a
Merge pull request #1 from Miljan9602/patch-1
madjarevicn Dec 20, 2022
1c9a6a8
Updated dockerfile file
Miljan9602 Dec 21, 2022
0a0f211
Updated docker file with ./
Miljan9602 Dec 21, 2022
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
Prev Previous commit
Next Next commit
Implement block validation API
  • Loading branch information
Ruteri committed Nov 18, 2022
commit 913a7920141919d65cabb436c5074d915796f51a
7 changes: 6 additions & 1 deletion cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
builder "github.com/ethereum/go-ethereum/builder"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/core/rawdb"
blockvalidationapi "github.com/ethereum/go-ethereum/eth/block-validation"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/internal/flags"
Expand Down Expand Up @@ -203,7 +204,11 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
// Configure log filter RPC API.
filterSystem := utils.RegisterFilterAPI(stack, backend, &cfg.Eth)

// Configure GraphQL if requested.
if err := blockvalidationapi.Register(stack, eth, ctx); err != nil {
utils.Fatalf("Failed to register the Block Validation API: %v", err)
}

// Configure GraphQL if requested
if ctx.IsSet(utils.GraphQLEnabledFlag.Name) {
utils.RegisterGraphQLService(stack, backend, filterSystem, &cfg.Node)
}
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ var (
utils.GpoIgnoreGasPriceFlag,
utils.MinerNotifyFullFlag,
utils.IgnoreLegacyReceiptsFlag,
utils.BuilderBlockValidationBlacklistSourceFilePath,
configFileFlag,
}, utils.NetworkFlags, utils.DatabasePathFlags)

Expand Down
8 changes: 8 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,14 @@ var (
Value: metrics.DefaultConfig.InfluxDBOrganization,
Category: flags.MetricsCategory,
}

// Builder API flags
BuilderBlockValidationBlacklistSourceFilePath = &cli.StringFlag{
Name: "builder.validation_blacklist",
Usage: "Path to file containing blacklisted addresses, json-encoded list of strings. Default assumes CWD is repo's root",
Value: "ofac_blacklist.json",
Category: flags.EthCategory,
}
)

var (
Expand Down
34 changes: 34 additions & 0 deletions core/beacon/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/trie"

boostTypes "github.com/flashbots/go-boost-utils/types"
)

//go:generate go run github.com/fjl/gencodec -type PayloadAttributesV1 -field-override payloadAttributesMarshaling -out gen_blockparams.go
Expand Down Expand Up @@ -181,6 +183,38 @@ func ExecutableDataToBlock(params ExecutableDataV1) (*types.Block, error) {
return block, nil
}

func ExecutionPayloadToBlock(payload *boostTypes.ExecutionPayload) (*types.Block, error) {
// TODO: separate decode function to avoid allocating twice
transactionBytes := make([][]byte, len(payload.Transactions))
for i, txHexBytes := range payload.Transactions {
transactionBytes[i] = txHexBytes[:]
}
txs, err := decodeTransactions(transactionBytes)
if err != nil {
return nil, err
}

header := &types.Header{
ParentHash: common.Hash(payload.ParentHash),
UncleHash: types.EmptyUncleHash,
Coinbase: common.Address(payload.FeeRecipient),
Root: common.Hash(payload.StateRoot),
TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)),
ReceiptHash: common.Hash(payload.ReceiptsRoot),
Bloom: types.BytesToBloom(payload.LogsBloom[:]),
Difficulty: common.Big0,
Number: new(big.Int).SetUint64(payload.BlockNumber),
GasLimit: payload.GasLimit,
GasUsed: payload.GasUsed,
Time: payload.Timestamp,
BaseFee: payload.BaseFeePerGas.BigInt(),
Extra: payload.ExtraData,
MixDigest: common.Hash(payload.Random),
}
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
return block, nil
}

// BlockToExecutableData constructs the executableDataV1 structure by filling the
// fields from the given block. It assumes the given block is post-merge block.
func BlockToExecutableData(block *types.Block) *ExecutableDataV1 {
Expand Down
71 changes: 71 additions & 0 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2421,3 +2421,74 @@ func (bc *BlockChain) SetBlockValidatorAndProcessorForTesting(v Validator, p Pro
bc.validator = v
bc.processor = p
}

func (bc *BlockChain) ValidatePayload(block *types.Block, feeRecipient common.Address, expectedProfit *big.Int, vmConfig vm.Config) error {
header := block.Header()
if err := bc.engine.VerifyHeader(bc, header, true); err != nil {
return err
}

current := bc.CurrentBlock()
reorg, err := bc.forker.ReorgNeeded(current.Header(), header)
if err == nil && reorg {
return errors.New("block requires a reorg")
}

parent := bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
if parent == nil {
return errors.New("parent not found")
}

statedb, err := bc.StateAt(parent.Root)
if err != nil {
return err
}

// The chain importer is starting and stopping trie prefetchers. If a bad
// block or other error is hit however, an early return may not properly
// terminate the background threads. This defer ensures that we clean up
// and dangling prefetcher, without defering each and holding on live refs.
defer statedb.StopPrefetcher()

receipts, _, usedGas, err := bc.processor.Process(block, statedb, vmConfig)
if err != nil {
return err
}

if err := bc.validator.ValidateBody(block); err != nil {
return err
}

if err := bc.validator.ValidateState(block, statedb, receipts, usedGas); err != nil {
return err
}

if len(receipts) == 0 {
return errors.New("no proposer payment receipt")
}

lastReceipt := receipts[len(receipts)-1]
if lastReceipt.Status != types.ReceiptStatusSuccessful {
return errors.New("proposer payment not successful")
}
txIndex := lastReceipt.TransactionIndex
if txIndex+1 != uint(len(block.Transactions())) {
return fmt.Errorf("proposer payment index not last transaction in the block (%d of %d)", txIndex, len(block.Transactions())-1)
}

paymentTx := block.Transaction(lastReceipt.TxHash)
if paymentTx == nil {
return errors.New("payment tx not in the block")
}

paymentTo := paymentTx.To()
if paymentTo == nil || *paymentTo != feeRecipient {
return fmt.Errorf("payment tx not to the proposers fee recipient (%v)", paymentTo)
}

if paymentTx.Value().Cmp(expectedProfit) != 0 {
return fmt.Errorf("inaccurate payment %s, expected %s", paymentTx.Value().String(), expectedProfit.String())
}

return nil
}
175 changes: 175 additions & 0 deletions eth/block-validation/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package blockvalidation

import (
"encoding/json"
"errors"
"fmt"
"math/big"
"os"

"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/beacon"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/rpc"
"github.com/urfave/cli/v2"

boostTypes "github.com/flashbots/go-boost-utils/types"
)

type BlacklistedAddresses []common.Address

type AccessVerifier struct {
blacklistedAddresses map[common.Address]struct{}
}

func (a *AccessVerifier) verifyTraces(tracer *logger.AccessListTracer) error {
log.Info("x", "tracer.AccessList()", tracer.AccessList())
for _, accessTuple := range tracer.AccessList() {
// TODO: should we ignore common.Address{}?
if _, found := a.blacklistedAddresses[accessTuple.Address]; found {
log.Info("bundle accesses blacklisted address", "address", accessTuple.Address)
return fmt.Errorf("blacklisted address %s in execution trace", accessTuple.Address.String())
}
}

return nil
}

func (a *AccessVerifier) verifyTransactions(signer types.Signer, txs types.Transactions) error {
for _, tx := range txs {
from, err := signer.Sender(tx)
if err == nil {
if _, present := a.blacklistedAddresses[from]; present {
return fmt.Errorf("transaction from blacklisted address %s", from.String())
}
}
to := tx.To()
if to != nil {
if _, present := a.blacklistedAddresses[*to]; present {
return fmt.Errorf("transaction to blacklisted address %s", to.String())
}
}
}
return nil
}

func NewAccessVerifierFromFile(path string) (*AccessVerifier, error) {
bytes, err := os.ReadFile(path)
if err != nil {
return nil, err
}

var ba BlacklistedAddresses
if err := json.Unmarshal(bytes, &ba); err != nil {
return nil, err
}

blacklistedAddresses := make(map[common.Address]struct{}, len(ba))
for _, address := range ba {
blacklistedAddresses[address] = struct{}{}
}

return &AccessVerifier{
blacklistedAddresses: blacklistedAddresses,
}, nil
}

// Register adds catalyst APIs to the full node.
func Register(stack *node.Node, backend *eth.Ethereum, ctx *cli.Context) error {
var accessVerifier *AccessVerifier
if ctx.IsSet(utils.BuilderBlockValidationBlacklistSourceFilePath.Name) {
var err error
accessVerifier, err = NewAccessVerifierFromFile(ctx.String(utils.BuilderBlockValidationBlacklistSourceFilePath.Name))
if err != nil {
return err
}
}

stack.RegisterAPIs([]rpc.API{
{
Namespace: "flashbots",
Service: NewBlockValidationAPI(backend, accessVerifier),
},
})
return nil
}

type BlockValidationAPI struct {
eth *eth.Ethereum
accessVerifier *AccessVerifier
}

// NewConsensusAPI creates a new consensus api for the given backend.
// The underlying blockchain needs to have a valid terminal total difficulty set.
func NewBlockValidationAPI(eth *eth.Ethereum, accessVerifier *AccessVerifier) *BlockValidationAPI {
return &BlockValidationAPI{
eth: eth,
accessVerifier: accessVerifier,
}
}

func (api *BlockValidationAPI) ValidateBuilderSubmissionV1(params *boostTypes.BuilderSubmitBlockRequest) error {
// TODO: fuzztest, make sure the validation is sound
// TODO: handle context!

if params.ExecutionPayload == nil {
return errors.New("nil execution payload")
}
payload := params.ExecutionPayload
block, err := beacon.ExecutionPayloadToBlock(payload)
if err != nil {
return err
}

if params.Message.ParentHash != boostTypes.Hash(block.ParentHash()) {
return fmt.Errorf("incorrect ParentHash %s, expected %s", params.Message.ParentHash.String(), block.ParentHash().String())
}

if params.Message.BlockHash != boostTypes.Hash(block.Hash()) {
return fmt.Errorf("incorrect BlockHash %s, expected %s", params.Message.BlockHash.String(), block.Hash().String())
}

if params.Message.GasLimit != block.GasLimit() {
return fmt.Errorf("incorrect GasLimit %d, expected %d", params.Message.GasLimit, block.GasLimit())
}

if params.Message.GasUsed != block.GasUsed() {
return fmt.Errorf("incorrect GasUsed %d, expected %d", params.Message.GasUsed, block.GasUsed())
}

feeRecipient := common.BytesToAddress(params.Message.ProposerFeeRecipient[:])
expectedProfit := params.Message.Value.BigInt()

var vmconfig vm.Config
var tracer *logger.AccessListTracer = nil
if api.accessVerifier != nil {
if err := api.accessVerifier.verifyTransactions(types.LatestSigner(api.eth.BlockChain().Config()), block.Transactions()); err != nil {
return err
}
isPostMerge := true // the call is PoS-native
precompiles := vm.ActivePrecompiles(api.eth.APIBackend.ChainConfig().Rules(new(big.Int).SetUint64(params.ExecutionPayload.BlockNumber), isPostMerge))
tracer = logger.NewAccessListTracer(nil, common.Address{}, common.Address{}, precompiles)
vmconfig = vm.Config{Tracer: tracer, Debug: true}
}

err = api.eth.BlockChain().ValidatePayload(block, feeRecipient, expectedProfit, vmconfig)
if err != nil {
log.Error("invalid payload", "hash", payload.BlockHash.String(), "number", payload.BlockNumber, "parentHash", payload.ParentHash.String(), "err", err)
return err
}

if api.accessVerifier != nil && tracer != nil {
if err := api.accessVerifier.verifyTraces(tracer); err != nil {
return err
}
}

log.Info("validated block", "hash", block.Hash(), "number", block.NumberU64(), "parentHash", block.ParentHash())
return nil
}
Loading