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

Introduce native tracer support #81

Merged
merged 10 commits into from
Jun 17, 2024

Conversation

frisitano
Copy link
Contributor

This PR introduces native tracer support such that blocks can be prover using standard rpc methods. This is a replacement for #51. This is currently blocked as alchemy is returning incorrect data for prestate tracer requests. I have opened a ticket with the support team and they are looking into it.

Merge steps:

  1. Merge companion PR Native trace processing support zk_evm#246
  2. Repoint zk_evm dependencies in cargo to either the git repo or a new release.
  3. Merge this PR into develop.

@frisitano
Copy link
Contributor Author

frisitano commented May 27, 2024

I have tested this over the block range of 19240650 - 19240850 and 199 blocks completed successfully with one failure. This yields a 99.5% success rate.

@muursh
Copy link
Contributor

muursh commented May 27, 2024

I have tested this over the block range of 19240650 - 19240850 and 199 blocks completed successfully with one failure. This yields a 99.5% success rate.

What was the failure? Which block and do you know why?

@frisitano
Copy link
Contributor Author

I have tested this over the block range of 19240650 - 19240850 and 199 blocks completed successfully with one failure. This yields a 99.5% success rate.

What was the failure? Which block and do you know why?

It's block 19240734. The error is:

Error: Failed to get proof for account: JsonRpcClientError(TimeoutError)

I have not had a chance to investigate the root cause of this but @Nashtare and I had concluded that the success rate was sufficiently high to merge as is and then leave this investigation / fix for a follow up issue / PR.

@Nashtare Nashtare added the enhancement New feature or request label May 28, 2024
Cargo.toml Outdated Show resolved Hide resolved
@frisitano frisitano force-pushed the tx-proof-rpc-new branch 4 times, most recently from 4bbad04 to 5234bc9 Compare May 30, 2024 15:57
@@ -5,6 +5,7 @@
# 2 --> End block index (inclusive)
# 3 --> Rpc endpoint:port (eg. http://35.246.1.96:8545)
# 4 --> Ignore previous proofs (boolean)
# 5 --> Rpc type (eg. jerigon / native)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be set before Ignore previous proofs? So that it goes in pair with the RPC endpoint, and we can keep the boolean as optional with default value. Not really blocking though

