0.1.3 • Published 3 years ago

@eth-optimism/data-transport-layer v0.1.3

Weekly downloads
43
License
MIT
Repository
-
Last release
3 years ago

@eth-optimism/data-transport-layer

What is this?

The Optimistic Ethereum Data Transport Layer is a long-running software service (written in TypeScript) designed to reliably index Optimistic Ethereum transaction data from Layer 1 (Ethereum). Specifically, this service indexes:

  • Transactions that have been enqueued for submission to the CanonicalTransactionChain via enqueue.
  • Transactions that have been included in the CanonicalTransactionChain via appendQueueBatch or appendSequencerBatch.
  • State roots (transaction results) that have been published to the StateCommitmentChain via appendStateBatch.

How does it work?

We run two sub-services, the L1IngestionService and the L1TransportServer. The L1IngestionService is responsible for querying for the various events and transaction data necessary to accurately index information from our Layer 1 (Ethereum) smart contracts. The L1TransportServer simply provides an API for accessing this information.

Getting started

Configuration

See an example config at .env.example; copy into a .env file before running.

L1_TRANSPORT__L1_RPC_ENDPOINT can be the JSON RPC endpoint of any L1 Ethereum node. L1_TRANSPORT__ADDRESS_MANAGER should be the contract addresss of the Address Manager on the corresponding network; find their values in the Regenesis repo.

Building and usage

After cloning and switching to the repository, install dependencies:

$ yarn

Use the following commands to build, use, test, and lint:

$ yarn build
$ yarn start
$ yarn test
$ yarn lint

Configuration

We're using dotenv for our configuration. Copy .env.example into .env, feel free to modify it. Here's the list of environment variables you can change:

VariableDefaultDescription
DATA_TRANSPORT_LAYER__DB_PATH./dbPath to the database for this service.
DATA_TRANSPORT_LAYER__ADDRESS_MANAGER-Address of the AddressManager contract on L1. See regenesis repo to find this address for mainnet or kovan.
DATA_TRANSPORT_LAYER__POLLING_INTERVAL5000Period of time between execution loops.
DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORSfalseIf true, will catch all errors without throwing.
DATA_TRANSPORT_LAYER__CONFIRMATIONS12Number of confirmations to wait before accepting transactions as "canonical".
DATA_TRANSPORT_LAYER__SERVER_HOSTNAMElocalhostHost to run the API on.
DATA_TRANSPORT_LAYER__SERVER_PORT7878Port to run the API on.
DATA_TRANSPORT_LAYER__SYNC_FROM_L1trueWhether or not to sync from L1.
DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT-RPC endpoint for an L1 node.
DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL2000Logs to sync per polling interval.
DATA_TRANSPORT_LAYER__SYNC_FROM_L2falseWhether or not to sync from L2.
DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT-RPC endpoint for an L2 node.
DATA_TRANSPORT_LAYER__TRANSACTIONS_PER_POLLING_INTERVAL1000Number of L2 transactions to query per polling interval.
DATA_TRANSPORT_LAYER__L2_CHAIN_ID-L2 chain ID.
DATA_TRANSPORT_LAYER__LEGACY_SEQUENCER_COMPATIBILITYfalseWhether or not to enable "legacy" sequencer sync (without the custom eth_getBlockRange endpoint)

HTTP API

This section describes the HTTP API for accessing indexed Layer 1 data.

Latest Ethereum Block Context

Request

GET /eth/context/latest

Response

{
    "blockNumber": number,
    "timestamp": number
}

Enqueue by Index

Request

GET /enqueue/index/{index: number}

Response

{
  "index": number,
  "target": string,
  "data": string,
  "gasLimit": number,
  "origin": string,
  "blockNumber": number,
  "timestamp": number
}

Transaction by Index

Request

GET /transaction/index/{index: number}

Response

{
    "transaction": {
        "index": number,
        "batchIndex": number,
        "data": string,
        "blockNumber": number,
        "timestamp": number,
        "gasLimit": number,
        "target": string,
        "origin": string,
        "queueOrigin": string,
        "type": string | null,
        "decoded": {
            "sig": {
                "r": string,
                "s": string,
                "v": string
            },
            "gasLimit": number,
            "gasPrice": number,
            "nonce": number,
            "target": string,
            "data": string
        } | null,
        "queueIndex": number | null,
    },
    
    "batch": {
        "index": number,
        "blockNumber": number,
        "timestamp": number,
        "submitter": string,
        "size": number,
        "root": string,
        "prevTotalElements": number,
        "extraData": string
    }
}

Transaction Batch by Index

Request

GET /batch/transaction/index/{index: number}

Response

{
    "batch": {
        "index": number,
        "blockNumber": number,
        "timestamp": number,
        "submitter": string,
        "size": number,
        "root": string,
        "prevTotalElements": number,
        "extraData": string
    },
    
    "transactions": [
      {
        "index": number,
        "batchIndex": number,
        "data": string,
        "blockNumber": number,
        "timestamp": number,
        "gasLimit": number,
        "target": string,
        "origin": string,
        "queueOrigin": string,
        "type": string | null,
        "decoded": {
            "sig": {
                "r": string,
                "s": string,
                "v": string
            },
            "gasLimit": number,
            "gasPrice": number,
            "nonce": number,
            "target": string,
            "data": string
        } | null,
        "queueIndex": number | null,
      }
    ]
}

State Root by Index

Request

GET /stateroot/index/{index: number}

Response

{
    "stateRoot": {
        "index": number,
        "batchIndex": number,
        "value": string
    },

    "batch": {
        "index": number,
        "blockNumber": number,
        "timestamp": number,
        "submitter": string,
        "size": number,
        "root": string,
        "prevTotalElements": number,
        "extraData": string
    },
}

State Root Batch by Index

Request

GET /batch/stateroot/index/{index: number}

Response

{
    "batch": {
        "index": number,
        "blockNumber": number,
        "timestamp": number,
        "submitter": string,
        "size": number,
        "root": string,
        "prevTotalElements": number,
        "extraData": string
    },
    
    "stateRoots": [
        {
            "index": number,
            "batchIndex": number,
            "value": string
        }
    ]
}