Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing Otterscan support #5414

Merged
merged 43 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
a119ceb
Implementing Otterscan support
naps62 Jul 16, 2023
7b6871b
comments
naps62 Jul 17, 2023
6205a0e
code review
naps62 Jul 17, 2023
34b966d
code review
naps62 Jul 17, 2023
93bcbd9
code review
naps62 Jul 18, 2023
e0dea78
code review
naps62 Jul 18, 2023
c80fab8
Merge branch 'master' into ots
naps62 Jul 18, 2023
88feee7
code review
naps62 Jul 18, 2023
664b54a
Some fixes
naps62 Jul 19, 2023
00e085e
code review
naps62 Jul 19, 2023
7350691
Merge branch 'master' into ots
naps62 Jul 26, 2023
25db0cc
Update anvil/src/eth/otterscan.rs
naps62 Jul 26, 2023
0d38757
code review
naps62 Jul 26, 2023
52e03f4
code review
naps62 Jul 26, 2023
460d598
ots_getBlockDetailsByHash
naps62 Jul 26, 2023
b10230a
search endpoints tests
naps62 Jul 27, 2023
ac835bf
tests for ots_getBlockTransactions
naps62 Jul 27, 2023
1d79382
tests for ots_getBlockDetails
naps62 Jul 27, 2023
432d89f
code review
naps62 Jul 27, 2023
9b11ebf
code review
naps62 Jul 28, 2023
0520337
code review
naps62 Jul 28, 2023
3ad752e
code review
naps62 Jul 28, 2023
9d652cb
code review
naps62 Jul 28, 2023
92659cd
code review
naps62 Jul 28, 2023
045f397
code review
naps62 Jul 28, 2023
0ba605f
code review
naps62 Jul 31, 2023
006555f
code review
naps62 Jul 31, 2023
76f226b
code review
naps62 Jul 31, 2023
3789fd2
code review
naps62 Jul 31, 2023
658d0f4
Merge branch 'master' into ots
naps62 Aug 7, 2023
751e88d
code review
naps62 Aug 7, 2023
2542ba8
code review
naps62 Aug 7, 2023
864e3b1
code review
naps62 Aug 7, 2023
3aba8d6
code review
naps62 Aug 7, 2023
9caf3fb
code review
naps62 Aug 7, 2023
52e94a8
code review
naps62 Aug 7, 2023
293496e
Merge branch 'master' into ots
naps62 Aug 8, 2023
50cf28b
code review
naps62 Aug 8, 2023
53dcf44
Update Cargo.toml
naps62 Aug 8, 2023
4aafc9b
code review
naps62 Aug 8, 2023
5444bc9
clippy
Evalir Aug 8, 2023
9519f9f
code review
naps62 Aug 8, 2023
486c71d
code review
naps62 Aug 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ vergen = { version = "8", default-features = false, features = ["build", "git",
[dependencies]
# foundry internal
foundry-evm = { path = "../evm" }
anvil-core = { path = "core", features = ["fastrlp", "serde", "impersonated-tx"] }
anvil-core = { path = "core", features = ["otterscan", "fastrlp", "serde", "impersonated-tx"] }
anvil-rpc = { path = "rpc" }
anvil-server = { path = "server" }
foundry-utils = { path = "../utils" }
Expand Down Expand Up @@ -55,6 +55,7 @@ serde = { version = "1", features = ["derive"] }
thiserror = "1"
yansi = "0.5"
tempfile = "3"
itertools = "0.10"

# cli
clap = { version = "4", features = ["derive", "env", "wrap_help"], optional = true }
Expand All @@ -75,6 +76,7 @@ tokio = { version = "1", features = ["full"] }
crc = "3.0.1"

[features]
default = ["cli"]
default = ["cli", "otterscan"]
cmd = ["foundry-common", "forge", "clap", "clap_complete", "ctrlc", "anvil-server/clap"]
cli = ["tokio/full", "cmd", "fdlimit"]
otterscan = []
1 change: 1 addition & 0 deletions anvil/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ default = []
impersonated-tx = []
fastrlp = ["dep:open-fastrlp"]
serde = ["dep:serde"]
otterscan = []
100 changes: 100 additions & 0 deletions anvil/core/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,106 @@ pub enum EthRequest {
/// Ref: [Here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content)
#[cfg_attr(feature = "serde", serde(rename = "txpool_content", with = "empty_params"))]
TxPoolContent(()),

/// Otterscan's `ots_getApiLevel` endpoint
/// Otterscan currently requires this endpoint, even though it's not part of the ots_*
/// https://github.com/otterscan/otterscan/blob/071d8c55202badf01804f6f8d53ef9311d4a9e47/src/useProvider.ts#L71
/// Related upstream issue: https://github.com/otterscan/otterscan/issues/1081
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "erigon_getHeaderByNumber"))]
ErigonGetHeaderByNumber(
Copy link
Member

Choose a reason for hiding this comment

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

Should this be called so? If so, can we add a bit of context as to why it has erigon naming? not super familiar with otterscan so just wanna make sure we have this documented 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I documented the impl EthApi functions, but now that you mention, probably most of those comments belong here instead

As for this particular one, it's otterscan being a bit sneaky and making an erigon-specific call on load to "check if we're connected to an erigon node". In practice I think they could achieve the same result (show a proper error msg when the node isnt' supported) by using ay other ots_ endpoint, but oh well.

Perhaps I'll change that upstream later. for now it's reported here, waiting for input: otterscan/otterscan#1081

#[cfg_attr(feature = "serde", serde(deserialize_with = "lenient_block_number_seq"))]
BlockNumber,
),

/// Otterscan's `ots_getApiLevel` endpoint
/// Used as a simple API versioning scheme for the ots_* namespace
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_getApiLevel", with = "empty_params"))]
OtsGetApiLevel(()),

/// Otterscan's `ots_getInternalOperations` endpoint
/// Traces internal ETH transfers, contracts creation (CREATE/CREATE2) and self-destructs for a
/// certain transaction.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_getInternalOperations", with = "sequence"))]
OtsGetInternalOperations(H256),

/// Otterscan's `ots_hasCode` endpoint
/// Check if an ETH address contains code at a certain block number.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_hasCode"))]
OtsHasCode(
Address,
#[cfg_attr(feature = "serde", serde(deserialize_with = "lenient_block_number", default))]
BlockNumber,
),

/// Otterscan's `ots_traceTransaction` endpoint
/// Trace a transaction and generate a trace call tree.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_traceTransaction", with = "sequence"))]
OtsTraceTransaction(H256),

/// Otterscan's `ots_getTransactionError` endpoint
/// Given a transaction hash, returns its raw revert reason.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_getTransactionError", with = "sequence"))]
OtsGetTransactionError(H256),

/// Otterscan's `ots_getBlockDetails` endpoint
/// Given a block number, return its data. Similar to the standard eth_getBlockByNumber/Hash
/// method, but can be optimized by excluding unnecessary data such as transactions and
/// logBloom
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_getBlockDetails"))]
OtsGetBlockDetails(
#[cfg_attr(feature = "serde", serde(deserialize_with = "lenient_block_number_seq"))]
BlockNumber,
),

/// Otterscan's `ots_getBlockDetails` endpoint
/// Same as `ots_getBlockDetails`, but receiving a block hash instead of number
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_getBlockDetailsByHash", with = "sequence"))]
OtsGetBlockDetailsByHash(H256),

/// Otterscan's `ots_getBlockTransactions` endpoint
/// Gets paginated transaction data for a certain block. Return data is similar to
/// eth_getBlockBy* + eth_getTransactionReceipt.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_getBlockTransactions"))]
OtsGetBlockTransactions(u64, usize, usize),

/// Otterscan's `ots_searchTransactionsBefore` endpoint
/// Address history navigation. searches backwards from certain point in time.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_searchTransactionsBefore"))]
OtsSearchTransactionsBefore(Address, u64, usize),

/// Otterscan's `ots_searchTransactionsAfter` endpoint
/// Address history navigation. searches forward from certain point in time.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_searchTransactionsAfter"))]
OtsSearchTransactionsAfter(Address, u64, usize),

/// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
/// Given a sender address and a nonce, returns the tx hash or null if not found. It returns
/// only the tx hash on success, you can use the standard eth_getTransactionByHash after that
/// to get the full transaction data.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_getTransactionBySenderAndNonce",))]
OtsGetTransactionBySenderAndNonce(
Address,
#[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize_number"))] U256,
),

/// Otterscan's `ots_getTransactionBySenderAndNonce` endpoint
/// Given an ETH contract address, returns the tx hash and the direct address who created the
/// contract.
#[cfg(feature = "otterscan")]
#[cfg_attr(feature = "serde", serde(rename = "ots_getContractCreator", with = "sequence"))]
OtsGetContractCreator(Address),
}

/// Represents ethereum JSON-RPC API
Expand Down
Loading