Comment on lines 58 to 60
debug!("Got block result: {:?}", rpc_block_metadata.block_by_number);
debug!("Got trace result: {:?}", block_trace);
debug!("Got chain_id: {:?}", rpc_block_metadata.chain_id);
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: maybe remove? Not sure this brings much

) -> Result<Vec<TxnInfo>> {
let mut futures_ordered = FuturesOrdered::new();

for tx_hash in &block.transactions {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Last time we tested blocks, I recall we needed to reverse the order here. Has this been tested since @frisitano?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I tested this on 200 blocks with a 99.5% success rate. The change was made below on line 30 in which we push_back instead of the prior push_front, see ref.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Awesome, thanks!
The failure being due to the branch collapsing bug mentioned in the related issue I presume?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No that issue has been fixed (hacked) by fetching proofs after block execution and inserting short nodes (extension and leafs) into the trie builder.

This failure is due to an error when trying to fetch a proof for an account - see #81 (comment). I haven't had an opportunity to look into it.

Comment on lines 15 to 18
pub const EMPTY_TRIE_HASH: H256 = H256([
0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e,
0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21,
]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

non-blocking, as not exposed (yet) but we should try to group all these common constants somewhere (probably somewhere under zk_evm crates) and reuse/re-exports them instead of always redefining them

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, I will add a TODO. I was also wondering if this module would be better positioned in the zk_evm/mpt_trie crate for reuse?

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah that'd make sense, it's a bit too specific on MPTs to be inside zero-bin I'd say.
cc @0xaatif @BGluth

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah I think inside mpt_trie probably makes the most sense.

@frisitano
Copy link
Contributor Author

I've opened a PR in zk_evm repo to migrate the PartialTrieBuilder. I've repointed deps of this PR to the new branch and also addressed the feedback. Once that PR is merged I will repoint deps and squash commits to make it ready for merge.

@0xaatif 0xaatif self-requested a review June 4, 2024 10:00
Copy link
Contributor

@0xaatif 0xaatif left a comment

Choose a reason for hiding this comment

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

The most important change is keeping with alloy from now on.

I'd like to re-review after markups

.gitignore Outdated
@@ -13,3 +13,6 @@ proofs/
# Serialized generated prover & verifier state used by plonky2
prover_state_*
verifier_state_*

# System files
.DS_Store
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: newline

README.md Show resolved Hide resolved
rpc/src/cli.rs Outdated Show resolved Hide resolved
rpc/src/cli.rs Outdated Show resolved Hide resolved
rpc/src/rpc/jerigon.rs Outdated Show resolved Hide resolved

/// A static retry policy that always retries.
#[derive(Debug, Default)]
pub struct StaticRetryPolicy;
Copy link
Contributor

Choose a reason for hiding this comment

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

Library code should never care about this - that's why we should be abstract over Provider

Comment on lines 139 to 145
) -> Result<
(
Vec<(H160, EIP1186ProofResponse)>,
Vec<(H160, EIP1186ProofResponse)>,
),
anyhow::Error,
> {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit

Suggested change
) -> Result<
(
Vec<(H160, EIP1186ProofResponse)>,
Vec<(H160, EIP1186ProofResponse)>,
),
anyhow::Error,
> {
) -> anyhow::Result<[Vec<(H160, EIP1186ProofResponse)>; 2]> {

keys.into_iter().collect(),
Some((block_number - 1).into()),
)
.map_err(|e| anyhow!("Failed to get proof for account: {:?}", e))
Copy link
Contributor

Choose a reason for hiding this comment

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

use anyhow::Context as __;
Suggested change
.map_err(|e| anyhow!("Failed to get proof for account: {:?}", e))
.context("Failed to get proof for account")

Anyhow will preserve the source error in it's cause chain. This is the whole point of using anyhow

futures::try_join!(tx_fut, tx_receipt_fut, pre_trace_fut, diff_trace_fut,)?;

Ok((
tx.ok_or_else(|| anyhow!("Transaction not found."))?,
Copy link
Contributor

Choose a reason for hiding this comment

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

use anyhow::Context as _;
Suggested change
tx.ok_or_else(|| anyhow!("Transaction not found."))?,
tx.context("Transaction not found.")?,

Also works on Options

current_a=$((initial_a + i))
echo "Running debug block script with block=$current_a rpc=$b"
"$script_dir/debug_block.sh" $current_a $b $rpc_type
done
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: NL

@frisitano
Copy link
Contributor Author

The most important change is keeping with alloy from now on.

I'd like to re-review after markups

I've been trying to migrate to alloy but I'm running into an issue when trying to rlp encode the ReceiptEnvelope to populate trace_decoder::trace_protocol::TxnMeta. I would expect the following to work but it doesn't:

    let tx_receipt = provider.get_transaction_receipt(tx_hash).await?.unwrap();
    let tx_receipt_rlp = tx_receipt.inner.encoded_2718();

If someone could take a look at this to assess what I may be doing wrong that would be appreciated.

@0xaatif
Copy link
Contributor

0xaatif commented Jun 5, 2024

Does any of this help?
https://github.com/0xPolygonZero/eth-tx-proof/blob/3805968cf6c1d88fa40ca10a37e9bba00c05faf3/leader/src/lib.rs#L521-L527

/// There are two representations of domain objects in ethereum:
/// - RPC (JSON), in [`alloy::rpc`].
/// - RLP (binary), in [`alloy::consensus`].
///
/// This module provides best-effort [RLP encoding](alloy::rlp::Encodable) for
/// RPC types.

@frisitano
Copy link
Contributor Author

Does any of this help?

https://github.com/0xPolygonZero/eth-tx-proof/blob/3805968cf6c1d88fa40ca10a37e9bba00c05faf3/leader/src/lib.rs#L521-L527

/// There are two representations of domain objects in ethereum:

/// - RPC (JSON), in [`alloy::rpc`].

/// - RLP (binary), in [`alloy::consensus`].

///

/// This module provides best-effort [RLP encoding](alloy::rlp::Encodable) for

/// RPC types.

It certainly looks like it could, thanks!

@vgnom vgnom added this to the Cancun - Q2 2024 milestone Jun 5, 2024
@frisitano
Copy link
Contributor Author

I've implemented an initial migration to alloy but I have hit a blocker. Previously we were using a retry policy to mitigate the request failures due to rate limiting from rpc providers. ethers shipped with an out the box retry client. I have done some investigation to see how we can implement a retry policy for alloy. alloy does ship with a ClientBuilder struct that wraps tower::ServiceBuilder. It is suggested that we should be able to introduce a retry layer using this builder however my efforts (and those of others) have not been successful thus far. Without the retry logic I am unable to test against rpc providers.

This PR still needs a hygiene sweep but I would like to address the retry issue first.

@frisitano frisitano force-pushed the tx-proof-rpc-new branch 2 times, most recently from 73f310c to 7cd3d62 Compare June 8, 2024 14:40
@frisitano
Copy link
Contributor Author

This is ready for review along with 0xPolygonZero/zk_evm#258.

@frisitano frisitano requested a review from 0xaatif June 8, 2024 14:43
@frisitano
Copy link
Contributor Author

I've completed the merge with develop and have tested native. It may be wise to test jerigon again but I don't have access to a jergion rpc.

@atanmarko
Copy link
Member

atanmarko commented Jun 17, 2024

EDIT: obligatory parameter to select jerigon or native before test_only and ignore previous proofs

@frisitano You can probably update tools/prove_jerigon.sh to prove_rpc.sh with the default as jerigon client and optional parameter as native

@frisitano
Copy link
Contributor Author

@frisitano You can probably update tools/prove_jerigon.sh to prove_rpc.sh with the default as jerigon client and optional parameter as native

Good catch! However, I don't think we will be able to make the rpc type optional as we can only have one optional argument (the last positional argument). Currently test_only is being used as the optional argument. I am happy to introduce it as a required argument, what do you think?

@atanmarko
Copy link
Member

Tested prove_jerigon.sh with 371ca61, no regressions.

@frisitano
Copy link
Contributor Author

EDIT: obligatory parameter to select jerigon or native before test_only and ignore previous proofs

@frisitano You can probably update tools/prove_jerigon.sh to prove_rpc.sh with the default as jerigon client and optional parameter as native

I've updated the script. Let me know your thoughts.

@atanmarko
Copy link
Member

EDIT: obligatory parameter to select jerigon or native before test_only and ignore previous proofs
@frisitano You can probably update tools/prove_jerigon.sh to prove_rpc.sh with the default as jerigon client and optional parameter as native

I've updated the script. Let me know your thoughts.

@frisitano Script is OK. Please fix also the docs and the CI.

@frisitano
Copy link
Contributor Author

EDIT: obligatory parameter to select jerigon or native before test_only and ignore previous proofs
@frisitano You can probably update tools/prove_jerigon.sh to prove_rpc.sh with the default as jerigon client and optional parameter as native

I've updated the script. Let me know your thoughts.

@frisitano Script is OK. Please fix also the docs and the CI.

README updated. As discussed on slack, no changes required to CI.

rpc/src/jerigon.rs Outdated Show resolved Hide resolved
@atanmarko
Copy link
Member

atanmarko commented Jun 17, 2024

@frisitano We want to fix alloy version, so we will use recently released tag v0.1.1.
Here is the PR. Could you please regression test it with native tracer? Jerigon works without regressions with v0.1.1.

@atanmarko
Copy link
Member

@Nashtare @BGluth Any additional comments/requests or we are ready to merge?

Copy link
Collaborator

@Nashtare Nashtare left a comment

Choose a reason for hiding this comment

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

@atanmarko Only did a synthetic review over the latest changes but I'm good to merge.

@atanmarko atanmarko removed the request for review from cpubot June 17, 2024 16:53
@atanmarko atanmarko merged commit 23fff4d into 0xPolygonZero:develop Jun 17, 2024
5 checks passed
@frisitano
Copy link
Contributor Author

@frisitano We want to fix alloy version, so we will use recently released tag v0.1.1. Here is the PR. Could you please regression test it with native tracer? Jerigon works without regressions with v0.1.1.

Regression tested latest develop with the native tracer. No regressions, working as expected.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

8 participants