Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Circuit for EXTCODEHASH opcode #353

Merged

Conversation

z2trillion
Copy link
Collaborator

@z2trillion z2trillion commented Feb 26, 2022

@github-actions github-actions bot added crate-bus-mapping Issues related to the bus-mapping workspace member T-opcode Type: opcode-related and focused PR/Issue labels Feb 26, 2022
@z2trillion z2trillion force-pushed the feat/opcode-extcodehash branch 2 times, most recently from f3e186b to 14ec0d9 Compare February 26, 2022 03:24
@z2trillion
Copy link
Collaborator Author

@ed255, can you take a look at this when you get the chance?

external_address: RandomLinearCombination<F, N_BYTES_ACCOUNT_ADDRESS>,
tx_id: Cell<F>,
previously_accessed: Cell<F>,
external_code_hash: Cell<F>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be Word<F>, right? As the code hash can be more than 254 bits

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The code hash is 256 bits, but the constraints are all expressed in terms of its RLC encoding. The code hash is RLC encoded for the RW table here: https://github.com/scroll-tech/zkevm-circuits/blob/e2a746f632f67e905fde5390e604c491cbc367fc/zkevm-circuits/src/evm_circuit/witness.rs#L647 and self.external_code_hash is RLC encoded in the assign_exec_step step in this gadget as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

Correct!

Comment on lines 142 to 143
#[test]
fn extcodehash_gadget_cold_account() {
Copy link
Collaborator

@roynalnaruto roynalnaruto Feb 28, 2022

Choose a reason for hiding this comment

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

I think we should also have a test case that asserts failure, when gas available is only sufficient for a warm account, whereas gas_cost for EXTCODEHASH should be more than that (for a cold account). In this scenario the prover should fail with insufficient gas available.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wrote this test:

    #[test]
    fn extcodehash_gadget_insufficient_gas() {
        let address = address!("0xaabbccddee000000000000000000000000000011");
        let code = bytecode! {
            PUSH20(address.to_word())
            #[start]
            EXTCODEHASH
            STOP
        };
        assert_eq!(test_circuits_using_bytecode(code, BytecodeTestConfig {
            gas_limit: 100,
            ..Default::default()
        }), Ok(()));
    }

but it fails with

---- evm_circuit::execution::extcodehash::test::extcodehash_gadget_insufficient_gas stdout ----
thread 'evm_circuit::execution::extcodehash::test::extcodehash_gadget_insufficient_gas' panicked at 'called `Result::unwrap()` on an `Err` value: TracingError("Failed to trace tx, err: intrinsic gas too low: have 100, want 21000")', zkevm-circuits/src/test_util.rs:58:78

which is during the witness generation. I don't think it's possible (right now) to even try to generate a proof for a transaction that reverts because of insufficient gas.

The two existing warm/cold tests already ensure that the gas cost constraint in the state transition is correct.

Copy link
Contributor

Choose a reason for hiding this comment

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

We're working on enabling better test-case generation. See: #349
Other Opcodes like GASPRICE also do have issues to be implemented until we close it.
We can leave an issue open as tech-debt or something similar.

For now, we don't really have a way as when Geth gets an out-of-gas exception it doesn't return the trace.
We also need to update this behaviour. And we should file an issue for that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Forget about what I said above.
I was wrong. In fact, a tx like the one you purpose here is not valid. And would not be included in a block as basically, there's no way to execute it.

The minimum gas needed to start a tx is 21000. Hence, if you use 21001 as gas argument this would end up in an out-of-gas and you'd get a trace back. But without enough funds to even kickstart the tx,

My suggestion is to increase the gas you provide to the tx.

Copy link
Contributor

@CPerezz CPerezz left a comment

Choose a reason for hiding this comment

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

LGTM

Brilliant job!!

external_address: RandomLinearCombination<F, N_BYTES_ACCOUNT_ADDRESS>,
tx_id: Cell<F>,
previously_accessed: Cell<F>,
external_code_hash: Cell<F>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Correct!

Comment on lines 142 to 143
#[test]
fn extcodehash_gadget_cold_account() {
Copy link
Contributor

Choose a reason for hiding this comment

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

We're working on enabling better test-case generation. See: #349
Other Opcodes like GASPRICE also do have issues to be implemented until we close it.
We can leave an issue open as tech-debt or something similar.

For now, we don't really have a way as when Geth gets an out-of-gas exception it doesn't return the trace.
We also need to update this behaviour. And we should file an issue for that.

@ed255
Copy link
Member

ed255 commented Mar 7, 2022

@z2trillion The current approach followed to implement the EXTCODEHASH looks good to me! I think it would be good to now work on the spec of this opcode :) And once the spec is reviewed and merged we can conclude the work in this PR.

@z2trillion z2trillion force-pushed the feat/opcode-extcodehash branch from 0637e1a to 8d4ce09 Compare March 7, 2022 18:17
@z2trillion
Copy link
Collaborator Author

@ed255 i've made a PR for the specs here: privacy-scaling-explorations/zkevm-specs#139. This PR is ready for another look as well.

@z2trillion z2trillion requested a review from ed255 March 8, 2022 02:29
@z2trillion z2trillion force-pushed the feat/opcode-extcodehash branch from 595c329 to 3df8130 Compare March 14, 2022 22:38
@z2trillion
Copy link
Collaborator Author

@ed255 this is ready for review again

Copy link
Member

@ed255 ed255 left a comment

Choose a reason for hiding this comment

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

Overall looks good! I've just added a few comments about details on the bus-mapping implementation, and a typo I spotted in the circuit tests.

@z2trillion z2trillion requested a review from ed255 March 16, 2022 19:41
from_bytes::expr(&external_address.cells),
1.expr(),
is_warm.expr(),
None,
Copy link
Member

Choose a reason for hiding this comment

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

I've reviewed the implementation of SSTORE and I realized I missed this before. For an op that can revert, this shouldn't be None. Take a look here:
https://github.com/appliedzkp/zkevm-circuits/blob/c5dda20e901951e61f751b89dd50607f83b98a95/zkevm-circuits/src/evm_circuit/execution/sstore.rs#L75-L81

This will require adding two read operations for CallContextFieldTag::RwCounterEndOfReversion, CallContextFieldTag::IsPersistent as seen here:
https://github.com/appliedzkp/zkevm-circuits/blob/c5dda20e901951e61f751b89dd50607f83b98a95/zkevm-circuits/src/evm_circuit/execution/sstore.rs#L50-L56

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've made these changes to the circuit and the changes needed to the bus mapping, but now the circuit tests fail.

Do you know if the witness generation supports RwCounterEndOfReversion and IsPersistent? I noticed that the sload bus mapping doesn't correspond to the circuit and that the sload and sstore circuits both manually construct the rw tables for their tests.

Copy link
Member

Choose a reason for hiding this comment

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

I've made these changes to the circuit and the changes needed to the bus mapping, but now the circuit tests fail.

Do you know if the witness generation supports RwCounterEndOfReversion and IsPersistent? I noticed that the sload bus mapping doesn't correspond to the circuit and that the sload and sstore circuits both manually construct the rw tables for their tests.

I will investigate this

Copy link
Member

Choose a reason for hiding this comment

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

Found the bug! After you added generating the operations for CallContextFieldTag::RwCounterEndOfReversion and CallContextFieldTag::RwCounterEndOfReversion you altered the positions of the other operations for that step in rw_indices. So when you query the values in the assign advice method, you need to update the indexes of rw_index to obtain the values for nonce, balance and code_hash. See #353 (comment)

@z2trillion z2trillion force-pushed the feat/opcode-extcodehash branch from 9c760d0 to 33cf4f7 Compare March 21, 2022 17:25
Co-authored-by: Eduard S. <eduardsanou@posteo.net>
Copy link
Member

@ed255 ed255 left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for working on this :)

Copy link
Collaborator

@icemelon icemelon left a comment

Choose a reason for hiding this comment

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

LGTM. just one nitpick

* (1.expr() - nonce.expr() * nonempty_witness.expr())
* (1.expr() - balance.expr() * nonempty_witness.expr())
* (1.expr() - (code_hash.expr() - empty_code_hash_rlc) * nonempty_witness.expr()),
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is smart. it took me a while to realize the constraint is right. 😄

Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
@icemelon icemelon merged commit 1ec38f2 into privacy-scaling-explorations:main Mar 24, 2022
@icemelon icemelon deleted the feat/opcode-extcodehash branch March 24, 2022 19:42
zemse pushed a commit to zemse/zkevm-circuits that referenced this pull request Mar 22, 2023
* add test case for tx.to is zero

* fix: handle the rlp of tx whose to = zero

* add gates for is_create

* clippy
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
crate-bus-mapping Issues related to the bus-mapping workspace member T-opcode Type: opcode-related and focused PR/Issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants