Goals
Contributors should aim to achieve the following goals when making design decisions:
- Loosely coupled components: Components should require as little knowledge of the definitions of other components as possible. This reduces dependencies between PRs and encourages contributors to work in parallel. It also improves extensibility of the code as new features like sharding and libp2p support are added.
- Easily tested: The design should make testing of individual components as easy as possible. This goes hand in hand with the previous goal of loose coupling.
- Readable code: More readable code should encourage more contributions from the community and help with bug fixing.
- Well documented: Similar to above, this will help both contributors and users of the project.
The current design tries to achieve the goals of loose coupling and ease of testing by using an event-driven architecture where possible. Readability is improved by using features of JavaScript ES6 such as classes, async/await, promises, arrow functions, for...of, template literals and destructuring assignment among others. Shorter names are used when possible and long functions are broken up into smaller helpers, along with TypeDoc annotations for most methods and parameters. Documentation is auto-generated from TypeDoc comments and many examples of usage are provided (TO DO).
We will now briefly describe the directory structure and main components of the Ethereumjs client to help contributors better understand how the project is organized.
Directory structure
/bin
Contains the CLI script for theethereumjs
command./docs
Contains auto-generated API docs./lib/blockchain
Contains theChain
class./lib/net
Contains all of the network layer classes includingPeer
,Protocol
and its subclasses,Server
and its subclasses, andPeerPool
./lib/service
Contains the main Ethereum services (FullEthereumService
andLightEthereumService
)./lib/rpc
Contains the RPC server (optionally) embedded in the client./lib/sync
Contains the various chain synchronizers andFetcher
helpers./lib/miner
Contains the miner module that can build new blocks on top of the chain./test
Contains test cases, testing helper functions, mocks and test data.
Components
Chain
[In Progress] This class represents the blockchain and is a wrapper around@ethereumjs/blockchain
. It handles creation of the data directory, provides basic blockchain operations and maintains an updated current state of the blockchain, including current height, total difficulty, and latest block.Server
This class represents a server that discovers new peers and handles incoming and dropped connections. When a new peer connects, theServer
class will negotiate protocols and emit aconnected
event with a newPeer
instance. The peer will have properties corresponding to each protocol. For example, if a new peer understands theeth
protocol, it will contain aneth
property that provides alleth
protocol methods (for example:peer.eth.getBlockHeaders()
)RlpxServer
[In Progress] Subclass ofServer
that implements thedevp2p/rlpx
transport.Libp2pServer
[In Progress] Subclass ofServer
that implements thelibp2p
transport.
Peer
Represents a network peer. Instances ofPeer
are generated by theServer
subclasses and contain instances of supported protocol classes as properties. Instances ofPeer
subclasses can also be used to directly connect to other nodes via theconnect()
method. Peers emitmessage
events whenever a new message is received using any of the supported protocols.RlpxPeer
[In Progress] Subclass ofPeer
that implements thedevp2p/rlpx
transport.Libp2pPeer
[In Progress] Subclass ofPeer
that implements thelibp2p
transport.
Protocol
[In Progress] This class and subclasses provide a user-friendly wrapper around the low level ethereum protocolseth/66
andles/4
. Subclasses must define the messages provided by the protocol.EthProtocol
[In Progress] Implementseth/66
protocol.LesProtocol
[In Progress] Implementsles/4
protocol.
PeerPool
[In Progress] Represents a pool of network peers.PeerPool
instances emitadded
andremoved
events when new peers are added and removed and also emit themessage
event whenever any of the peers in the pool emit a message. EachService
has an associatedPeerPool
and they are used primarily bySynchronizer
s to help with blockchain synchronization.Synchronizer
Subclasses of this class implements a specific blockchain synchronization strategy. They also make use of subclasses of theFetcher
class that help fetch headers and bodies from pool peers. The fetchers internally make use of streams to handle things like queuing and backpressure.FullSynchronizer
[In Progress] Implements full syncing of the blockchainLightSynchronizer
[In Progress] Implements light syncing of the blockchain
Handler
Subclasses of this class implements a protocol message handler. Handlers respond to incoming requests from peers.EthHandler
[In Progress] Handles incoming ETH requestsLesHandler
[In Progress] Handles incoming LES requests
Service
Subclasses ofService
will implement specific functionality of aClient
. For example, theEthereumService
subclasses will synchronize the blockchain using the full or light sync protocols. Each service must specify which protocols it needs and define astart()
andstop()
function.FullEthereumService
[In Progress] Implementation of ethereum full sync.LightEthereumService
[In Progress] Implementation of ethereum light sync.
Client
[In Progress] Represents the top-level ethereum client, and is responsible for managing the lifecycle of included services.RPCManager
[In Progress] Implements an embedded JSON-RPC server to handle incoming RPC requests.