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

transaction gasPrice does not equal baseFeePerGas + maxPriorityFeePerGas #4094

Closed
brendene opened this issue Dec 28, 2022 · 3 comments · Fixed by #4112
Closed

transaction gasPrice does not equal baseFeePerGas + maxPriorityFeePerGas #4094

brendene opened this issue Dec 28, 2022 · 3 comments · Fixed by #4112

Comments

@brendene
Copy link

Running on the latest version of ganache, ganache v7.7.2 (@ganache/cli: 0.8.1, @ganache/core: 0.8.1)

This could be my misunderstanding, but it appears that gasPrice != min(maxPriorityFeePerGas + baseFeePerGas, maxFeePerGas) when multiple transactions are mined in the same block.

command: ganache-cli --chain.vmErrorsOnRPCResponse true --miner.blockTime 3600 --chain.chainId 1 -v --miner.timestampIncrement 12 --wallet.deterministic

repro:

accounts = w3.eth.accounts                                                                                                                                                                                                                                         
for i in range(1,4):                                                                                                                                                                                                                                               
    txnHashes.append(w3.eth.send_transaction({'from'                 : accounts[0],                                                                                                                                                                                
                                              'to'                   : accounts[1],                                                                                                                                                                                
                                              'value'                : w3.toWei('1', 'ether'),                                                                                                                                                                     
                                              'gas'                  : 21000,                                                                                                                                                                                      
                                              'maxPriorityFeePerGas' : w3.toWei(i , 'gwei'),                                                                                                                                                                       
                                              'maxFeePerGas'         : w3.toWei(30 , 'gwei')}))                                                                                                                                                                    
w3.provider.make_request('evm_mine', [])                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                   
for txnHash in txnHashes:                                                                                                                                                                                                                                          
    txn = w3.eth.get_transaction(txnHash)                                                                                                                                                                                                                          
    block = w3.eth.get_block(txn.blockNumber)                                                                                                                                                                                                                      
    print(f'{block.baseFeePerGas=} {txn.maxPriorityFeePerGas=} {txn.maxFeePerGas=} {txn.gasPrice=}')

Output:

block.baseFeePerGas=875000000 txn.maxPriorityFeePerGas=1000000000 txn.maxFeePerGas=30000000000 txn.gasPrice=1875000000
block.baseFeePerGas=875000000 txn.maxPriorityFeePerGas=2000000000 txn.maxFeePerGas=30000000000 txn.gasPrice=3000000000
block.baseFeePerGas=875000000 txn.maxPriorityFeePerGas=3000000000 txn.maxFeePerGas=30000000000 txn.gasPrice=4000000000

For the 2nd and 3rd transactions I expected the gasPrice to be 2875000000 and 3875000000 respectively.
When the transaction are mined individually, the invariant holds.

The example uses the web3.py library but the raw json is:

{'from': '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1', 'to': '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0', 'value': '0xde0b6b3a7640000', 'gas': '0x5208', 'maxPriorityFeePerGas': '0x3b9aca00', 'maxFeePerGas': '0x6fc23ac00'}
{'from': '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1', 'to': '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0', 'value': '0xde0b6b3a7640000', 'gas': '0x5208', 'maxPriorityFeePerGas': '0x77359400', 'maxFeePerGas': '0x6fc23ac00'}
{'from': '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1', 'to': '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0', 'value': '0xde0b6b3a7640000', 'gas': '0x5208', 'maxPriorityFeePerGas': '0xb2d05e00', 'maxFeePerGas': '0x6fc23ac00'}

And the raw responses are:

{'id': 12, 'jsonrpc': '2.0', 'result': {'type': '0x2', 'hash': '0x79f205173e9ff6878320b5a6167a4a07d3c65669fdf995293c88cb7aa79facf7', 'chainId': '0x1', 'nonce': '0x0', 'bloc
kHash': '0xcd96e8f2140ddce2e1aa86129fcd30d9f0ee33e6870af3a9190e589326568c19', 'blockNumber': '0x1', 'transactionIndex': '0x0', 'from': '0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1', 'to': '0xffcf8fdee72ac11b5c542428b35eef5769c409f0', 'value': '0xde0b6b3a764000
0', 'maxPriorityFeePerGas': '0x3b9aca00', 'maxFeePerGas': '0x6fc23ac00', 'gasPrice': '0x6fc23ac0', 'gas': '0x5208', 'input': '0x', 'accessList': [], 'v': '0x1', 'r': '0xf53bbc8b944d320b2d5917ac8b2bf1bd3e0e6d14c39e740c532198c7a4cb5f88', 's': '0x3fd99bceb278e1b
97ac98a9c7a67f6dcf9f10ae85fd4ffa255a8a1fce72bde2f'}}

{'id': 14, 'jsonrpc': '2.0', 'result': {'type': '0x2', 'hash': '0xf8c20f31c957d9a7418e71161b407b08bca2dd44e921439af3c8bd7c1157c8c2', 'chainId': '0x1', 'nonce': '0x1', 'bloc
kHash': '0xcd96e8f2140ddce2e1aa86129fcd30d9f0ee33e6870af3a9190e589326568c19', 'blockNumber': '0x1', 'transactionIndex': '0x1', 'from': '0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1', 'to': '0xffcf8fdee72ac11b5c542428b35eef5769c409f0', 'value': '0xde0b6b3a764000
0', 'maxPriorityFeePerGas': '0x77359400', 'maxFeePerGas': '0x6fc23ac00', 'gasPrice': '0xb2d05e00', 'gas': '0x5208', 'input': '0x', 'accessList': [], 'v': '0x0', 'r': '0x6d2e48588b35d7e1ce71db5eb9a7f2c94e8f6e061eca15242a2409c39440cee', 's': '0x158d1ec71e465519
d076bf8e592b3a455e5d0499a8ee229aa3da7a416b9991f7'}}

{'id': 16, 'jsonrpc': '2.0', 'result': {'type': '0x2', 'hash': '0xf1fbd2ace4bc613672fdec399afc301081c404451b84324ee880f79c88a84b31', 'chainId': '0x1', 'nonce': '0x2', 'bloc
kHash': '0xcd96e8f2140ddce2e1aa86129fcd30d9f0ee33e6870af3a9190e589326568c19', 'blockNumber': '0x1', 'transactionIndex': '0x2', 'from': '0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1', 'to': '0xffcf8fdee72ac11b5c542428b35eef5769c409f0', 'value': '0xde0b6b3a764000
0', 'maxPriorityFeePerGas': '0xb2d05e00', 'maxFeePerGas': '0x6fc23ac00', 'gasPrice': '0xee6b2800', 'gas': '0x5208', 'input': '0x', 'accessList': [], 'v': '0x1', 'r': '0x4e3fc279f2dd436837461fd641d7de0cb0f5f562a3db0243101dd8372b43048c', 's': '0x3984d95009ac9bd
1ab9ceb0dc2a6614169d31f15111048c0f9f759fb8329fe1c'}}
@davidmurdoch
Copy link
Member

Do you know if this is only happening on the post merge (7.7.0+) releases?

@brendene
Copy link
Author

Do you know if this is only happening on the post merge (7.7.0+) releases?

I see this happening in pre merge releases as well (ex. 7.6.0)

@MicaiahReid
Copy link
Contributor

MicaiahReid commented Jan 4, 2023

I've looked into this a bit, and it seems that we have a discrepancy for the gas price between the result of eth_getTransactionByHash and eth_getTransactionReceipt. The transaction's gasPrice field differs from the receipt's effectiveGasPrice field. The receipt's effectiveGasPrice is the correct value, and is what is actually used at the VM level to update account balances, so that's good.

However, we're returning the wrong gasPrice when you fetch the transaction via eth_getTransactionByHash. This is happening because when we save the transaction to the chain, we don't update the transaction's effectiveGasPrice field based off of the baseFeePerGas of the block that the transaction was mined onto. Instead, when you fetched the receipt we would calculate the effectiveGasPrice just to correct what we return to the user. This is a bug.

I have a PR incoming that removes the on the fly calculation of the effectiveGasPrice on the receipt, and instead updates that actual effectiveGasPrice of the transaction before saving to the chain.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants