Git Product home page Git Product logo

ethparser-go's Introduction

Ethereum Parser

I had a lot of fun working on this project. My approach was to create a parser that could be easily extended with new repositories and ethereum clients. Most of the code is tested with unit tests and I tried to keep it as clean as possible. The most interesting parts are commented in the code so that reviewers can understand my thought process.

Packages

I created different packages to have a separation of concerns and I used the internal package for the components that I don't want to expose to the public.

  • internal

    • e2e e2e test suite.
    • ethereum logic to interact with the needed methods of the ethereum client. It relies on a generic RPCClient interface that can be implemented by any client. Inside the package, there are some utility functions to deal with ethereum hex numbers.
    • jsonrpc logic to interact with any JSON-RPC server. It is used by my ethereum client. Inside, there are some transport-layer types. The HTTPRequestBuilder is a really simple builder, and it could be replaced with a more generic one.
    • storage implementation of an in-memory concurrency safe TransactionsRepository and AddressesRepository.
    • mock mocks for the tests.
    • testdata test data used by the tests. Here I used go:embed to simply load a json file with real ethereum block data.
  • parser logic to parse and observe the ethereum blocks and transactions. The parser accepts different options to enhance the default implementation with more sophisticated components.

  • types types used by the main components.

Usage

The default parser can be initialized in the following way:

ctx := context.Background()
log := slog.New(slog.NewJSONHandler(os.Stdout, nil))

p, err := parser.NewParser(
  "https://cloudflare-eth.com",
  log,
)
// handle the error

err = p.Run(ctx)

The parser can be extended with different components by passing options to the constructor. For example, to use a different repository, you can pass the WithTransactionsRepository option:

repo := NewTransactionsRepository()

p, err := parser.NewParser(
  "https://cloudflare-eth.com",
  log,
  parser.WithTransactionsRepository(repo),
)

All the available options are defined in the parser/options.go file.

Testing

All the unit tests can be run with the following command:

make test

To display the tests coverage in an interactive html page, run the following command:

make display_coverage

In addition, I created a simple e2e test suite that runs the parser with a real ethereum client to show that it works as expected. The test is located in the tests/e2e folder. Usually I would run this with a docker-compose file that would start an ethereum emulator, but wanted to keep it simple for this project. To start the test, just run the following command:

make test_e2e

Linting

To lint the code, run the following command:

make lint

To fix linting issues, run the following command:

make fmt

CI

I added a simple GitHub Actions workflow that runs the tests and linter on every pull request.

Considerations

type Parser interface {
    GetCurrentBlock() int
    Subscribe(address string) bool
    GetTransactions(address string) []Transaction
}

During the implementation, I thought about some improvements that could be made to the public interface of the parser.

  • context is not being used in the parser methods. I would definitely add it in a real-world scenario to allow the caller to cancel the operation and pass trace information.
  • The Subscribe and GetTransactions methods could be improved to return an error. This way, the caller could know if the subscription failed and why (really useful it there is a cache or a network error).
  • The parser doesn't have a method to start parsing. I assumed that it would start parsing when the parser is created. I really don't like this approach this is why I added a Run method to the parser. This way, the caller can start the parser and control it with a context.
  • The GetCurrentBlock returns an int. I would change it to return an uint64 to avoid possible future overflow issues.

ethparser-go's People

Contributors

ilkamo avatar

Watchers

 avatar

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.