Skip to content

Commit ae225cd

Browse files
committed
even more docs, including Docker
1 parent 80580c8 commit ae225cd

File tree

10 files changed

+662
-14
lines changed

10 files changed

+662
-14
lines changed

book/src/SUMMARY.md

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,25 @@
8787
- [Releasing modules](releasing_modules.md)
8888
---
8989

90-
- [Lib](libv2/overview.md)
91-
- [Concurrency](libv2/concurrency.md)
92-
- [Client](libv2/client.md)
90+
- [Lib](./libv2/overview.md)
91+
- [Concurrency](./libv2/concurrency.md)
92+
- [Client](./libv2/client.md)
9393
- [Anvil]()
94-
- [AWS Secrets Manager](libv2/client/aws_secrets_manager.md)
95-
- [Github](libv2/client/github.md)
96-
- [Kafka](libv2/client/kafka.md)
97-
- [Loki](libv2/client/loki.md)
98-
- [MockServer](libv2/client/mockserver.md)
99-
- [Postgres](libv2/client/postgres.md)
100-
- [Prometheus](libv2/client/prometheus.md)
101-
- [Logging](libv2/logging.md)
94+
- [AWS Secrets Manager](./libv2/client/aws_secrets_manager.md)
95+
- [Github](./libv2/client/github.md)
96+
- [Grafana]()
97+
- [Kafka](./libv2/client/kafka.md)
98+
- [Loki](./libv2/client/loki.md)
99+
- [MockServer](./libv2/client/mockserver.md)
100+
- [Postgres](./libv2/client/postgres.md)
101+
- [Prometheus](./libv2/client/prometheus.md)
102+
- [Docker](./docker/overview.md)
103+
- [Blockchain nodes](./docker/blockchain_nodes.md)
104+
- [Chainlink ecosystem](./docker/chainlink_ecosystem.md)
105+
- [Third party apps]()
106+
- [Test helpers](./docker/test_helpers.md)
107+
108+
- [Logging](./libv2/logging.md)
102109

