Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added estimateGasBundle method #102

Merged
merged 1 commit into from
Dec 20, 2021

Conversation

libevm
Copy link

@libevm libevm commented Dec 20, 2021

#100

Adds method eth_estimateGasBundle that accepts similar params to eth_callBundle, but doesn't require the bundle to be signed, e.g.:

provider.send('eth_estimateGasBundle', [
        {
            txs: [{
                from: signerAddress,
                to: contractAddress,
                data: '0x....'
            },{
               from: userAddress,
               to: contractAddress,
               data: '0x.....'
           }],
            stateBlockNumber: '0x' + blockNumber.toString(16),
            blockNumber: '0x' + blockNumber.toString(16),
        }
    ])

Returns the result in the format:

response {
  results: [
    { gasUsed: 46174 },
    { gasUsed: 57516 },
  ]
}

Manually tested with the following script, bit unsure where to add the tests for mev-geth so some guidance would be appreciated:

const { ethers, providers } = require("ethers");
const { getContractAddress } = require('@ethersproject/address');
const { parseUnits } = require("ethers/lib/utils");

const abi = `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"drip","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"},{"name":"data","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"newOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferAnyERC20Token","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenOwner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Approval","type":"event"}]`
const bytecode = '0x608060405234801561001057600080fd5b5060008054600160a060020a031916331790556040805180820190915260068082527f5745454e55530000000000000000000000000000000000000000000000000000602090920191825261006791600291610134565b5060408051808201909152600b8082527f5765656e757320f09f92aa00000000000000000000000000000000000000000060209092019182526100ac91600391610134565b5060048054601260ff19909116179081905560ff16600a0a620f4240810260058190556103e890910260065560008054600160a060020a0390811682526007602090815260408084208590558354815195865290519216937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a36101cf565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785556101a2565b828001600101855582156101a2579182015b828111156101a2578251825591602001919060010190610187565b506101ae9291506101b2565b5090565b6101cc91905b808211156101ae57600081556001016101b8565b90565b610cc6806101de6000396000f3fe608060405260043610610110576000357c01000000000000000000000000000000000000000000000000000000009004806395d89b41116100a7578063d4ee1d9011610076578063d4ee1d9014610466578063dc39d06d1461047b578063dd62ed3e146104b4578063f2fde38b146104ef57610110565b806395d89b411461033b5780639f678cca14610350578063a9059cbb14610365578063cae9ca511461039e57610110565b8063313ce567116100e3578063313ce5671461029757806370a08231146102c257806379ba5097146102f55780638da5cb5b1461030a57610110565b806306fdde0314610156578063095ea7b3146101e057806318160ddd1461022d57806323b872dd14610254575b61011c33600654610522565b5060003411156101545760405133903480156108fc02916000818181858888f19350505050158015610152573d6000803e3d6000fd5b505b005b34801561016257600080fd5b5061016b6105c5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101a557818101518382015260200161018d565b50505050905090810190601f1680156101d25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101ec57600080fd5b506102196004803603604081101561020357600080fd5b50600160a060020a038135169060200135610653565b604080519115158252519081900360200190f35b34801561023957600080fd5b506102426106b9565b60408051918252519081900360200190f35b34801561026057600080fd5b506102196004803603606081101561027757600080fd5b50600160a060020a038135811691602081013590911690604001356106fc565b3480156102a357600080fd5b506102ac610807565b6040805160ff9092168252519081900360200190f35b3480156102ce57600080fd5b50610242600480360360208110156102e557600080fd5b5035600160a060020a0316610810565b34801561030157600080fd5b5061015461082b565b34801561031657600080fd5b5061031f6108b3565b60408051600160a060020a039092168252519081900360200190f35b34801561034757600080fd5b5061016b6108c2565b34801561035c57600080fd5b5061015461091a565b34801561037157600080fd5b506102196004803603604081101561038857600080fd5b50600160a060020a038135169060200135610929565b3480156103aa57600080fd5b50610219600480360360608110156103c157600080fd5b600160a060020a03823516916020810135918101906060810160408201356401000000008111156103f157600080fd5b82018360208201111561040357600080fd5b8035906020019184600183028401116401000000008311171561042557600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506109d9945050505050565b34801561047257600080fd5b5061031f610b3a565b34801561048757600080fd5b506102196004803603604081101561049e57600080fd5b50600160a060020a038135169060200135610b49565b3480156104c057600080fd5b50610242600480360360408110156104d757600080fd5b50600160a060020a0381358116916020013516610c04565b3480156104fb57600080fd5b506101546004803603602081101561051257600080fd5b5035600160a060020a0316610c2f565b600160a060020a03821660009081526007602052604081205461054b908363ffffffff610c7516565b600160a060020a038416600090815260076020526040902055600554610577908363ffffffff610c7516565b600555604080518381529051600160a060020a038516916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35060015b92915050565b6003805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561064b5780601f106106205761010080835404028352916020019161064b565b820191906000526020600020905b81548152906001019060200180831161062e57829003601f168201915b505050505081565b336000818152600860209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b600080805260076020527f6d5257204ebe7d88fd91ae87941cb2dd9d8062b64ae5a2bd2d28ec40b9fbf6df546005546106f79163ffffffff610c8516565b905090565b600160a060020a038316600090815260076020526040812054610725908363ffffffff610c8516565b600160a060020a0385166000908152600760209081526040808320939093556008815282822033835290522054610762908363ffffffff610c8516565b600160a060020a0380861660009081526008602090815260408083203384528252808320949094559186168152600790915220546107a6908363ffffffff610c7516565b600160a060020a0380851660008181526007602090815260409182902094909455805186815290519193928816927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060019392505050565b60045460ff1681565b600160a060020a031660009081526007602052604090205490565b600154600160a060020a0316331461084257600080fd5b60015460008054604051600160a060020a0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600054600160a060020a031681565b6002805460408051602060018416156101000260001901909316849004601f8101849004840282018401909252818152929183018282801561064b5780601f106106205761010080835404028352916020019161064b565b61092633600654610522565b50565b33600090815260076020526040812054610949908363ffffffff610c8516565b3360009081526007602052604080822092909255600160a060020a0385168152205461097b908363ffffffff610c7516565b600160a060020a0384166000818152600760209081526040918290209390935580518581529051919233927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a350600192915050565b336000818152600860209081526040808320600160a060020a038816808552908352818420879055815187815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a36040517f8f4ffcb10000000000000000000000000000000000000000000000000000000081523360048201818152602483018690523060448401819052608060648501908152865160848601528651600160a060020a038a1695638f4ffcb195948a94938a939192909160a490910190602085019080838360005b83811015610ac9578181015183820152602001610ab1565b50505050905090810190601f168015610af65780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015610b1857600080fd5b505af1158015610b2c573d6000803e3d6000fd5b506001979650505050505050565b600154600160a060020a031681565b60008054600160a060020a03163314610b6157600080fd5b60008054604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a0392831660048201526024810186905290519186169263a9059cbb926044808401936020939083900390910190829087803b158015610bd157600080fd5b505af1158015610be5573d6000803e3d6000fd5b505050506040513d6020811015610bfb57600080fd5b50519392505050565b600160a060020a03918216600090815260086020908152604080832093909416825291909152205490565b600054600160a060020a03163314610c4657600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b818101828110156105bf57600080fd5b600082821115610c9457600080fd5b5090039056fea165627a7a7230582039806f4d6c5cf7caf5b6167c964e7be3f312232c72a5e710eb2ad72d191720f50029'

const provider = new ethers.providers.JsonRpcProvider()

const main = async () => {
    const signer = await provider.getSigner(0)
    const signerAddress = await signer.getAddress()
    const nonce = await provider.getTransactionCount(signerAddress)

    const contractAddress = await getContractAddress({
        from: signerAddress,
        nonce
    })

    const erc20 = new ethers.Contract(contractAddress, abi, signer)

    const tx = await signer.sendTransaction({
        data: bytecode,
        nonce
    })
    await tx.wait()

    const user = new ethers.Wallet.createRandom().connect(provider)
    const userAddress = await user.getAddress()

    await erc20.drip()

    await signer.sendTransaction({
        to: userAddress,
        value: parseUnits('10')
    }).then(x => x.wait())

    const blockNumber = await provider.getBlockNumber()

    const { data } = await erc20.populateTransaction.approve(userAddress, parseUnits('1'))
    const dump2 = await erc20.populateTransaction.transferFrom(signerAddress, userAddress, parseUnits('0.1'))

    const callTransferFrom = {
        from: userAddress,
        to: contractAddress,
        data: dump2.data
    }

    console.log('eth_estimateGasBundle')
    const resp = await provider.send('eth_estimateGasBundle', [
        {
            txs: [{
                from: signerAddress,
                to: contractAddress,
                data
            },
                callTransferFrom,
                callTransferFrom,
                callTransferFrom
            ],
            stateBlockNumber: '0x' + blockNumber.toString(16),
            blockNumber: '0x' + blockNumber.toString(16),
        }
    ])
    console.log('response', resp)

    await erc20.approve(userAddress, parseUnits('1')).then(x => x.wait()).then(x => console.log(x.gasUsed.toString()))
    await erc20.connect(user).transferFrom(signerAddress, userAddress, parseUnits('0.1')).then(x => x.wait()).then(x => console.log(x.gasUsed.toString()))
    await erc20.connect(user).transferFrom(signerAddress, userAddress, parseUnits('0.1')).then(x => x.wait()).then(x => console.log(x.gasUsed.toString()))
    await erc20.connect(user).transferFrom(signerAddress, userAddress, parseUnits('0.1')).then(x => x.wait()).then(x => console.log(x.gasUsed.toString()))
}

main()

Response:

$ node test_estimateBundle.js

eth_estimateGasBundle
response {
  results: [
    { gasUsed: 46174 },
    { gasUsed: 57516 },
    { gasUsed: 40416 },
    { gasUsed: 40416 }
  ]
}
46174
57516
40416
40416

Please be patient, something something etc. First time writing Go and don't really know the correct conventions.

Copy link

@tarcisiozf tarcisiozf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome add, just some small (opinionated) details to discuss

internal/ethapi/api.go Show resolved Hide resolved
internal/ethapi/api.go Show resolved Hide resolved
@jparyani jparyani self-requested a review December 20, 2021 22:50
@jparyani jparyani merged commit 72a9c78 into flashbots:mev-callbundle Dec 20, 2021
@jparyani
Copy link

This is great, thanks!

Fixes #100

@jparyani
Copy link

@libevm sadly there's no good place for end to end tests atm, especially for the mev-callbundle branch. Right now, end to end tests live in https://github.com/flashbots/mev-geth-demo and you can look at

- name: Check out the e2e code repo
to see how they're run.

I'm fine leaving the testing outside the scope of this PR, but feel free to add it if you have the time.

Ruteri pushed a commit that referenced this pull request Feb 18, 2022
* fix issue with geth not shutting down (#97)
* Add eth_callBundle rpc method (#14)
* flashbots: add eth_estimateGasBundle (#102)
* feat(ethash): flashbots_getWork RPC with profit (#106)
* Calculate megabundle as soon as it's received (#112)
* Add v0.5 specification link (#118)
Ruteri added a commit that referenced this pull request Feb 21, 2022
* fix issue with geth not shutting down (#97)
* Add eth_callBundle rpc method (#14)
* flashbots: add eth_estimateGasBundle (#102)
* feat(ethash): flashbots_getWork RPC with profit (#106)
* Calculate megabundle as soon as it's received (#112)
* Add v0.5 specification link (#118)
Ruteri added a commit that referenced this pull request Feb 21, 2022
* fix issue with geth not shutting down (#97)
* Add eth_callBundle rpc method (#14)
* flashbots: add eth_estimateGasBundle (#102)
* feat(ethash): flashbots_getWork RPC with profit (#106)
* Calculate megabundle as soon as it's received (#112)
* Add v0.5 specification link (#118)
Ruteri added a commit that referenced this pull request Apr 4, 2022
* fix issue with geth not shutting down (#97)
* Add eth_callBundle rpc method (#14)
* flashbots: add eth_estimateGasBundle (#102)
* feat(ethash): flashbots_getWork RPC with profit (#106)
* Calculate megabundle as soon as it's received (#112)
* Add v0.5 specification link (#118)
Ruteri added a commit that referenced this pull request Jun 7, 2022
* fix issue with geth not shutting down (#97)
* Add eth_callBundle rpc method (#14)
* flashbots: add eth_estimateGasBundle (#102)
* feat(ethash): flashbots_getWork RPC with profit (#106)
* Calculate megabundle as soon as it's received (#112)
* Add v0.5 specification link (#118)
Ruteri added a commit that referenced this pull request Jun 15, 2022
* fix issue with geth not shutting down (#97)
* Add eth_callBundle rpc method (#14)
* flashbots: add eth_estimateGasBundle (#102)
* feat(ethash): flashbots_getWork RPC with profit (#106)
* Calculate megabundle as soon as it's received (#112)
* Add v0.5 specification link (#118)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants