fix(fab3): GetTransactionReceipt leaks EVM logs from MVCC-invalidated transactions#64
fix(fab3): GetTransactionReceipt leaks EVM logs from MVCC-invalidated transactions#64Aman-Cool wants to merge 1 commit intohyperledger:mainfrom
Conversation
…tTransactionReceipt Signed-off-by: Aman-Cool <aman017102007@gmail.com>
c3c1a54 to
548571c
Compare
|
Hey @mbrandenburger @pasquale95, just wanted to flag a few things to make your review easier. The Happy to answer any questions or make changes if something looks off. Thanks for taking a look! |
|
@Aman-Cool Thank you for creating this PR! I believe this PR belongs in a different repository (i.e., https://github.com/hyperledger-archives/fabric-chaincode-evm). Closing this for now. |
Bug:
GetTransactionReceiptreturns logs for MVCC-invalidated transactionsWhat's wrong
Found this while hammering the gateway with concurrent transactions. Two clients writing to the same contract key → one gets MVCC-conflicted by the committer -> calling
eth_getTransactionReceipton the dead transaction returns"status": "0x0"(correct) with a non-emptylogsarray (very wrong).Those logs came from the endorser's simulation, state changes that the committer threw away. Nothing committed, but the receipt says otherwise.
What made it click was checking
eth_getLogsfor the same block. No logs. SoGetTransactionReceiptandGetLogsare looking at the exact same bytes in the same block and returning contradictory answers.GetLogsalready had the validity guard:GetTransactionReceiptsets status correctly from the same flag, then completely ignores it when extracting logs. Classic "fixed half the problem" situation.There's also a secondary issue: failed contract deployments were still getting a
contractAddressin the receipt. No contract exists at that address, the deployment was invalidated, but we were advertising it anyway.Why it's bad
EIP-658 is explicit:
status = 0x0means empty logs. Every Ethereum client library, indexer, and dApp is built around this. An ERC-20Transferevent in a failed receipt will get processed as a real transfer by anything listening. Under low load you'd never see this, MVCC conflicts only show up under real concurrency, which is exactly when you need your receipts to be correct.The fix
Gate log extraction and
contractAddressontxnValidValue == 1. Two extraifblocks. Valid transactions behave identically to before. Invalid transactions get empty logs and no contract address, matching whatGetLogsalready returns and what EIP-658 requires.Tests
Two new specs in
ethservice_test.go, one for an MVCC-invalidated call transaction (assertsstatus=0x0,logs=nil), one for an MVCC-invalidated deployment (assertscontractAddress=""). All 83 existing specs still pass.