103110
---
104111
- [Lib (*Deprecated*)](lib.md)
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
# Blockchain nodes
2+
3+
It is highly advised that if you did decide to play around with these Docker containers that you use an existing Ethereum enviroment builder
4+
instead of trying to put all the pieces together. That's especially important for Proof-Of-Stake networks, where the setup is a multi-stage
5+
operation that needs to be executed in specific order and where multiple containers need access to the same (or shared) state.
6+
7+
By default, each of supported clients has a default image version that's defined [here](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/lib/docker/ethereum/images.go).
8+
All of them apart from Reth, come in two flavours: one that is a Proof-Of-Stake (Ethereum 2.0) network and another that's a Proof-Of-Work/Authority (Ethereum 1.0). Reth has only the former
9+
since the latter was never implemented by its creators.
10+
11+
All of these epehemeral networks are using a grossly simplified configuration that is composed of a single blockchain node. Technically that's also true, in case of PoS networks,
12+
even though they are running three containers:
13+
* execution layer container
14+
* consensus layer container
15+
* validator
16+
17+
> [!NOTE]
18+
> We use our own fork of [Ethereum Genesis Generator](https://github.com/ethpandaops/ethereum-genesis-generator) to
19+
> create genesis files both for PoW/PoA and PoS Ethereum networks.
20+
21+
## Execution Layer
22+
Following execution layers are available
23+
* Besu
24+
* Erigon
25+
* Geth
26+
* Nethermind
27+
* Reth
28+
29+
## Consensus Layer
30+
Only one consensus client is available: Prysm.
31+
32+
# Quick start
33+
The simplest of starting a new Ethereum network is by specifying only the execution layer:
34+
```go
35+
builder := NewEthereumNetworkBuilder()
36+
cfg, err := builder.
37+
WithExecutionLayer(types.ExecutionLayer_Nethermind).
38+
Build()
39+
if err != nil {
40+
panic(err)
41+
}
42+
43+
net, rpcs, err := cfg.Start()
44+
if err != nil {
45+
panic(err)
46+
}
47+
```
48+
49+
If no Ethereum version is specified, Ethereum 1.0 (pre-Merge) will be used.
50+
51+
# Ethereum 2 network
52+
To start Ethereum 2.0 network you need to pass one more parameter to the builder:
53+
```go
54+
builder := NewEthereumNetworkBuilder()
55+
cfg, err := builder.
56+
// notice the new parameter
57+
WithEthereumVersion(config_types.EthereumVersion_Eth2).
58+
WithExecutionLayer(config_types.ExecutionLayer_Geth).
59+
Build()
60+
if err != nil {
61+
panic(err)
62+
}
63+
64+
net, rpcs, err := cfg.Start()
65+
if err != nil {
66+
panic(err)
67+
}
68+
```
69+
70+
> [!NOTE]
71+
> It takes significantly longer to boot up an Ethereum 2.0 network due to number of
72+
> containers involved. 1 minute long wait times are not unheard of, so if startup
73+
> speed is crucial think if Ethereum 1.0 is good enough for your use case.
74+
75+
# Custom docker images
76+
If you don't want to use default image versions you can pass custom ones in the following manner:
77+
```go
78+
builder := NewEthereumNetworkBuilder()
79+
cfg, err := builder.
80+
WithCustomDockerImages(map[config.ContainerType]string{
81+
config.ContainerType_ExecutionLayer: "ethereum/client-go:v1.15.0",
82+
}).
83+
Build()
84+
if err != nil {
85+
panic(err)
86+
}
87+
88+
net, rpcs, err := cfg.Start()
89+
if err != nil {
90+
panic(err)
91+
}
92+
```
93+
Where available container types are:
94+
```go
95+
const (
96+
ContainerType_ExecutionLayer ContainerType = "execution_layer"
97+
ContainerType_ConsensusLayer ContainerType = "consensus_layer"
98+
ContainerType_ConsensusValidator ContainerType = "consensus_validator"
99+
ContainerType_GenesisGenerator ContainerType = "genesis_generator"
100+
ContainerType_ValKeysGenerator ContainerType = "val_keys_generator"
101+
)
102+
```
103+
When passing custom docker image for execution layer you don't need to use neither `WithEthereumVersion()` nor `WithExecutionLayer()` functions
104+
as we will get these from the Docker image.
105+
106+
> [!NOTE]
107+
> There are two useful "synthetic" Docker tags you can use with custom images:
108+
> - `latest_available` - which represents the latest release (including pre-releases)
109+
> - `latest_stable` - which represents latest **stable** release
110+
111+
# Existing Docker network(s)
112+
By default, the chain will be started on a new Docker network with random name. If you want it to connect to existing one instead, use the following option:
113+
```go
114+
builder := NewEthereumNetworkBuilder()
115+
cfg, err := builder.
116+
WithExecutionLayer(types.ExecutionLayer_Nethermind).
117+
WithDockerNetworks([]string{"my-existing-network"}).
118+
Build()
119+
if err != nil {
120+
panic(err)
121+
}
122+
```
123+
124+
# Chain customisation
125+
Below you will find a description of easily customisable parameters of the chain or its startup.
126+
127+
## Slots per epoch and seconds per slot (Ethereum 2.0 only)
128+
These parameters control how fast epochs progress.
129+
130+
`Seconds per slot` represents the number of seconds that validator have to vote on blocks.
131+
The lower the value the faster the epoch finalisation. If it's too low, validators will not be
132+
able to vote and no new blocks will be produced. Minimum allowed value is `3`.
133+
134+
`Slots per epoch` represent the number of voting runds per epoch. The lower the number, the faster
135+
the finalization. Minimum allowed value is `2.`
136+
137+
## ChainID
138+
Can be anything as long as it's an integer.
139+
140+
## Addresses to fund
141+
Addresses that will be funded with `9000000000000000000000000000 wei` in the genesis.
142+
143+
## Hard Forks (Ethereum 2.0 only)
144+
Map of hard fork name to epoch, in which the fork should happen. Has to be `> 0`. It's useful for testing
145+
how software will behave during the fork. Currently, the only fork that's supported is `Deneb`, but it can
146+
only be used with Docker images that belong to "pre-Deneb times" and running on `Shanghai` version of Ethereum 2.0
147+
(so pretty old versions). For the latest images there are no supported future forks as of time of this documentation
148+
creation there were no dates set for any of the incoming forks (which means none of them is supported by neither
149+
execution nor consensus layer clients).
150+
151+
## Validator count (Ethereum 2.0 only)
152+
Number of validators to run. `4` is a minimum allowed.
153+
154+
## Genesis Delay (Ethereum 2.0 only)
155+
Extra delay added to genesis block timestamp to be sure that both layers are up and running before it happens. Increasing it could be
156+
useful in case of running on very slow system.
157+
158+
## Default values
159+
Default chain config comes with the following values:
160+
```toml
161+
seconds_per_slot=12
162+
slots_per_epoch=6
163+
genesis_delay=15
164+
validator_count=8
165+
chain_id=1337
166+
addresses_to_fund=["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]
167+
```
168+
169+
# Other useful options
170+
## Blockchain node log level
171+
By default, all blockchain nodes use `info` log level, but you can change that with the following option:
172+
```go
173+
builder := NewEthereumNetworkBuilder()
174+
cfg, err := builder.
175+
WithCustomDockerImages(map[config.ContainerType]string{
176+
config.ContainerType_ExecutionLayer: "ethereum/client-go:v1.15.0",
177+
}).
178+
WithNodeLogLevel("debug").
179+
Build()
180+
if err != nil {
181+
panic(err)
182+
}
183+
```
184+
This configuration is applied only to execution layer nodes. Following values are supported:
185+
* `trace`
186+
* `debug`
187+
* `info`
188+
* `warn`
189+
* `error`
190+
191+
## Waiting for first epoch finalization (Ethereum 2.0 only)
192+
In case you want the network to wait until first epoch has been finalised you can use the following option:
193+
```go
194+
builder := NewEthereumNetworkBuilder()
195+
cfg, err := builder.
196+
WithCustomDockerImages(map[config.ContainerType]string{
197+
config.ContainerType_ExecutionLayer: "ethereum/client-go:v1.15.0",
198+
}).
199+
WithWaitingForFinalization().
200+
Build()
201+
if err != nil {
202+
panic(err)
203+
}
204+
```
205+
206+
# Accessing containers from inside and outside of the Docker network
207+
Function that starts the environment returns an error or two values:
208+
* instance of `blockchain.Network` that can be used to start our test clients
209+
* instance of `test_env.RpcProvider` that has a list of useful endpoints
210+
211+
These endpoints come in two flavours:
212+
* public (accessible from other Docker networks and the host machine)
213+
* private (accessible only from inside the same Docker network)
214+
215+
And are the HTTP and WS endpoints of the execution layer clients, ones which the Chainlink Node
216+
needs to communicate with. Beacon Chain (consensus layer) endpoints are not exposed.
217+
218+
If you're wondering which one to use, the usual case would be:
219+
* public for the Ethereum Client that will interact with the chain, deploy contracts, etc.
220+
* private for the Chainlink Node if it uses the same Docker network as the chain, public otherwise
221+
222+
# Ethereum 2.0 container creation sequence
223+
Since the sequence of container creation and interaction for Ethereum 2.0 is much more complicated
224+
than for Ethereum 1.0 (where we only need to start a single container) below you will find a sequence
225+
diagram that explains it in more detail:
226+
227+
```mermaid
228+
---
229+
title: Ethereum 2.0 container creation sequence
230+
---
231+
sequenceDiagram
232+
participant Host Machine
233+
participant Validators Keys Generator
234+
participant Genesis Generator
235+
participant Execution Layer (e.g. Besu or Geth)
236+
participant Consensus Layer (Prysm Beacon Chain)
237+
participant Consensus Layer (Prysm Validator)
238+
participant After Genesis Helper
239+
participant User
240+
Validators Keys Generator->>Host Machine: Generate new validators keys<br/> and save them to on the host
241+
Genesis Generator->>Host Machine: Generate Ethereum 1.0 and Ethereum 2.0 genesis files<br/> and save them on the host
242+
Host Machine->>Execution Layer (e.g. Besu or Geth): Read Ehtereum 1.0 genesis and start
243+
Host Machine->>Consensus Layer (Prysm Beacon Chain): Read Ehtereum 2.0 genesis and start
244+
Consensus Layer (Prysm Beacon Chain)->>Execution Layer (e.g. Besu or Geth): Conntect and start<br/> following the chain
245+
Host Machine->>Consensus Layer (Prysm Validator): Read validator keys and start
246+
Consensus Layer (Prysm Validator)->>Consensus Layer (Prysm Beacon Chain): Connect and start voting on blocks
247+
loop observe chain
248+
After Genesis Helper->>Execution Layer (e.g. Besu or Geth): Wait until new blocks are produced
249+
end
250+
After Genesis Helper->>User: Allow to proceed<br/> and interact with the chain
251+
```
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Chainlink ecosystem
2+
3+
Currently, only one application has a wrapper that lives in this framework: the Job Distributor.
4+
Chainlink Node wrapper can be found in the [chainlink repository](https://github.com/smartcontractkit/chainlink/blob/develop/integration-tests/docker/test_env/cl_node.go).
5+
6+
## Job Distributor
7+
JD is a component for a centralized creation and management of jobs executed by Chainlink Nodes. It's a single point of entry
8+
that frees you from having to setup each job separately on each node from the DON.
9+
10+
It requires a Postgres DB instance, which can also be started using the CTF:
11+
```go
12+
pg, err := test_env.NewPostgresDb(
13+
[]string{network.Name},
14+
test_env.WithPostgresDbName("jd-db"),
15+
test_env.WithPostgresImageVersion("14.1"))
16+
if err != nil {
17+
panic(err)
18+
}
19+
err = pg.StartContainer()
20+
if err != nil {
21+
panic(err)
22+
}
23+
```
24+
25+
Then all you need to do, to start a new instance is:
26+
```go
27+
jd := New([]string{network.Name},
28+
//replace with actual image
29+
WithImage("localhost:5001/jd"),
30+
WithVersion("latest"),
31+
WithDBURL(pg.InternalURL.String()),
32+
)
33+
34+
err = jd.StartContainer()
35+
if err != nil {
36+
panic(err)
37+
}
38+
```
39+
40+
Once you have JD started you can create a new GRPC connection and start interacting with it
41+
to register DON nodes, create jobs, etc:
42+
```go
43+
conn, cErr := grpc.NewClient(jd.Grpc, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}...)
44+
if cErr != nil {
45+
panic(cErr)
46+
}
47+
48+
// use the connection
49+
```

0 commit comments

Comments
 (0)