Git Product home page Git Product logo

go-ethlibs's Introduction

Infura

Website

Documentation - Not sure where to start? Check out our documentation.

Status - Think you're having issues? Check the Infura network status.

Community – Submit bugs, ask questions, provide feedback, and request features.

go-ethlibs's People

Contributors

antonydenyer avatar basgys avatar caroline-theotter avatar jeechoi avatar johnosullivan avatar meronym avatar ncocchiaro avatar ryanschneider avatar shazow avatar skmgoldin avatar timmyers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-ethlibs's Issues

node: IPC transport hangs on large responses

scanner := bufio.NewScanner(conn)

For example this code pointed to a yolov3x node never returns from BlockByNumber:

func main() {
	ctx := context.Background()
	url := "~/Library/Ethereum/yolo-v3/geth.ipc"
	client, err := node.NewClient(ctx, url)
	if err != nil {
		panic(err)
	}

	start := uint64(0x3ede)
	log.Printf("[WARN] start: %d", start)
	block, err := client.BlockByNumber(ctx, start, true)
	if err != nil {
		panic(err)
	} else {
		log.Printf("[INFO] block: %#v", *block)
	}
}

Haven't full debugged it but my guess is either the scanner fails and we don't handle the error correctly or the scanner hangs.

Making public on Monday, June 24, 2019

If anyone has objections or concerns, last chance to voice them here. :)

Things we'll want to do, as part of making the repo public:

  • Flip the public bit
  • Migrate over any in-progress PRs
  • Activate the public TravisCI
  • Update our internal uses of ethereum-interactions to go-ethlibs
  • Archive our internal ethereum-interactions fork

Cannot specify JSONRPC request Id

I can see some scenarios where the caller wants to provide an explicit JSONRPC request ID, but we currently don't expose that.

One solution would be in the GetBlockByNumber, etc. methods in the websocket.Connection interface took options as the last argument(s) (as varargs), and we provided a way to specify the request ID in those options. I can't think of any other options we'd want to implement right now, but could see us exposing options to configure the underlaying http or websocket requests (e.g. http headers or timeouts).

Support EIP-1559 once approved

Importantly we'll need to know how the RPC payloads change so we can deserialize e.g. eth_getTransactionByHash on these txs into eth.Transaction.

Enable CI for repo

I have some boilerplate travisci already defined, so Travis works.

Some people like circleci, which I'm open to as well.

Please enable integration with one of them. :) (Assigning to people with permissions)

EIP-2930 RLP Changes

We need to be able to decode EIP-2930 RLP-encoded transactions in eth.Transaction.FromRaw, as well as creating new signed EIP-2930 transactions in eth.Transaction.Sign and eth.Transaction.RLP.

More broadly, we need to be setup to handle EIP-2718 typed transactions in this code base.

EIP-2930 JSONRPC Changes

Related to #36 we will need to support adding accessList to eth.Transaction when .Type is eth.TransactionTypeAccessList.

eth.Block: EIP-4844 new Header fields

https://eips.ethereum.org/EIPS/eip-4844#header-extension

The current header encoding is extended with two new 64-bit unsigned integer fields:

  • blob_gas_used is the total amount of blob gas consumed by the transactions within the block.
  • excess_blob_gas is a running total of blob gas consumed in excess of the target, prior to the block. Blocks with above-target blob gas consumption increase this value, blocks with below-target blob gas consumption decrease it (bounded at 0).

Dencun: EIP-4788 Beacon Block Root accessible from EVM

I'm assuming that this will also show up in eth.Block since it's part of the RLP of the block header.

https://eips.ethereum.org/EIPS/eip-4788

execution-api tracking issue: ethereum/execution-apis#449

# curl https://rpc.dencun-devnet-8.ethpandaops.io/ -H 'Content-Type: application/json' -d '{"method":"eth_getBlockByNumber","params":["0x2a1cb", true],"id":1,"jsonrpc":"2.0"}' | jq . 
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "baseFeePerGas": "0x7",
    "blobGasUsed": "0x60000",
    "difficulty": "0x0",
    "excessBlobGas": "0x0",
    "extraData": "0x4e65746865726d696e64",
    "gasLimit": "0x1c9c380",
    "gasUsed": "0xf618",
    "hash": "0xfc2715ff196e23ae613ed6f837abd9035329a720a1f4e8dce3b0694c867ba052",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "miner": "0xf97e180c050e5ab072211ad2c213eb5aee4df134",
    "mixHash": "0xfe22e918a42ab40a176372da0352271d7a8d206af1f0f81b4ae24e0366b294e1",
    "nonce": "0x0000000000000000",
    "number": "0x2a1cb",
+    "parentBeaconBlockRoot": "0x3e75ca617f5191780dc90f5054d192c29167813ca0e38b84b26c30ae8886998b",
    "parentHash": "0x0efbec3f110f71016eabe050984405a0f5b5bf7d4c653aaeb876a2a83d7e2a95",
    "receiptsRoot": "0x9af165447e5b3193e9ac8389418648ee6d6cb1d37459fe65cfc245fc358721bd",
    "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    "size": "0x437",
    "stateRoot": "0x4662ac8f239eb6b068a89d82db55fbd699bc883a43812a6ced13976f91c30b71",
    "timestamp": "0x65004480",
    "totalDifficulty": "0x1",
    "transactions": [
      {
        "blockHash": "0xfc2715ff196e23ae613ed6f837abd9035329a720a1f4e8dce3b0694c867ba052",
        "blockNumber": "0x2a1cb",
        "from": "0xad01b55d7c3448b8899862eb335fbb17075d8de2",
        "gas": "0x5208",
        "gasPrice": "0x1d1a94a201c",
        "maxFeePerGas": "0x1d1a94a201c",
        "maxPriorityFeePerGas": "0x1d1a94a201c",
        "maxFeePerBlobGas": "0x3e8",
        "hash": "0x5ceec39b631763ae0b45a8fb55c373f38b8fab308336ca1dc90ecd2b3cf06d00",
        "input": "0x",
        "nonce": "0x1b483",
        "to": "0x000000000000000000000000000000000000f1c1",
        "transactionIndex": "0x0",
        "value": "0x0",
        "type": "0x3",
        "accessList": [],
        "chainId": "0x1a1f0ff42",
        "blobVersionedHashes": [
          "0x01a128c46fc61395706686d6284f83c6c86dfc15769b9363171ea9d8566e6e76"
        ],
        "v": "0x0",
        "r": "0x343c6239323a81ef61293cb4a4d37b6df47fbf68114adb5dd41581151a077da1",
        "s": "0x48c21f6872feaf181d37cc4f9bbb356d3f10b352ceb38d1c3b190d749f95a11b",
        "yParity": "0x0"
      },
      {
        "blockHash": "0xfc2715ff196e23ae613ed6f837abd9035329a720a1f4e8dce3b0694c867ba052",
        "blockNumber": "0x2a1cb",
        "from": "0xad01b55d7c3448b8899862eb335fbb17075d8de2",
        "gas": "0x5208",
        "gasPrice": "0x1d1a94a201c",
        "maxFeePerGas": "0x1d1a94a201c",
        "maxPriorityFeePerGas": "0x1d1a94a201c",
        "maxFeePerBlobGas": "0x3e8",
        "hash": "0xed2587d8c4cccd09bc2c0ac50dd0bc596177b3eef2624957114fd8c075ff71f7",
        "input": "0x",
        "nonce": "0x1b484",
        "to": "0x000000000000000000000000000000000000f1c1",
        "transactionIndex": "0x1",
        "value": "0x0",
        "type": "0x3",
        "accessList": [],
        "chainId": "0x1a1f0ff42",
        "blobVersionedHashes": [
          "0x01f79951ba3a9c2a617bece3d0a355a32c21d2502b5d1245dcef954c1e97e301"
        ],
        "v": "0x0",
        "r": "0x1bffc7230fbf4675f4050ddfc09a0ea8957f6ed839f2a6aafe8d60ba3704f0a6",
        "s": "0x42cf198e98b71eb47ab04b3115bb96de8ca8ee36ed92990efc258a0f80f4fa98",
        "yParity": "0x0"
      },
      {
        "blockHash": "0xfc2715ff196e23ae613ed6f837abd9035329a720a1f4e8dce3b0694c867ba052",
        "blockNumber": "0x2a1cb",
        "from": "0xad01b55d7c3448b8899862eb335fbb17075d8de2",
        "gas": "0x5208",
        "gasPrice": "0x1d1a94a201c",
        "maxFeePerGas": "0x1d1a94a201c",
        "maxPriorityFeePerGas": "0x1d1a94a201c",
        "maxFeePerBlobGas": "0x3e8",
        "hash": "0x8b6536d1dacf8f2e4d95bb8b2ed05067b96b27a8b3abe004d29a712cafdf712a",
        "input": "0x",
        "nonce": "0x1b485",
        "to": "0x000000000000000000000000000000000000f1c1",
        "transactionIndex": "0x2",
        "value": "0x0",
        "type": "0x3",
        "accessList": [],
        "chainId": "0x1a1f0ff42",
        "blobVersionedHashes": [
          "0x017c8f97daa97f4089502ff59f05e40217f2644a9462588189c5ca4e24221d08"
        ],
        "v": "0x0",
        "r": "0x8146d689e09836b87d4fe551cc590c83f6c96029f8def92686bfd1859fed4704",
        "s": "0x4357b7bc331e23381841b6afc98cf4bd322cd6d90dd9f2f1af78b593611c7251",
        "yParity": "0x0"
      }
    ],
    "transactionsRoot": "0xc5f62b8c7d89e8dce123a91ebe4fd2428f9960f13316e99ff4a8754bd8ee6fa8",
    "uncles": [],
    "withdrawals": [],
    "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
  }
}

Don't proxy/change request.ID in looping transport layer unless necessary

I mentioned this as a comment in #18, but ideally we don't change the outgoing request ID in the websocket/IPC layer unless strictly necessary. However, to do this either the clients need to ensure that each concurrent request has a unique ID, or we need to serialize requests w/ the same ID, which requires a fair amount more logic in loop.go.

A good compromise after #7 is fixed is that if the context has no request ID, then generate a unique one, if the context has an ID, first see if there's already a request w/ that ID in flight, in which case we need to wait for that previous request to complete before dispatching the next one.

Thus, by default, the client would behave as it does now: each request gets it's own auto-generated unique ID. If a client wants to both control IDs and dispatch multiple requests concurrently, they need to supply unique IDs to each request, which seems like a reasonable trade-off.

Consider a request builder and response parser design

Thinking about #7 more, and my general unhappiness with the verbosity of the node.Client interface, it might make more sense to remove all the RPC-specific methods from that interface, and instead offer them as some sort of request builder and response parser pair.

So instead of:

block, err := client.BlockByHash(ctx, hash, true, node.WithRequestID(jsonrpc.ID{Str: "foo"}))

One would instead use:

block, err := pkg.NewRequest().BlockByHash(hash, true).WithStringID("foo").Send(client).Response().AsBlock()

Though not sure where said builders would live (e.g. what the actual name of pkg would be).

This pattern is used in a couple places to varying effectiveness, namely go-redis and the golang AWS SDK v2. Anyways, just a rough idea for now, but the main advantage is that it separates the definition of new RPCs from node.Client, which just needs to implement .Request and .Subscribe which makes implementing new virtual clients and or mocks much cleaner.

Add `eth.BlockSpecifier` for EIP-1898 Support

Now that Infura is predominately using geth 1.9.x for our backend nodes, I'd like to consider exposing EIP-1898 support, and adding it here seems like a good first step.

I'm picturing something like:

type Tag string //also update eth.BlockNumberOrTag to use this

type BlockSpecifier struct {
  Number *Quantity 
  Tag *Tag
  Hash *Hash
  RequireCanonical *bool
  Raw bool
}

And custom JSON (un)marshal routines that can handle the various cases:

  • raw Quantity or Hash
  • tags ("latest", "pending", etc.)
  • the JSON format in the EIP itself

.Raw can be used when constructing a BlockSpecifier in code to control how it'll be marshaled, if true then the specifier would be marshaled as a simple string instead of a JSON object (e.g. { Tag: Tag("latest") } would be just "latest" and not { "blockNumber": "latest" }.

eth.Transaction: EIP-4844 Blob Txs (type 0x3)

https://eips.ethereum.org/EIPS/eip-4844#blob-transaction

We introduce a new EIP-2718 transaction, “blob transaction”, where the TransactionType is BLOB_TX_TYPE (0x03) and the TransactionPayload is the RLP serialization of the following TransactionPayloadBody:

[chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, access_list, max_fee_per_blob_gas, blob_versioned_hashes, y_parity, r, s]

The field to deviates slightly from the semantics with the exception that it MUST NOT be nil and therefore must always represent a 20-byte address. This means that blob transactions cannot have the form of a create transaction.

The field max_fee_per_blob_gas is a uint256 and the field blob_versioned_hashes represents a list of hash outputs from kzg_to_versioned_hash.

The EIP-2718 ReceiptPayload for this transaction is rlp([status, cumulative_transaction_gas_used, logs_bloom, logs]).

Use TextMarshaler interface to simplify eth.Address and eth.Data

Not directly related to #61, but we could also simplify with the TextMarshaler and TextUnmarshaler interface, so we don't have to deal with json.Marshal/Unmarshal in our functions for the base64 encoding/decoding.

Those text marshalers would focus solely on validating and returning a canonical representation of an address, which would be compatible with other encoding formats.

Before

func (a *Address) UnmarshalJSON(data []byte) error {
	// We'll keep the checksummed string in memory so we can use it for internal representations
	str, err := unmarshalHex(data, 20, "data")
	str = ToChecksumAddress(str)
	if err != nil {
		return err
	}
	*a = Address(str)
	return nil
}

func (a Address) MarshalJSON() ([]byte, error) {
	// Seems like geth and parity both return the lower-cased string rather than the checksummed one
	s := strings.ToLower(string(a))
	return json.Marshal(&s)
}

After

func (a *Address) UnmarshalText(text []byte) error {
	str, err := validateHex(string(text), 20, "data")
	if err != nil {
		return err
	}
	str = ToChecksumAddress(str)
	*a = Address(str)
	return nil
}

func (a Address) MarshalText() ([]byte, error) {
	return bytes.ToLower([]byte(a)), nil
}

Originally posted by @basgys in #61 (comment)

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.