Git Product home page Git Product logo

optimism-rosetta's Introduction

Rosetta

Rosetta Ethereum

ROSETTA-ETHEREUM IS CONSIDERED ALPHA SOFTWARE. USE AT YOUR OWN RISK! COINBASE ASSUMES NO RESPONSIBILITY OR LIABILITY IF THERE IS A BUG IN THIS IMPLEMENTATION.

Overview

rosetta-ethereum provides a reference implementation of the Rosetta API for Ethereum in Golang. If you haven't heard of the Rosetta API, you can find more information here.

Features

  • Comprehensive tracking of all ETH balance changes
  • Stateless, offline, curve-based transaction construction (with address checksum validation)
  • Atomic balance lookups using go-ethereum's GraphQL Endpoint
  • Idempotent access to all transaction traces and receipts

System Requirements

rosetta-ethereum has been tested on an AWS c5.2xlarge instance. This instance type has 8 vCPU and 16 GB of RAM. If you use a computer with less than 16 GB of RAM, it is possible that rosetta-ethereum will exit with an OOM error.

Recommended OS Settings

To increase the load rosetta-ethereum can handle, it is recommended to tune your OS settings to allow for more connections. On a linux-based OS, you can run the following commands (source):

sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_max_syn_backlog=10000
sysctl -w net.core.somaxconn=10000
sysctl -p (when done)

We have not tested rosetta-ethereum with net.ipv4.tcp_tw_recycle and do not recommend enabling it.

You should also modify your open file settings to 100000. This can be done on a linux-based OS with the command: ulimit -n 100000.

Usage

As specified in the Rosetta API Principles, all Rosetta implementations must be deployable via Docker and support running via either an online or offline mode.

YOU MUST INSTALL DOCKER FOR THE FOLLOWING INSTRUCTIONS TO WORK. YOU CAN DOWNLOAD DOCKER HERE.

Install

Running the following commands will create a Docker image called rosetta-ethereum:latest.

From GitHub

To download the pre-built Docker image from the latest release, run:

curl -sSfL https://raw.githubusercontent.com/coinbase/rosetta-ethereum/master/install.sh | sh -s

Do not try to install rosetta-ethereum using GitHub Packages!

From Source

After cloning this repository, run:

make build-local

Run

Running the following commands will start a Docker container in detached mode with a data directory at <working directory>/ethereum-data and the Rosetta API accessible at port 8080.

Configuration Environment Variables

  • MODE (required) - Determines if Rosetta can make outbound connections. Options: ONLINE or OFFLINE.
  • NETWORK (required) - Ethereum network to launch and/or communicate with. Options: MAINNET, ROPSTEN, RINKEBY, GOERLI or TESTNET (which defaults to ROPSTEN for backwards compatibility).
  • PORT(required) - Which port to use for Rosetta.
  • GETH (optional) - Point to a remote geth node instead of initializing one
  • SKIP_GETH_ADMIN (optional, default: FALSE) - Instruct Rosetta to not use the geth admin RPC calls. This is typically disabled by hosted blockchain node services.

Mainnet:Online

docker run -d --rm --ulimit "nofile=100000:100000" -v "$(pwd)/ethereum-data:/data" -e "MODE=ONLINE" -e "NETWORK=MAINNET" -e "PORT=8080" -p 8080:8080 -p 30303:30303 rosetta-ethereum:latest

If you cloned the repository, you can run make run-mainnet-online.

Mainnet:Online (Remote)

docker run -d --rm --ulimit "nofile=100000:100000" -e "MODE=ONLINE" -e "NETWORK=MAINNET" -e "PORT=8080" -e "GETH=<NODE URL>" -p 8080:8080 -p 30303:30303 rosetta-ethereum:latest

If you cloned the repository, you can run make run-mainnet-remote geth=<NODE URL>.

Mainnet:Offline

docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=MAINNET" -e "PORT=8081" -p 8081:8081 rosetta-ethereum:latest

