feat[contracts]: Use standard RLP transaction format#566
feat[contracts]: Use standard RLP transaction format#566smartcontracts merged 9 commits intov0.3.0-rlpfrom
Conversation
|
b4591e0 to
a620463
Compare
fa398cd to
399c0e2
Compare
| @@ -747,7 +745,7 @@ func (s *SyncService) ApplyTransaction(tx *types.Transaction) error { | |||
| } | |||
|
|
|||
| // Set the raw transaction data in the meta | |||
There was a problem hiding this comment.
Technically the better way to do this is use the raw RLP sent via RPC so that it doesn't need to be reserialized here. The txmeta is created in eth_sendRawTransaction handler and rawTransaction can be set there
There was a problem hiding this comment.
How would you do this?
There was a problem hiding this comment.
This is the line that needs updating:
optimism/l2geth/internal/ethapi/api.go
Line 1738 in eef1df4
The RLP encoded tx is in scope as a hexutil.Bytes
There was a problem hiding this comment.
When the RollupClient fetches a tx, it sets the rawTransaction here:
optimism/l2geth/rollup/client.go
Line 329 in eef1df4
|
How do we handle the reverts in the RLP decoding? |
Reverts in the RLP decoding will cause the whole call frame to revert. So wouldn't get past SequencerEntrypoint. |
karlfloersch
left a comment
There was a problem hiding this comment.
Awesome! I remember reviewing this a few weeks back & I didn't find anything super note worthy this time. I left a little todo for myself which I'll look into in a bit but just wanted to say that this looks great so far!
Definitely want more eyes but this really simplifies our logic which is great
| function ovmCHAINID() | ||
| internal | ||
| returns ( | ||
| uint256 |
There was a problem hiding this comment.
@smartcontracts - Did you mention something about using a smaller uint for the chainID? Or was that with regard to the nonce that Proto and others have brought up?
I'm not familiar with the DTL RLP codepath but maybe submitting a crazy high v would cause unexpected behavior / cause us to decode a transaction incorrectly. Haven't confirmed this but was wondering if it was on your radar
There was a problem hiding this comment.
Yes, I was planning to make that change in another PR following this one. We'll match the limits up with whatever geth is using. Just didn't want to add that change here b/c too much for a single PR.
| }) | ||
| const call: any = Mock__OVM_ExecutionManager.smocked.ovmCREATEEOA.calls[0] | ||
| const eoaAddress = ethers.utils.recoverAddress(call._messageHash, { | ||
| v: call._v + 27, |
There was a problem hiding this comment.
todo(karl): look into why this v + 27 works when the chain ID of the DEFAULT_EIP155_TX is 420
There was a problem hiding this comment.
What do you mean by this?
packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol
Show resolved
Hide resolved
ben-chain
left a comment
There was a problem hiding this comment.
This is looking great, woot woot! Seems like Karl has a todo and I had a few small comments, but feels close.
packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol
Outdated
Show resolved
Hide resolved
packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol
Outdated
Show resolved
Hide resolved
| _r, | ||
| _s | ||
| ) == address(this), | ||
| transaction.sender() == address(this), |
There was a problem hiding this comment.
Notably the way this code path is currently done is that we re-encode the raw RLP within sender() to do recovery. We could instead recover the sig based on hash(msg.data[4:end]).
A quick aside: can you briefly talk about the reasoning for making the OVM_ECDSAContractAccount accept encoded bytes now as opposed to just a single Lib_EIP155Tx.EIP155Tx argument? Doesn't seem like it makes l2geth any different, and could add redundant encoding/decoding. Just curious to hear it laid out; makes total sense in the OVM_SequencerEntryPoint.
There was a problem hiding this comment.
Hmmm yeah interesting, I hadn't thought of passing the EIP155Tx directly. I think that's a great idea. Will do this!
There was a problem hiding this comment.
Ok looking at this now, this introduces enough of a diff that we may want to leave it for another PR + treat it as an optimization if this method is too expensive.
There was a problem hiding this comment.
Yeah, it's a bit of a tradeoff. Ultimately the most gas-efficient version could just require extcodehash(msg.sender) == SEQUENCER_ENTRYPOINT_CODEHASH and trust that code path explicitly instead of redoing the work. Down to leave for future work.
packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol
Outdated
Show resolved
Hide resolved
packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol
Outdated
Show resolved
Hide resolved
packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol
Show resolved
Hide resolved
...s/contracts/contracts/optimistic-ethereum/libraries/wrappers/Lib_ExecutionManagerWrapper.sol
Show resolved
Hide resolved
…s/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party>
…optimism into feat/rlp-transactions
* feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party>
* feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party>
* feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party>
* feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party>
* feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party>
…619) * feat[contracts]: Use standard RLP transaction format (#566) * feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party> * feat[contracts]: Add value transfer to contract account * fix[contracts]: Tweak transfer logic and add tests * fix[geth]: Remove logic that rejects value gt 0 txs * fix: nonce issue in rpc tests * fix: use correct wallet in rpc value tests * Update rpc.spec.ts * cleanup: remove double definition * chore: add changeset * chore: add changeset * tests: delete dead test * l2geth: log the tx value * l2geth: pass through zero value at top level * test: receipt passes * test: more specifically set balance Co-authored-by: ben-chain <ben@pseudonym.party> Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com>
* feat: Attempt to decode txs as RLP first (#563) Co-authored-by: smartcontracts <smartcontracts@doge.org> * l2geth: remove eth_sendRawEthSignTransaction endpoint (#589) * feat[contracts]: Use standard RLP transaction format (#566) * feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party> * feat[contracts]: Make ProxyEOA compatible with eip1967 (#592) * feat[contracts]: Make ProxyEOA compatible with eip1967 * fix[contracts]: Fix bug introduced by indirect constant * chore[contracts]: Add changeset * Update .changeset/old-cycles-invite.md Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * l2geth: remove ovmsigner (#591) * l2geth: remove ovmsigner Also reduce the diff Co-authored-by: smartcontracts * l2geth: add changeset * l2geth: set rlp encoded tx in txmeta in RPC layer (#644) * l2geth: set rlp encoded tx in txmeta in RPC layer * l2geth: remove extra setter of txmeta * chore: add changeset * feat: Have ExecutionManager pass data upwards (#643) * feat[contracts]: Make ExecutionManager return data * fix[l2geth]: fix linting error * fix[contracts]: Fix build error * fix[contracts]: fix failing unit tests * Add changeset Co-authored-by: Karl Floersch <karl@karlfloersch.com> * rpc: only allow txs with no calldata when there is value (#645) * l2geth: api checks for 0 value * chore: add changeset * l2geth: remove check for specific gasprice * feat[contracts]: Add value transfer support to ECDSAContractAccount (#619) * feat[contracts]: Use standard RLP transaction format (#566) * feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party> * feat[contracts]: Add value transfer to contract account * fix[contracts]: Tweak transfer logic and add tests * fix[geth]: Remove logic that rejects value gt 0 txs * fix: nonce issue in rpc tests * fix: use correct wallet in rpc value tests * Update rpc.spec.ts * cleanup: remove double definition * chore: add changeset * chore: add changeset * tests: delete dead test * l2geth: log the tx value * l2geth: pass through zero value at top level * test: receipt passes * test: more specifically set balance Co-authored-by: ben-chain <ben@pseudonym.party> Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com> * dtl: remove legacy encoding (#618) * dtl: remove legacy decoding * tests: remove dead test * chore: add changeset * Add Goerli v3 deployment (#651) * Add Goerli v3 deployment * Add Goerli v3 to README * dtlL fix syncing off by one (#687) * dtl: syncing off by one error * chore: add changeset * dtl: index the value field (#686) * chore: add changeset * chore: add changeset * dtl: pass through value field * core-utils: update and test toRpcString * lint: fix * l2geth: parse value fields * chore: add changeset * rpc: gas fixes (#695) * l2geth: prevent fees lower than 21000 * l2geth: remove old check for too high tx gaslimit * tests: update to use new min gas estimated value * chore: add changeset * test: update expected values * test: remove dead test * examples: fix waffle example + gas changes in tests (#724) * examples: fix waffle example * tests: update gas price in assertion * chore: add changeset * l2geth: estimate gas assertion in decimal * test: use configurable key * ops: delete extra whitespace (#731) * fix: prevent eth sendtransaction (#725) * api: prevent unsafe calls * api: fill in txmeta * chore: add changeset * chore: add changeset * l2geth + contracts: standard interface for systems contracts and userland contracts (#721) * l2geth: fix call returndata parsing * contracts: standardize simulateMessage and run to return bytes * chore: add changeset * chore: add changeset * l2geth: more simple decoding * contracts: remove named arguments * chore: fix linter errors * Add contract deployment to Kovan (#715) * fix: remove type check in rollup client (#750) * l2geth: remove tx type check in client * chore: add changeset * dtl: prevent null reference in L1 handler (#757) * dtl: prevent reference of null value * chore: add changeset * test: eth_call exceptions (#800) * feat[l2geth]: Pass up contract revert reasons during DoEstimateGas (#774) * wip: Starting work on geth revert reasons during estimate gas fix: error in comment fix: I got things backwards fix: Use UnpackValues instead of Unpack Update l2geth/accounts/abi/abi.go Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * Add integration test for reverts fix: build error * chore: Add changeset Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * chore: add changeset (#831) * Migrate ETH between gateways (#778) * add migrate ETH functionality * contracts: add eth gateway docstring (#832) Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com> Co-authored-by: smartcontracts <smartcontracts@doge.org> Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com> Co-authored-by: smartcontracts <kelvinfichter@gmail.com> Co-authored-by: ben-chain <ben@pseudonym.party> Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: Maurelian <maurelian@protonmail.ch> Co-authored-by: Kevin Ho <kevinjho1996@gmail.com>
…sm#566) * feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party>
…thereum-optimism#619) * feat[contracts]: Use standard RLP transaction format (ethereum-optimism#566) * feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party> * feat[contracts]: Add value transfer to contract account * fix[contracts]: Tweak transfer logic and add tests * fix[geth]: Remove logic that rejects value gt 0 txs * fix: nonce issue in rpc tests * fix: use correct wallet in rpc value tests * Update rpc.spec.ts * cleanup: remove double definition * chore: add changeset * chore: add changeset * tests: delete dead test * l2geth: log the tx value * l2geth: pass through zero value at top level * test: receipt passes * test: more specifically set balance Co-authored-by: ben-chain <ben@pseudonym.party> Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com>
* feat: Attempt to decode txs as RLP first (#563) Co-authored-by: smartcontracts <smartcontracts@doge.org> * l2geth: remove eth_sendRawEthSignTransaction endpoint (#589) * feat[contracts]: Use standard RLP transaction format (#566) * feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party> * feat[contracts]: Make ProxyEOA compatible with eip1967 (#592) * feat[contracts]: Make ProxyEOA compatible with eip1967 * fix[contracts]: Fix bug introduced by indirect constant * chore[contracts]: Add changeset * Update .changeset/old-cycles-invite.md Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * l2geth: remove ovmsigner (#591) * l2geth: remove ovmsigner Also reduce the diff Co-authored-by: smartcontracts * l2geth: add changeset * l2geth: set rlp encoded tx in txmeta in RPC layer (ethereum-optimism#644) * l2geth: set rlp encoded tx in txmeta in RPC layer * l2geth: remove extra setter of txmeta * chore: add changeset * feat: Have ExecutionManager pass data upwards (ethereum-optimism#643) * feat[contracts]: Make ExecutionManager return data * fix[l2geth]: fix linting error * fix[contracts]: Fix build error * fix[contracts]: fix failing unit tests * Add changeset Co-authored-by: Karl Floersch <karl@karlfloersch.com> * rpc: only allow txs with no calldata when there is value (ethereum-optimism#645) * l2geth: api checks for 0 value * chore: add changeset * l2geth: remove check for specific gasprice * feat[contracts]: Add value transfer support to ECDSAContractAccount (ethereum-optimism#619) * feat[contracts]: Use standard RLP transaction format (#566) * feat[contracts]: Use standard RLP transaction format * fix[l2geth]: Encode transaction as RLP * fix: Correct gas estimation in integration tests * fix: Correct gas estimation in integration tests * Update packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol Co-authored-by: ben-chain <ben@pseudonym.party> * fix[contracts]: Use isCreate instead of checking target address * fix[contracts]: Minor optimization in SequencerEntrypoint * fix[contracts]: Pass max gas to contract call in EOA contract Co-authored-by: ben-chain <ben@pseudonym.party> * feat[contracts]: Add value transfer to contract account * fix[contracts]: Tweak transfer logic and add tests * fix[geth]: Remove logic that rejects value gt 0 txs * fix: nonce issue in rpc tests * fix: use correct wallet in rpc value tests * Update rpc.spec.ts * cleanup: remove double definition * chore: add changeset * chore: add changeset * tests: delete dead test * l2geth: log the tx value * l2geth: pass through zero value at top level * test: receipt passes * test: more specifically set balance Co-authored-by: ben-chain <ben@pseudonym.party> Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com> * dtl: remove legacy encoding (ethereum-optimism#618) * dtl: remove legacy decoding * tests: remove dead test * chore: add changeset * Add Goerli v3 deployment (ethereum-optimism#651) * Add Goerli v3 deployment * Add Goerli v3 to README * dtlL fix syncing off by one (ethereum-optimism#687) * dtl: syncing off by one error * chore: add changeset * dtl: index the value field (ethereum-optimism#686) * chore: add changeset * chore: add changeset * dtl: pass through value field * core-utils: update and test toRpcString * lint: fix * l2geth: parse value fields * chore: add changeset * rpc: gas fixes (ethereum-optimism#695) * l2geth: prevent fees lower than 21000 * l2geth: remove old check for too high tx gaslimit * tests: update to use new min gas estimated value * chore: add changeset * test: update expected values * test: remove dead test * examples: fix waffle example + gas changes in tests (ethereum-optimism#724) * examples: fix waffle example * tests: update gas price in assertion * chore: add changeset * l2geth: estimate gas assertion in decimal * test: use configurable key * ops: delete extra whitespace (ethereum-optimism#731) * fix: prevent eth sendtransaction (ethereum-optimism#725) * api: prevent unsafe calls * api: fill in txmeta * chore: add changeset * chore: add changeset * l2geth + contracts: standard interface for systems contracts and userland contracts (ethereum-optimism#721) * l2geth: fix call returndata parsing * contracts: standardize simulateMessage and run to return bytes * chore: add changeset * chore: add changeset * l2geth: more simple decoding * contracts: remove named arguments * chore: fix linter errors * Add contract deployment to Kovan (ethereum-optimism#715) * fix: remove type check in rollup client (ethereum-optimism#750) * l2geth: remove tx type check in client * chore: add changeset * dtl: prevent null reference in L1 handler (ethereum-optimism#757) * dtl: prevent reference of null value * chore: add changeset * test: eth_call exceptions (ethereum-optimism#800) * feat[l2geth]: Pass up contract revert reasons during DoEstimateGas (ethereum-optimism#774) * wip: Starting work on geth revert reasons during estimate gas fix: error in comment fix: I got things backwards fix: Use UnpackValues instead of Unpack Update l2geth/accounts/abi/abi.go Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * Add integration test for reverts fix: build error * chore: Add changeset Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * chore: add changeset (ethereum-optimism#831) * Migrate ETH between gateways (ethereum-optimism#778) * add migrate ETH functionality * contracts: add eth gateway docstring (ethereum-optimism#832) Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com> Co-authored-by: smartcontracts <smartcontracts@doge.org> Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com> Co-authored-by: smartcontracts <kelvinfichter@gmail.com> Co-authored-by: ben-chain <ben@pseudonym.party> Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> Co-authored-by: Maurelian <maurelian@protonmail.ch> Co-authored-by: Kevin Ho <kevinjho1996@gmail.com>
* feat(derive): new batch span stage for holocene * small fix
Renamed the test function test_serde_rountrip_op_execution_payload_envelope to test_serde_roundtrip_op_execution_payload_envelope to correct a spelling mistake in "roundtrip". This ensures consistency and improves code readability.
Closes #566 (1/5) Co-authored-by: Arun Dhyani <dhyaniarun7@gmail.com>
Closes #566 --------- Co-authored-by: Himess <95512809+Himess@users.noreply.github.com> Co-authored-by: Himess <semihcvlk53@gmail.com>
Description
Porting over https://github.com/ethereum-optimism/contracts/pull/300/files now that we've converted the predeploys to use
optimistic-solc. ModifiesOVM_ECDSAContractAccountandOVM_SequencerEntrypointto only accept standard RLP transactions and not accept our custom format.