flashbots / mev-geth Goto Github PK
View Code? Open in Web Editor NEWThis project forked from ethereum/go-ethereum
Go implementation of MEV-Auction for Ethereum
License: GNU Lesser General Public License v3.0
This project forked from ethereum/go-ethereum
Go implementation of MEV-Auction for Ethereum
License: GNU Lesser General Public License v3.0
Why should this feature exist?
There is no hiding it, there is no lack of lazy people out there (like me!)
What are the use-cases?
Easier onboarding of new searchers by not having to setup the go toolchain first
Do you have ideas regarding the implementation of this feature?
I think it would be trivial with GitHub actions (knock on wood)
https://github.com/marketplace/actions/go-release-binary
Are you willing to implement this feature?
If that's what needed! 👯♂️
We should find a better name for this, but the idea is that a bundle often changes token balances (ETH, ERC20, NFT's, etc) and while it's possible to "sandwich" your bundle with balanceOf
calls for specific tokens you expect to transfer within a bundle, for a specific account, we could automatically figure out which tokens were moved. We should create an RPC endpoint that returns a report of all token balances that were modified as a result of this bundle running in simulation.
When conducting whitehat rescues, especially for a brand new rescue type, this is one of the most sensitive issues: your custom code worked enough to rescue assets, but has a bug that locks assets or transfers to the wrong place. Having bundle execution distilled to a set of balance changes would help prevent accidental fund loss by providing positive confirmation of token flow.
If this could be combined with Flashbots protect RPC endpoint, we could easily prevent certain behaviors from propagating through our RPC (like TokenOops).
I think this would be a separate endpoint from callBundle
, as that should be as fast as possible, and this implementation would require at LEAST two simulation passes and many extraneous storage lookups.
Would be fine to either use signed or unsigned transactions
Miners have expressed some confusion around how the mev-geth repo is structured.
Should review documentation to clarify our release process, commits, and branches.
type: feature-request
discussion: flashbots/pm#52
product: mev-geth
build linux version ,geth -v show VERSION is 1.10.3-stable-4c1ff91c
build windows version by command: env CC=x86_64-w64-mingw32-gcc-posix CXX=x86_64-w64-mingw32-g++-posix CGO_CFLAGS="-D_WIN32_WINNT=0x0400" CGO_CXXFLAGS="-D_WIN32_WINNT=0x0400" /root/go/bin/gox -cgo -osarch="windows/amd64" ./...
then show VERSION is 1.10.3-stable.
something maybe still use ethereum/go-ethereum , not /flashbots/mev-geth?
New Ethereum JSON-RPC Endpoint - Transaction Simulation
Ethereum's RPC currently lacks a way to eth_call or trace a transaction at the HEAD of a block, which is where flashbot bundles will always land. Given that flashbot bundles will not always land (either due to another bundle being selected or the miner for the target block not being a flashbots miner), simulating a transanction is extremely important to give the developer feedback. From a developer's perspective, there is no difference between their code failing to work properly and their bundle not being selected for any other reason.
To fix the above issue, we need a new jsonrpc endpoint to allow simulation of a flashbots bundle at the HEAD of a block. I believe we can accomplish this in a way that is generally useful and would be accepted upstream.
Currently, eth_call allows you to specify an arbitrary transaction, at an arbitrary block height (within your pruning window) and returns the return data. Since it is simulating a transaction and not running inside a "real" block, it needs to select a value for miner, block number, and timestamp. When passed a block, eth_call uses the storage state that was computed AFTER that block had run: if you pass in block 780, it would include all transactions that were included inside block 780. However, the block value and timestamp it selects are those from block 780 as well, effectively simulating transacctions at the "tail" of the block.
I propose a modification to eth_call:
eth_call({transaction}, block_tag [, fake_block_number, fake_timestamp, fake_miner])
These optional values would override the simulated transaction's default for the variables. If you wanted to simulate something that happens at the head of block 780, you would call:
eth_call({transaction}, 779 , 780, $BLOCK_779's_TIMESTAMP_PLUS_X_SECONDS])
Something important to mention here is that we've been talking about eth_call for simplicity here, but eth_call is missing:
1.) a multi-transaction endpoint that will take an array of transactioins to simulate, each building on each other sequentially
2.) Something that returns traces of value transferred, not just the RETURN data of the function call
This might be possible with geth's trace module:
https://github.com/ethereum/go-ethereum/wiki/Tracing:-Introduction
"go-ethereum supports running custom JavaScript tracers within the Ethereum node, which have full access to the EVM stack, memory and contract storage"
There's also OpenEthereum's trace endpoint that solves both of the above features: trace_callMany
https://openethereum.wiki/JSONRPC-trace-module/#example_1
It might be easier to add this endpoint to OpenEthereum instead of geth and we already use OpenEthereum for other mev-inspect. This end point does not necessarily need to live in geth, and would never be run against the same node as the bundle selection eth_sendBundle
endpoint.
Geth version: geth version
Geth
Version: 1.10.16-stable
Git Commit: ec93a8f
Git Commit Date: 20220302
Architecture: amd64
Go Version: go1.18
Operating System: linux
GOPATH=
GOROOT=go
OS & Version: Linux Ubunut 20.04
Commit hash : (if develop
)
mv-geth config:
[Eth]
NetworkId = 1
SyncMode = "light"
EthDiscoveryURLs = ["enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@les.mainnet.ethdisco.net"]
SnapDiscoveryURLs = ["enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@les.mainnet.ethdisco.net"]
NoPruning = false
NoPrefetch = false
TxLookupLimit = 2350000
LightPeers = 100
UltraLightFraction = 75
DatabaseCache = 512
DatabaseFreezer = ""
TrieCleanCache = 154
TrieCleanCacheJournal = "triecache"
TrieCleanCacheRejournal = 3600000000000
TrieDirtyCache = 256
TrieTimeout = 3600000000000
SnapshotCache = 102
Preimages = false
EnablePreimageRecording = false
RPCGasCap = 50000000
RPCEVMTimeout = 0
RPCTxFeeCap = 1e+00
[Eth.Miner]
GasFloor = 0
GasCeil = 8000000
GasPrice = 1000000000
Recommit = 3000000000
Noverify = false
MaxMergedBundles = 3
TrustedRelays = ["0x870e2734ddbe2fba9864f33f3420d59bc641f2be"]
[Eth.Ethash]
CacheDir = "ethash"
CachesInMem = 2
CachesOnDisk = 3
CachesLockMmap = false
DatasetDir = "/home/david/.ethash"
DatasetsInMem = 1
DatasetsOnDisk = 2
DatasetsLockMmap = false
PowMode = 0
NotifyFull = false
[Eth.TxPool]
Locals = []
NoLocals = false
Journal = "transactions.rlp"
Rejournal = 3600000000000
PriceLimit = 1
PriceBump = 10
AccountSlots = 16
GlobalSlots = 5120
AccountQueue = 64
GlobalQueue = 1024
Lifetime = 10800000000000
PrivateTxLifetime = 259200000000000
TrustedRelays = ["0x870e2734ddbe2fba9864f33f3420d59bc641f2be"]
[Eth.GPO]
Blocks = 2
Percentile = 60
MaxHeaderHistory = 300
MaxBlockHistory = 5
MaxPrice = 500000000000
IgnorePrice = 2
[Node]
DataDir = "/home/david/.ethereum"
IPCPath = "geth.ipc"
HTTPHost = "localhost"
HTTPPort = 8545
HTTPVirtualHosts = ["localhost"]
HTTPModules = ["eth", "net", "web3"]
WSHost = ""
WSPort = 8546
WSModules = ["net", "web3", "eth"]
GraphQLVirtualHosts = ["localhost"]
[Node.P2P]
MaxPeers = 50
NoDiscovery = true
DiscoveryV5 = true
BootstrapNodes = ["enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303", "enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303", "enode://ca6de62fce278f96aea6ec5a2daadb877e51651247cb96ee310a318def462913b653963c155a0ef6c7d50048bba6e6cea881130857413d9f50a621546b590758@34.255.23.113:30303", "enode://279944d8dcd428dffaa7436f25ca0ca43ae19e7bcf94a8fb7d1641651f92d121e972ac2e8f381414b80cc8e5555811c2ec6e1a99bb009b3f53c4c69923e11bd8@35.158.244.151:30303", "enode://8499da03c47d637b20eee24eec3c356c9a2e6148d6fe25ca195c7949ab8ec2c03e3556126b0d7ed644675e78c4318b08691b7b57de10e5f0d40d05b09238fa0a@52.187.207.27:30303", "enode://103858bdb88756c71f15e9b5e09b56dc1be52f0a5021d46301dbbfb7e130029cc9d0d6f73f693bc29b665770fff7da4d34f3c6379fe12721b5d7a0bcb5ca1fc1@191.234.162.198:30303", "enode://715171f50508aba88aecd1250af392a45a330af91d7b90701c436b618c86aaa1589c9184561907bebbb56439b8f8787bc01f49a7c77276c58c1b09822d75e8e8@52.231.165.108:30303", "enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303"]
BootstrapNodesV5 = ["enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA", "enr:-KG4QDyytgmE4f7AnvW-ZaUOIi9i79qX4JwjRAiXBZCU65wOfBu-3Nb5I7b_Rmg3KCOcZM_C3y5pg7EBU5XGrcLTduQEhGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQ2_DUbiXNlY3AyNTZrMaEDKnz_-ps3UUOfHWVYaskI5kWYO_vtYMGYCQRAR3gHDouDdGNwgiMog3VkcIIjKA", "enr:-Ku4QImhMc1z8yCiNJ1TyUxdcfNucje3BGwEHzodEZUan8PherEo4sF7pPHPSIB1NNuSg5fZy7qFsjmUKs2ea1Whi0EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQOVphkDqal4QzPMksc5wnpuC3gvSC8AfbFOnZY_On34wIN1ZHCCIyg", "enr:-Ku4QP2xDnEtUXIjzJ_DhlCRN9SN99RYQPJL92TMlSv7U5C1YnYLjwOQHgZIUXw6c-BvRg2Yc2QsZxxoS_pPRVe0yK8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMeFF5GrS7UZpAH2Ly84aLK-TyvH-dRo0JM1i8yygH50YN1ZHCCJxA", "enr:-Ku4QPp9z1W4tAO8Ber_NQierYaOStqhDqQdOPY3bB3jDgkjcbk6YrEnVYIiCBbTxuar3CzS528d2iE7TdJsrL-dEKoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMw5fqqkw2hHC4F5HZZDPsNmPdB1Gi8JPQK7pRc9XHh-oN1ZHCCKvg", "enr:-IS4QLkKqDMy_ExrpOEWa59NiClemOnor-krjp4qoeZwIw2QduPC-q7Kz4u1IOWf3DDbdxqQIgC4fejavBOuUPy-HE4BgmlkgnY0gmlwhCLzAHqJc2VjcDI1NmsxoQLQSJfEAHZApkm5edTCZ_4qps_1k_ub2CxHFxi-gr2JMIN1ZHCCIyg", "enr:-IS4QDAyibHCzYZmIYZCjXwU9BqpotWmv2BsFlIq1V31BwDDMJPFEbox1ijT5c2Ou3kvieOKejxuaCqIcjxBjJ_3j_cBgmlkgnY0gmlwhAMaHiCJc2VjcDI1NmsxoQJIdpj_foZ02MXz4It8xKD7yUHTBx7lVFn3oeRP21KRV4N1ZHCCIyg", "enr:-Ku4QHqVeJ8PPICcWk1vSn_XcSkjOkNiTg6Fmii5j6vUQgvzMc9L1goFnLKgXqBJspJjIsB91LTOleFmyWWrFVATGngBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAMRHkWJc2VjcDI1NmsxoQKLVXFOhp2uX6jeT0DvvDpPcU8FWMjQdR4wMuORMhpX24N1ZHCCIyg", "enr:-Ku4QG-2_Md3sZIAUebGYT6g0SMskIml77l6yR-M_JXc-UdNHCmHQeOiMLbylPejyJsdAPsTHJyjJB2sYGDLe0dn8uYBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhBLY-NyJc2VjcDI1NmsxoQORcM6e19T1T9gi7jxEZjk_sjVLGFscUNqAY9obgZaxbIN1ZHCCIyg", "enr:-Ku4QPn5eVhcoF1opaFEvg1b6JNFD2rqVkHQ8HApOKK61OIcIXD127bKWgAtbwI7pnxx6cDyk_nI88TrZKQaGMZj0q0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDayLMaJc2VjcDI1NmsxoQK2sBOLGcUb4AwuYzFuAVCaNHA-dy24UuEKkeFNgCVCsIN1ZHCCIyg", "enr:-Ku4QEWzdnVtXc2Q0ZVigfCGggOVB2Vc1ZCPEc6j21NIFLODSJbvNaef1g4PxhPwl_3kax86YPheFUSLXPRs98vvYsoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDZBrP2Jc2VjcDI1NmsxoQM6jr8Rb1ktLEsVcKAPa08wCsKUmvoQ8khiOl_SLozf9IN1ZHCCIyg"]
StaticNodes = []
TrustedNodes = []
ListenAddr = ":30303"
EnableMsgEvents = false
[Node.HTTPTimeouts]
ReadTimeout = 30000000000
WriteTimeout = 30000000000
IdleTimeout = 120000000000
[Metrics]
HTTP = "127.0.0.1"
Port = 6060
InfluxDBEndpoint = "http://localhost:8086"
InfluxDBDatabase = "geth"
InfluxDBUsername = "test"
InfluxDBPassword = "test"
InfluxDBTags = "host=localhost"
InfluxDBToken = "test"
InfluxDBBucket = "geth"
InfluxDBOrganization = "geth"
Expecting same performance when calling the getPairsByIndexRange from Uniswap Lookup contract (0x5EF1009b9FCD4fec3094a5564047e190D72Bd511) like with "naked" Geth.
When calling getPairsByIndexRange on Uniswap Loopup contract (0x5EF1009b9FCD4fec3094a5564047e190D72Bd511) mev-geth never answers and timeout occurs.
INFO [03-17|19:21:10.730] Looking for peers peercount=2 tried=7 static=0
WARN [03-17|19:21:11.664] Served eth_call conn=127.0.0.1:37068 reqid=54 duration=1m58.94807364s err="getDeleteStateObject (9f1f56944016a42001ab2df0a16d1f0907708f2b) error: context canceled"
WARN [03-17|19:21:11.664] Served eth_call conn=127.0.0.1:37066 reqid=53 duration=2m0.022351454s err="getDeleteStateObject (829bd824b016326a401d083b33d092293333a830) error: context canceled"
INFO [03-17|19:21:22.044] Looking for peers peercount=2 tried=6 static=0
Uncaught Error Error: timeout (requestBody="{\"method\":\"eth_call\",\"params\":[{\"to\":\"0x5ef1009b9fcd4fec3094a5564047e190d72bd511\",\"data\":\"0xab2217e4000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac00000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000007d0\"},\"latest\"],\"id\":53,\"jsonrpc\":\"2.0\"}", requestMethod="POST", timeout=120000, url="http://127.0.0.1:8545", code=TIMEOUT, version=web/5.6.0)
at Logger.makeError (/home/david/development/flashbot/samples/simple-arbitrage/node_modules/@ethersproject/logger/src.ts/index.ts:261:28)
at <anonymous> (/home/david/development/flashbot/samples/simple-arbitrage/node_modules/@ethersproject/web/src.ts/index.ts:216:35)
at listOnTimeout (node:internal/timers:559:17)
at processTimers (node:internal/timers:502:7)
Now the latest version of GETH official website is v1.10.12。When will the v1.10.12-mev0.4.0 version be made。
Miners have been making suggestions in DMs for how to improve mev-geth to make it easier to integrate in mining pool infrastructure.
We should write up and simplify he process for them to describe their requests through issues on this repo.
I sent this TX with flashbot, but not sure why it was completed since I thought with the flashbot there should be no failing TX.
The strange thing is that the block explorer doesn't even show any TX in this block, but I am 100% sure I sent it with flashbot
https://etherscan.io/tx/0xD051CD11BF565686DC844CFEC21AE3812DEB7F52A26BB751AE0D5C452554247D
https://flashbots-explorer.marto.lol/?block=13165374
could it be that the relay sent it to a non mev node?
MEV exists for manipulating BLOCKHASH
.
Why should this feature exist?
Because it is MEV.
What are the use-cases?
Gaming. Random drops.
I do understand that controlling the BLOCKHASH
for just one bit equals the electricity cost of mining one block.
So the fee offered for this control must exceed that. Also, these fees can be combined—if multiple people want a BLOCKHASH
that is an even number, they can both pay the fee.
Going forward with proof of stake, the cost of mining goes to zero. So I think this pricing will become a lot more accessible.
The most important thing at this time is to discuss now if this might be implemented.
Do you have ideas regarding the implementation of this feature?
The BlockhashDesirability
smart contract interface is defined as follows:
interface BlockhashDesirability {
function isDesirable(bytes32 txHash, bytes32 blockhash) pure returns (bool);
}
Then we publish a singleton public utility contract, FLASHBOTS_BLOCKHASH_BOUNTY
implementing:
interface FlashbatsBlockhashBounty {
function fundBounty(bytes32 txHash, uint256 expirationTime, BlockhashDesirability checker) payable; // emits event Bounty(uint256 id);
function bountyDetails(uint256 bountyID) returns (...);
function takeBountyForNotPublishingUndesiribleBlock(uint256 bountyID, bytes32 blockhash, address coinbase, bytes inclusionProof) payable;
function takeBountyForPublishingDesiribleBlock(uint256 bountyID, uint256 blockNumber, address coinbase, bytes inclusionProof);
...
}
A searcher wants to influence the BLOCKHASH
. In this example they are sending Ether to a commit-reveal coin flip that has a desirable result If the BLOCKHASH
that tx is included in has zero in the last bit:
TX_HEADS
which starts the commit-reveal.TX_HEADS
transaction and the bounty ID to the miner.takeBountyForPublishingDesiribleBlock
.takeBountyForPublishingDesiribleBlock
. This bounty is very large.TX_HEADS
which starts the commit-reveal.TX_HEADS
transaction and the bounty ID to the miner.takeBountyForPublishingDesiribleBlock
. This bounty is large.takeBountyForPublishingDesiribleBlock
. This bounty is small.Maybe
Geth
Version: 1.9.26-unstable
Git Commit: f1436fb
Git Commit Date: 20210220
Architecture: amd64
Protocol Versions: [65 64 63]
Go Version: go1.16
Operating System: darwin
GOPATH=
GOROOT=go
geth syncs
geth syncs, then crashed
make geth
./build/bin/geth
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x40745c7]
goroutine 197275 [running]:
github.com/ethereum/go-ethereum/rlp.(*encbuf).encodeString(0xc0076d22a0, 0x0, 0x20, 0x20)
github.com/ethereum/go-ethereum/rlp/encode.go:179 +0x13c
github.com/ethereum/go-ethereum/rlp.writeBytes(0x4d9a020, 0xc0b0013a20, 0x97, 0xc0076d22a0, 0x4d9a020, 0xc0b0013a20)
github.com/ethereum/go-ethereum/rlp/encode.go:428 +0x6b
github.com/ethereum/go-ethereum/rlp.makeStructWriter.func1(0x4e92420, 0xc0b00139f0, 0x99, 0xc0076d22a0, 0x4e90000, 0xc0771669c0)
github.com/ethereum/go-ethereum/rlp/encode.go:552 +0x182
github.com/ethereum/go-ethereum/rlp.(*encbuf).encode(0xc0076d22a0, 0x4e92420, 0xc0b00139f0, 0x0, 0xc00063b0f0)
github.com/ethereum/go-ethereum/rlp/encode.go:160 +0x142
github.com/ethereum/go-ethereum/rlp.Encode(0x51903a0, 0xc0076d22a0, 0x4e92420, 0xc0b00139f0, 0x0, 0x0)
github.com/ethereum/go-ethereum/rlp/encode.go:57 +0x74
github.com/ethereum/go-ethereum/core/types.(*Log).EncodeRLP(0xc0b38b2210, 0x51903a0, 0xc0076d22a0, 0x48c6b978, 0xc0b38b2210)
github.com/ethereum/go-ethereum/core/types/log.go:88 +0xc8
github.com/ethereum/go-ethereum/rlp.makeEncoderWriter.func2(0x4f25ea0, 0xc0b38b2210, 0x199, 0xc0076d22a0, 0xc0b38b2210, 0x199)
github.com/ethereum/go-ethereum/rlp/encode.go:602 +0x15b
github.com/ethereum/go-ethereum/rlp.makePtrWriter.func1(0x4e54460, 0xc0b2889740, 0x196, 0xc0076d22a0, 0x4e54460, 0xc0b2889740)
github.com/ethereum/go-ethereum/rlp/encode.go:584 +0x29d
github.com/ethereum/go-ethereum/rlp.makeSliceWriter.func1(0x4d8d720, 0xc090d1ac60, 0x197, 0xc0076d22a0, 0x0, 0x0)
github.com/ethereum/go-ethereum/rlp/encode.go:530 +0x11d
github.com/ethereum/go-ethereum/rlp.makeStructWriter.func1(0x4ec38e0, 0xc090d1ab40, 0x199, 0xc0076d22a0, 0xc090d1ab40, 0x199)
github.com/ethereum/go-ethereum/rlp/encode.go:552 +0x182
github.com/ethereum/go-ethereum/rlp.makePtrWriter.func1(0x4d71840, 0xc090d1ab40, 0x16, 0xc0076d22a0, 0x4d70000, 0xc0818cc1b0)
github.com/ethereum/go-ethereum/rlp/encode.go:584 +0x29d
github.com/ethereum/go-ethereum/rlp.(*encbuf).encode(0xc0076d22a0, 0x4d71840, 0xc090d1ab40, 0xc000101680, 0x0)
github.com/ethereum/go-ethereum/rlp/encode.go:160 +0x142
github.com/ethereum/go-ethereum/rlp.Encode(0x51903a0, 0xc0076d22a0, 0x4d71840, 0xc090d1ab40, 0x0, 0x0)
github.com/ethereum/go-ethereum/rlp/encode.go:57 +0x74
github.com/ethereum/go-ethereum/core/types.(*Receipt).EncodeRLP(0xc0b38aea80, 0x51903a0, 0xc0076d22a0, 0x497e5c58, 0xc0b38aea80)
github.com/ethereum/go-ethereum/core/types/receipt.go:130 +0x132
github.com/ethereum/go-ethereum/rlp.makeEncoderWriter.func2(0x4f34a40, 0xc0b38aea80, 0x199, 0xc0076d22a0, 0xc0b38aea80, 0x199)
github.com/ethereum/go-ethereum/rlp/encode.go:602 +0x15b
github.com/ethereum/go-ethereum/rlp.makePtrWriter.func1(0x4ebaee0, 0xc0b38aea80, 0x16, 0xc0076d22a0, 0x4eb0000, 0xc0818181b0)
github.com/ethereum/go-ethereum/rlp/encode.go:584 +0x29d
github.com/ethereum/go-ethereum/rlp.(*encbuf).encode(0xc0076d22a0, 0x4ebaee0, 0xc0b38aea80, 0x3, 0xc089de4000)
github.com/ethereum/go-ethereum/rlp/encode.go:160 +0x142
github.com/ethereum/go-ethereum/rlp.EncodeToBytes(0x4ebaee0, 0xc0b38aea80, 0x0, 0x0, 0x0, 0x0, 0x0)
github.com/ethereum/go-ethereum/rlp/encode.go:74 +0xdb
github.com/ethereum/go-ethereum/core/types.Receipts.GetRlp(...)
github.com/ethereum/go-ethereum/core/types/receipt.go:288
github.com/ethereum/go-ethereum/core/types.DeriveSha(0x519f8e8, 0xc08a88b7a0, 0x51a56c8, 0xc0ae56c750, 0x0, 0x0, 0x0, 0x0)
github.com/ethereum/go-ethereum/core/types/derive_sha.go:47 +0xd8
github.com/ethereum/go-ethereum/eth/downloader.(*queue).DeliverReceipts.func1(0xd, 0xc078045d40, 0x48c98187051db274, 0x662617a138328dc0)
github.com/ethereum/go-ethereum/eth/downloader/queue.go:805 +0xb5
github.com/ethereum/go-ethereum/eth/downloader.(*queue).deliver(0xc01a0e61e0, 0xc0a5000820, 0x10, 0xc0ced46000, 0xc00053a000, 0xc0ced46030, 0x51bd6e0, 0x5ab3ae8, 0x45, 0xc00063bac0, ...)
github.com/ethereum/go-ethereum/eth/downloader/queue.go:855 +0x2a6
github.com/ethereum/go-ethereum/eth/downloader.(*queue).DeliverReceipts(0xc01a0e61e0, 0xc0a5000820, 0x10, 0xc0b2d16900, 0x45, 0x5e, 0x0, 0x0, 0x0)
github.com/ethereum/go-ethereum/eth/downloader/queue.go:814 +0x197
github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).fetchReceipts.func1(0x51a5398, 0xc078f96cc0, 0x10, 0xc00921a780, 0x5)
github.com/ethereum/go-ethereum/eth/downloader/downloader.go:1265 +0x74
github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).fetchParts(0xc000536380, 0xc00020eae0, 0xc00063bea0, 0xc00007c0e0, 0xc00063be90, 0xc00063bef0, 0xc00063bee0, 0xc00063bed0, 0x0, 0x5063248, ...)
github.com/ethereum/go-ethereum/eth/downloader/downloader.go:1331 +0x2d2
github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).fetchReceipts(0xc000536380, 0x416af4, 0xc087ab57b8, 0x471489a)
github.com/ethereum/go-ethereum/eth/downloader/downloader.go:1274 +0x2c5
github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).syncWithPeer.func5(0x0, 0x4d75dc0)
github.com/ethereum/go-ethereum/eth/downloader/downloader.go:546 +0x36
github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).spawnSync.func1(0xc000536380, 0xc0087297a0, 0xc00e7a92d8)
github.com/ethereum/go-ethereum/eth/downloader/downloader.go:568 +0x5b
created by github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).spawnSync
github.com/ethereum/go-ethereum/eth/downloader/downloader.go:568 +0xaf
eth_sendMegaBundle would allow for sending bundles which bypass the bundle scoring auction and instead are directly inserted in a block in the multi-worker
the mev-geth node is reponsible for filling the remaining space in the block with transactions from the mempool
the rpc parameters would be:
{
"transaction_list": [],
"timestamp": "",
"coinbase_diff": "",
"coinbase": "0x",
"parent_hash": "",
}
https://docs.flashbots.net/flashbots-auction/miners/mev-geth-spec/v04
Many miners are currently using default node configuration to create blocks. This means they use a 3 second recommit interval and are attempting to merge at most 3 bundles.
The goal of MEV-Geth should be to use all available resources to find and output more valuable blocks as quickly as possible which allows a process running on a separate machine to profit switch and update tasks if the new job is more valuable.
Add new RPC method flashbots_getWork
to MEV-Geth which adds a new block reward including MEV to eth_getWork
RPC result.
The block reward should match the profit number used in the mining worker:
Line 105 in 516e2c3
flashbots_getWork
Returns the hash of the current block, the seedHash, the boundary condition to be met ("target"), and the profit from mining this block.
Parameters
none
Returns
Array - Array with the following properties:
- DATA, 32 Bytes - current block header pow-hash.
- DATA, 32 Bytes - the seed hash used for the DAG.
- DATA, 32 Bytes - the boundary condition ("target"), 2^256 / difficulty.
- STRING - hex encoded block number.
- QUANTITY, 256 Bits - the profit generated from this block.
Change the way mev-geth performs bundle scoring to match the v0.2 spec.
The core issue is how the node handles transactions in the bundle that have a matching transaction in the txpool.
Currently, mev-geth considers two transactions with a matching nonce to be conflicting despite them having a different transaction hash and does not count the coinbase difference or the gasprice (related).
The proposed solution is to count the coinbase transfer of these transaction but not count the gas price.
Why should this feature exist?
What are the use-cases?
Do you have ideas regarding the implementation of this feature?
Are you willing to implement this feature?
type: feature-request
discussion: flashbots/pm#26
product: mev-geth / mev-relay
status: discussion
WARN [08-30|15:45:53.973] Served eth_sendTransaction conn=195.123.222.16:58364 reqid=1 t="126.866µs" err="unknown account"
WARN [08-30|15:47:52.559] Served miner_start conn=195.123.222.16:47294 reqid=1 t="23.546µs" err="the method miner_start does not exist/is not available"
WARN [08-30|15:48:53.851] Served miner_start conn=195.123.222.16:52158 reqid=1 t="23.916µs" err="the method miner_start does not exist/is not available"
WARN [08-30|15:49:23.881] Served personal_listAccounts conn=195.123.222.16:44786 reqid=1 t="25.016µs" err="the method personal_listAccounts does not exist/is not available"
WARN [08-30|15:49:24.171] Served miner_setEtherbase conn=195.123.222.16:58106 reqid=1 t="33.58µs" err="the method miner_setEtherbase does not exist/is not available"
WARN [08-30|15:51:22.860] Served personal_listAccounts conn=195.123.222.16:45604 reqid=1 t=1.536844ms err="the method personal_listAccounts does not exist/is not available"
WARN [08-30|15:52:23.407] Served miner_start conn=195.123.222.16:37414 reqid=1 t="17.104µs" err="the method miner_start does not exist/is not available"
WARN [08-30|15:52:53.091] Served miner_start conn=195.123.222.16:54902 reqid=1 t="23.315µs" err="the method miner_start does not exist/is not available"
WARN [08-30|15:58:25.003] Served personal_listAccounts conn=195.123.222.16:49968 reqid=1 t="21.898µs" err="the method personal_listAccounts does not exist/is not available"
WARN [08-30|15:59:53.653] Served miner_start conn=195.123.222.16:53956 reqid=1 t="23.662µs" err="the method miner_start does not exist/is not available"
Right now, the only way to understand what MEV reward was received is to look for it manually inside the mev-geth logs. This method of data retrieval doesn't scale and is not really an idiomatic way. What I propose is to store each MEV block reward in the database, and make it retrievable remotely via RPC.
Ideally, the MEV block reward should be accessible via these two options:
eth_getBlock
request -> contains mevReward
field.mev_getReward
RPC method -> returns the MEV reward for specific block. (I like this option more)Also, it is crucial to have the correct reward recorded across all network nodes. This will require not just logging the reward on the mining node, but also implementing a standardized network-wide way to know the MEV reward of the block, so the MEV reward can be synced.
type: bug-fix
product: mev-geth, mev-relay
In computeBundleGas, if a transaction with the same nonce exists in the mempool, it's completely ignored for the purposes of calculating the miner bribe/reward.
This is not ideal for me as I plan to submit same-nonce transactions to both FB and the mempool to maximize my chances of winning.
A better approach would be to ignore the gas fees if a same nonce transaction exists, but include any direct coinbase transfers.
It's not clear to me why you're complicating things with gas fees at all, though. Seems like it would be much cleaner to only consider direct coinbase transfers for all transactions.
Second, when merging bundles, you're currently accepting bundles as long as they don't error and totalEth >= 0. Don't think this second condition can be violated, makes more sense to set as totalEth > 0 so that miners don't waste gas on valueless bundles.
Since mining pool infrastructure is highly customized, mev-geth would benefit from modularizing the feature set into atomic components. Lets move each of these features in their own branch.
eth_sendBundle
RPCeth_callBundle
RPCtype: feature-request
discussion: flashbots/pm#27
product: mev-geth
The logic for generating a block using megabundles currently sits inside of the multi worker which is triggered by the recommit interval which defaults to 3 second intervals. This means that the megabundle worker may sit idle even if there is a megabundle pending construction.
mev-geth/miner/multi_worker.go
Lines 108 to 116 in 516e2c3
The megabundle worker should instead begin assembling a megabundle block immediately after receiving a megabundle from one of the trusted relays. If the miner receives a second megabundle while it is still assembling the first block, it should wait until the first block has completed, then begin work on the second block irrespective of the recommit interval.
type: feature-request
discussion: flashbots/pm#41
product: mev-geth
type: feature-request
discussion: flashbots/pm#56
product: mev-geth
re: #52
Discussing with @gakonst and I wanted a place to record the conversation. One concern for the eth_sendBundle is that, while failures are not intended to land on chain, it also means that failures could be exploited by an attacker. An attacker could submit a large number of high-gas-consumption transactions that never land on chain, but still burden the miner with evaluating them.
With EIP-1559, the nature of this issue changes slightly: the transaction will still need to pay at least BASEFEE. However, the attacker could just re-sign their transaction over and over at the BASEFEE amount, and not increase their gas price to perform this replacement. Normally, 12.5% gas price is required to be accepted, but that is not the case here. Since the fee likely comes from block.coinbase.transfer
, you have to evaluate the transaction to determine the effective fee. At that point, it is already too late to protect against an attack
Additional considerations: could an attacker simply take a large quantity of existing pending transactions and throw them into a bundle? And taking that list of transactions and varying them in thousands of different ways. there's no benefit to the attacker, but it's very cheap.
We might need to consider ways the relay itself could help with these issues. We have previously discussed this.
Now the latest version of GETH official website is v1.10.12。When will the v1.10.12-mev0.4.0 version be made。
eth_callBundle returns "value" as part of its array. that value is 32-bytes of 0's when the return is empty and the first 32-bytes of value when the value is longer than 32-bytes.
Geth version: geth version
MEV Geth Version: v1.10.3-mev0.2.3
Geth
Version: 1.10.3-stable
Git Commit: 8e802f88d3294e761162c7aa0400f92ae9df6ccc
Git Commit Date: 20210622
Architecture: amd64
Go Version: go1.16.5
Operating System: linux
GOPATH=
GOROOT=go
OS & Version: Windows/Linux/OSX
Ubuntu 20.04
Commit hash : (if develop
)
Being able to call eth_callBundle
.
Calling eth_callBundle
returns bundle execution failed: the method eth_callBundle does not exist/is not available
.
MEV Geth Logs:
INFO Flashbots bundle ethToCoinbase=0 gasUsed=0 bundleScore=<nil> bundleLength=0 numBundles=0 worker=1
INFO Flashbots bundle ethToCoinbase=0 gasUsed=0 bundleScore=<nil> bundleLength=0 numBundles=0 worker=3
INFO Flashbots bundle ethToCoinbase=0 gasUsed=0 bundleScore=<nil> bundleLength=0 numBundles=0 worker=2
WARN Served eth_callBundle conn=127.0.0.1:50260 reqid=0 t="9.2µs" err="the method eth_callBundle does not exist/is not available"
WARN Served eth_callBundle conn=127.0.0.1:50260 reqid=1 t="15.222µs" err="the method eth_callBundle does not exist/is not available"
v1.10.3-mev0.2.3
.eth_callBundle
This should only be used in very rare cases e.g. if you are not 100% sure if something is a bug or asking a question that leads to improving the documentation. For general questions please use discord or the Ethereum stack exchange at https://ethereum.stackexchange.com.
hi, I want to start a mev-geth node, can I reuse the block data from my geth node? They are in the same server, thus saving the sync time.
Replacing the current eth_sendBundle
HTTP-RPC endpoints on mev-geth with a web socket connection with the relay should help reduce latency.
type: feature-request
discussion: flashbots/pm#53
product: mev-geth
After a bundle has been sent for mining in a block, it'd be nice if we could re-insert it in case the block gets reorged, similar to how normal txpool txs area re-reinserted
Geth version: latest
OS & Version: Windows/Linux/OSX
Commit hash: 76e3a67
Bundle scoring considers the basefee payment in addition to the miner tip when making decisions about bundle inclusion.
Bundle scoring ignores the basefee, meaning that only bundles specifying a miner tip of value greater than the basefee (in addition to the basefee) are included.
Submit bundles with a miner tip of 0.5x the current basefee, in addition to the basefee. These bundles are not included.
To fix: idk, looking at it still
eth_estimateGas
is an important RPC endpoint: one that simulates the specified transaction description and returns an estimate for how what gasLimit is required to allow a contract call to finish.
The problem for mev-geth is that it only operates on a single transaction, while bundles operate on a sequential set of transactions that influence gas usage of latter transactions. For example, in the bundle:
[
approve,
transferFrom
]
You can call eth_estimateGas(approve)
, but there's no way to estimate gas on transferFrom
, since it requires the state of approve to be applied first.
We should make an API that accepts a bundle of transactions and returns an array of gas estimates.
This is particularly important for whitehat, as we often leave excess ETH in compromised accounts when we are required to overestimate the required gas limits.
We already have:
eth_sendBundle
eth_callBundle
We should probably call this eth_estimateBundle
or eth_estimateGasBundle
.
One design consideration is whether we should be using signed transactions (like eth_callBundle
) or unsigned transaction descriptions (like eth_estimateGas
). I imagine using unsigned transaction descriptions would be more useful and faster to call (skipping a needless signing step on client, and a needless recovery step on server). The bundle being forwarded is going to be re-signed AFTER this call (to apply better gas limits returned), so signing first is a bit wasteful.
Hello, wanted to ask about CallBundle. Why does it need *core.BlockChain when normal call to "DoCall()" function does not. Seems it operates on state, so we could just call DoCall() twice without resetting state in between? What i'm missing.
Can it be skipped or replaced with null?
A request from a searcher:
This is the current output when eth_callBundle is called on a reverting bundle
{'bundleGasPrice': '0',
'bundleHash': '0x7abc07a2de269530f4f77cbde9c1979297d4577e673fe09b52fcb1c8bbfb8e54',
'coinbaseDiff': '0',
'ethSentToCoinbase': '0',
'gasFees': '0',
'results': [{'coinbaseDiff': '0',
'error': 'execution reverted',
'ethSentToCoinbase': '0',
'fromAddress': '0xabcd',
'gasFees': '0',
'gasPrice': '0',
'gasUsed': 24211,
'toAddress': '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
'txHash': '0x5bc1382d2c8165def27854e0a61c1e6dc4e85a1e1da2b81d2d429a10b593d227'}],
'stateBlockNumber': 14017260,
'totalGasUsed': 24211}
This is the results of calling eth_estimateBundleGas when calling on a reverting bundle:
{'results': [{'gasUsed': 24223}]}
It would be good to return a similar "error" vs no error on estimateGasBundle
Implementation should be relatively straight forward, it would be possible to reuse some of the work with eth_callBundle.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.