If you cloned the repository, you can run make run-mainnet-offline.

Testnet:Online

docker run -d --rm --ulimit "nofile=100000:100000" -v "$(pwd)/ethereum-data:/data" -e "MODE=ONLINE" -e "NETWORK=TESTNET" -e "PORT=8080" -p 8080:8080 -p 30303:30303 rosetta-ethereum:latest

If you cloned the repository, you can run make run-testnet-online.

Testnet:Online (Remote)

docker run -d --rm --ulimit "nofile=100000:100000" -e "MODE=ONLINE" -e "NETWORK=TESTNET" -e "PORT=8080" -e "GETH=<NODE URL>" -p 8080:8080 -p 30303:30303 rosetta-ethereum:latest

If you cloned the repository, you can run make run-testnet-remote geth=<NODE URL>.

Testnet:Offline

docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=TESTNET" -e "PORT=8081" -p 8081:8081 rosetta-ethereum:latest

If you cloned the repository, you can run make run-testnet-offline.

Testing with rosetta-cli

To validate rosetta-ethereum, install rosetta-cli and run one of the following commands:

  • rosetta-cli check:data --configuration-file rosetta-cli-conf/testnet/config.json - This command validates that the Data API implementation is correct using the ethereum testnet node. It also ensures that the implementation does not miss any balance-changing operations.
  • rosetta-cli check:construction --configuration-file rosetta-cli-conf/testnet/config.json - This command validates the Construction API implementation. It also verifies transaction construction, signing, and submissions to the testnet network.
  • rosetta-cli check:data --configuration-file rosetta-cli-conf/mainnet/config.json - This command validates that the Data API implementation is correct using the ethereum mainnet node. It also ensures that the implementation does not miss any balance-changing operations.

Issues

Interested in helping fix issues in this repository? You can find to-dos in the Issues section. Be sure to reach out on our community before you tackle anything on this list.

Development

  • make deps to install dependencies
  • make test to run tests
  • make lint to lint the source code
  • make salus to check for security concerns
  • make build-local to build a Docker image from the local context
  • make coverage-local to generate a coverage report

License

This project is available open source under the terms of the Apache 2.0 License.

© 2021 Coinbase

optimism-rosetta's People

Contributors

akramhussein avatar andrewkmin avatar annieke avatar bruceliux avatar dependabot[bot] avatar dneilroth avatar geekarthur avatar gqln avatar inphi avatar lenny-hardenberg avatar patrick-ogrady avatar qiwu7 avatar racbc avatar refcell avatar riyasattalukder avatar roberto-bayardo avatar shrimalmadhur avatar ssutch-cb avatar xiangliu-cb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

optimism-rosetta's Issues

Provide tx value when estimating gas

Context: maticnetwork/polygon-rosetta#25

This is not an issue on Optimism right now because our l2geth is based on an older version of geth that isn't affected by this bug. However, post-bedrock, we'll be using the latest upstream, vanilla geth.

The estimateGas Value arg isn't used on Optimism so it won't hurt to add it right now to avoid breakage in the future.

/construction/preprocess operation type issue

Describe the bug
The block and account balance issues have been fixed, many thanks! I find another issue on /construction/preprocess with the following error:

2022/02/28 22:11:42 REQUEST /construction/preprocess network_identifier:{"blockchain":"Optimism","network":"Testnet"} intent:[{"operation_identifier":{"index":0},"type":"PAYMENT","account":{"address":"0x9670d6977d0b10130E5d4916c9134363281B6B0e"},"amount":{"value":"-100000000000","currency":{"symbol":"OP","decimals":18,"metadata":{"token_address":"0xF8B089026CaD7DDD8CB8d79036A1ff1d4233d64A"}}}},{"operation_identifier":{"index":1},"related_operations":[{"index":0}],"type":"PAYMENT","account":{"address":"0x705f9aE78b11a3ED5080c053Fa4Fa0c52359c674"},"amount":{"value":"100000000000","currency":{"symbol":"OP","decimals":18,"metadata":{"token_address":"0xF8B089026CaD7DDD8CB8d79036A1ff1d4233d64A"}}}}] metadata:null
2022/02/28 22:11:42 ERROR /construction/preprocess error:{"err":{},"client_err":{"code":4,"message":"Unable to parse intent","retriable":false,"details":{"context":"unable to find match for operation: at index 0"}},"retry":false}
2022/02/28 22:11:42 check:construction status server shutting down
[MEMORY] Heap: 4078.060371MB Stack: 1.343750MB System: 4235.299797MB GCs: 3

Error: request failed: /construction/preprocess {Code:4 Message:Unable to parse intent Description:<nil> Retriable:false Details:map[context:unable to find match for operation: at index 0]}: unable to preprocess: unable to create transaction

The root cause is in matchTransferOperations function: https://github.com/Inphi/optimism-rosetta/blob/master/services/construction_service.go#L712, we still use CALL operation type to match, but OP token transfer contract call uses PAYMENT as operation type.
To fix this, I think we need to ensure matchTransferOperations supports both CALL for native token and PAYMENT for OP/ERC20 token

Reconciliation issue on mainnet

Describe the bug
I find a reconciliation issue on mainnet:

Error: reconciliation failure: active reconciliation error for 0x40C539BBe076b91FdF681E6B4B84bd1Fe1F148d9 at 1502839 (computed: 0ETH, live: 100000000000000ETH)

The problem is for 0x40C539BBe076b91FdF681E6B4B84bd1Fe1F148d9(seems like it’s a contract account) at height 1502839, the computed balance is different from the live balance

I check the /block at height 1502839 and notice that the SELFDESTRUCT operation deducts 100000000000000 from the account, that’s why the computed balance is 0. But from the explorer https://optimistic.etherscan.io/tx/0x3ff079ba4ea0745401e9661d623550d24c9412ea9ad578bfbb0d441dadcce9bc seems like there is no any funds transfer/deduction from the account with the SELFDESTRUCT operation. To fix this, we may need to handle the SELFDESTRUCT properly for /block

{
                        "operation_identifier": {
                            "index": 2
                        },
                        "type": "SELFDESTRUCT",
                        "status": "SUCCESS",
                        "account": {
                            "address": "0x40C539BBe076b91FdF681E6B4B84bd1Fe1F148d9"
                        },
                        "amount": {
                            "value": "-100000000000000",
                            "currency": {
                                "symbol": "ETH",
                                "decimals": 18
                            }
                        }
                    }

Account API doesn't return OP token balance

Describe the bug
I test our testing account 0x9670d6977d0b10130E5d4916c9134363281B6B0e at height 1241242, then get the following response

{
    "block_identifier": {
        "index": 1241242,
        "hash": "0x9743df7f8f49faa952401c9ab3628f813016a9c42194a759d5cc636b216338d4"
    },
    "balances": [
        {
            "value": "1009271209351159315",
            "currency": {
                "symbol": "ETH",
                "decimals": 18
            }
        }
    ],
    "metadata": {
        "code": "0x",
        "nonce": 74
    }
}

The response doesn’t return the balance of the OP token, I think we need to investigate and fix it, also FWIW we can always use this transaction https://kovan-optimistic.etherscan.io/tx/0x0a0cfe735e0fc3549db81d07670e98d18d9f909de44ef9ad0446725b0d7a806c for quick testing as it’s the OP token transfer transaction for our testing account

Amount <nil> issue from /block for ERC20 token

Describe the bug
I find an issue related to /block API for ERC20 token with the following errors:

Error: unable to fetch block 11516: Amount.Value is not an integer: <nil>: amount is invalid in operation 2 invalid operation in transaction 0x859431549be32cccca16c3f41ca8c9d4ffc73eca7eb75ba0868b0d6b6aa336e7: /block: /block not attempting retry: unable to sync to 1410879: unable to sync to 1410879

Manually try the /block API on 11516 can also detect the <nil> amount

{
                        "operation_identifier": {
                            "index": 2
                        },
                        "type": "CALL",
                        "status": "SUCCESS",
                        "account": {
                            "address": "0x0000000000000000000000000000000000000000"
                        },
                        "amount": {
                            "value": "<nil>",
                            "currency": {
                                "symbol": "ETH",
                                "decimals": 18
                            }
                        }
                    }

I think root cause may be from here: https://github.com/Inphi/optimism-rosetta/blob/master/optimism/client.go#L764, which doesn’t handle the error properly and results in <nil> amount

Feat: Replace Block Tracing with Transaction Tracing

Overview

Average gas usage on optimism is at least 30-50% more than L1. On some days, we see gas usage up by 200-500% (etherscan has charts on this). So I'm concerned that tracing an entire block rather than per transaction would be too expensive for op-geth. Tracing consumes alot of CPU, memory and I/O for the response back and we've seen each of these resources being exhausted for legacy geth.

I'd prefer that we trace individually by transaction. But for now, let's add a TODO here so we don't forget to treat this properly.

Additional context
#77 (comment)

Genesis hash difference between /network/status and /block

Describe the bug
We notice the difference on genesis hash between /network/status and /block, for testnet
Response of /network/status

{
    "current_block_identifier": {
        "index": 1423803,
        "hash": "0x3d286b93b8524a64aad1f60ef3d5ff1f52a4b3b59acfcfce6f499e5c0fd1509e"
    },
    "current_block_timestamp": 1646850196000,
    "genesis_block_identifier": {
        "index": 0,
        "hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"
    },
    "sync_status": {
        "current_index": 1423803,
        "target_index": 1423803
    },
    "peers": null
}

Respsone of /block

{
    "block": {
        "block_identifier": {
            "index": 0,
            "hash": "0x02adc9b449ff5f2467b8c674ece7ff9b21319d76c4ad62a67a70d552655927e5"
        },
        "parent_block_identifier": {
            "index": 0,
            "hash": "0x02adc9b449ff5f2467b8c674ece7ff9b21319d76c4ad62a67a70d552655927e5"
        },
        "timestamp": 0,
        "transactions": []
    }
}

The genesis hash from /network/status is 0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d but the genesis hash from /block is 0x02adc9b449ff5f2467b8c674ece7ff9b21319d76c4ad62a67a70d552655927e5. I think root cause is that we hardcode genesis hash for /network/status from here: https://github.com/ethereum-optimism/optimism/blob/develop/l2geth/params/config.go#L31, but it’s different from the live genesis hash

Preventing /block timeouts due to long-running tx traces

Debugging transactions using a noop tracer executes pretty quickly. For example, running the rosetta call_tracer on 0x47cecb28aeb8c029644b772e9e99e3305d06562fd53c239c2a20c278089231d7 takes several minutes to compute. Whereas, awith a noop call tracer, tracing completes in under 10 seconds.

This suggests that we could improve the call tracing somewhat via scripting to avoid timeouts. One idea I have in mind is splitting up the work of executing a call trace into multiple work units. Each work unit will trace a fraction of the execution. Once all work units are complete, they can be concatenated as a single large transaction trace. The idea here is each workunit is less likely to timeout individually. We may even be able to run multiple work units in parallel and exploit multiprocessing on l2geth. Of course, figuring out how to split up tracing is key.

Another idea is to offload VM execution log parsing to the rosetta server. Perhaps it'll be fast to transmit the entire unprocessed execution trace to be processed in optimized Go code, rather than doing it in the suboptimal javascript engine running on geth.

Expose Transaction Metadata Traces as Config Option

Description

Previously, we have explicitly ignored transaction traces to avoid excessive bloat in the returning Rosetta transaction.metadata.trace field.

We should be either (or both): structuring and returning transaction traces as well as adding a config flag for whether the trace field should be populated in the transaction metadata.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.