Skip to content

Commit f5d889f

Browse files
authored
Merge pull request #87 from smartcontractkit/helm_sdk_installer
Add re-org env for Ethereum
2 parents 1195078 + ffca61d commit f5d889f

24 files changed

+1521
-566
lines changed

actions/setup.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@ func DefaultLocalSetup(
6262
if err != nil {
6363
return nil, err
6464
}
65+
if err := contracts.AwaitMining(blockchainClient); err != nil {
66+
return nil, err
67+
}
6568
link, err := contractDeployer.DeployLinkTokenContract(wallets.Default())
6669
if err != nil {
6770
return nil, err
6871
}
6972
// configure default retry
7073
retry.DefaultAttempts = conf.Retry.Attempts
71-
// linear waiting
7274
retry.DefaultDelayType = func(n uint, err error, config *retry.Config) time.Duration {
7375
return conf.Retry.LinearDelay
7476
}

config.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ networks:
9393
minimum_confirmations: 1
9494
gas_estimation_buffer: 0
9595
block_gas_limit: 400000000000000
96+
ethereum_geth_reorg:
97+
name: "Ethereum Geth reorg"
98+
chain_id: 1337
99+
type: evm
100+
<<: *secret_private_keys_default
101+
<<: *namespace_for_secret_default
102+
<<: *private_keys
103+
transaction_limit: 9500000
104+
transaction_timeout: 30s
105+
minimum_confirmations: 1
106+
gas_estimation_buffer: 0
107+
block_gas_limit: 400000000000000
96108
ethereum_hardhat:
97109
name: "Ethereum Hardhat"
98110
chain_id: 1337
@@ -156,7 +168,7 @@ networks:
156168
minimum_confirmations: 1
157169
gas_estimation_buffer: 1000000
158170
retry:
159-
attempts: 20
171+
attempts: 30
160172
linear_delay: 1s
161173

162174
kubernetes:

contracts/ethereum_reorg_util.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package contracts
2+
3+
import (
4+
"context"
5+
"github.com/ethereum/go-ethereum/core/types"
6+
"github.com/pkg/errors"
7+
"github.com/rs/zerolog/log"
8+
"github.com/smartcontractkit/integrations-framework/client"
9+
"time"
10+
)
11+
12+
const (
13+
DAGAwaitTimeout = 120 * time.Second
14+
)
15+
16+
// AwaitMining awaits first block after DAG generation on multi-node geth networks
17+
func AwaitMining(c client.BlockchainClient) error {
18+
log.Info().Msg("Awaiting first block to be mined")
19+
key := "next_block"
20+
cf := NewNextBlockConfirmer()
21+
c.AddHeaderEventSubscription(key, cf)
22+
if err := c.WaitForEvents(); err != nil {
23+
return err
24+
}
25+
return nil
26+
}
27+
28+
// NextBlockConfirmer await for the next block
29+
type NextBlockConfirmer struct {
30+
doneChan chan struct{}
31+
done bool
32+
ctx context.Context
33+
cancel context.CancelFunc
34+
}
35+
36+
// NewNextBlockConfirmer generic next block confirmer
37+
func NewNextBlockConfirmer() *NextBlockConfirmer {
38+
ctx, cancel := context.WithTimeout(context.Background(), DAGAwaitTimeout)
39+
return &NextBlockConfirmer{
40+
done: false,
41+
doneChan: make(chan struct{}),
42+
ctx: ctx,
43+
cancel: cancel,
44+
}
45+
}
46+
47+
func (f *NextBlockConfirmer) ReceiveBlock(_ *types.Block) error {
48+
if f.done {
49+
return nil
50+
}
51+
log.Info().Msg("First block received")
52+
f.done = true
53+
f.doneChan <- struct{}{}
54+
return nil
55+
}
56+
57+
func (f *NextBlockConfirmer) Wait() error {
58+
for {
59+
select {
60+
case <-f.doneChan:
61+
f.cancel()
62+
return nil
63+
case <-f.ctx.Done():
64+
return errors.New("timeout waiting for the next block to confirm")
65+
}
66+
}
67+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
apiVersion: v1
2+
description: Geth private network for reorg tests
3+
name: ethereum
4+
version: 0.0.1
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# kubernetes-ethereum-chart
2+
3+
Private Ethereum Network
4+
5+
## TL;DR;
6+
7+
```console
8+
$ git clone [email protected]:jpoon/kubernetes-ethereum-chart.git
9+
$ helm install --name ethereum kubernetes-ethereum-chart
10+
```
11+
12+
## Introduction
13+
14+
This chart bootstraps a private [Ethereum](https://www.ethereum.org/) network on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. For more information, https://www.microsoft.com/developerblog/2018/02/09/using-helm-deploy-blockchain-kubernetes/.
15+
16+
## Prerequisites
17+
18+
* Kubernetes 1.8
19+
20+
## Installing the Chart
21+
22+
The chart can be installed as follows:
23+
24+
```console
25+
$ git clone [email protected]:jpoon/kubernetes-ethereum-chart.git
26+
$ helm install --name ethereum kubernetes-ethereum-chart
27+
```
28+
29+
The command deploys a private Ethereum network on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists various ways to override default configuration during deployment.
30+
31+
> **Tip**: List all releases using `helm list`
32+
33+
## Uninstalling the Chart
34+
35+
To uninstall/delete the `my-release` deployment:
36+
37+
```console
38+
$ helm delete ethereum
39+
```
40+
41+
The command removes all the Kubernetes components associated with the chart and deletes the release.
42+
43+
## Configuration
44+
45+
See `values.yaml` for configuration notes. Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
46+
47+
```console
48+
$ helm install kubernetes-ethereum-chart --name ethereum --set geth.genesis.networkid=98052
49+
```
50+
51+
The above command sets the networkId to 98052
52+
53+
Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example,
54+
55+
```console
56+
$ helm install kubernetes-ethereum-chart --name ethereum -f values.yaml
57+
```
58+
59+
> **Tip**: You can use the default [values.yaml](values.yaml)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
1. Connect to Geth transaction nodes (through RPC or WS) at the following IP:
2+
3+
{{- if contains "NodePort" .Values.geth.tx.service.type }}
4+
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "ethereum.fullname" . }}-geth-tx-service)
5+
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
6+
echo $NODE_IP:$NODE_PORT
7+
{{- else if contains "LoadBalancer" .Values.geth.tx.service.type }}
8+
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "ethereum.fullname" . }}-geth-tx-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
9+
echo $SERVICE_IP
10+
11+
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
12+
You can watch the status of by running 'kubectl get svc -w {{ template "ethereum.fullname" . }}-geth-tx-service'
13+
{{- else if contains "ClusterIP" .Values.geth.tx.service.type }}
14+
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "ethereum.fullname" . }}-geth-tx-service,release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
15+
kubectl port-forward $POD_NAME 8545:8545 8546:8546
16+
{{- end }}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{{/* vim: set filetype=mustache: */}}
2+
{{/*
3+
Expand the name of the chart.
4+
*/}}
5+
{{- define "ethereum.name" -}}
6+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
7+
{{- end -}}
8+
9+
{{/*
10+
Create a default fully qualified app name.
11+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12+
*/}}
13+
{{- define "ethereum.fullname" -}}
14+
{{- $name := default .Chart.Name .Values.nameOverride -}}
15+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
16+
{{- end -}}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ template "ethereum.fullname" . }}-bootnode-registrar-deployment
5+
labels:
6+
app: {{ template "ethereum.name" . }}-bootnode-registrar-deployment
7+
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
8+
release: {{ .Release.Name }}
9+
heritage: {{ .Release.Service }}
10+
spec:
11+
replicas: {{ .Values.bootnodeRegistrar.replicaCount }}
12+
selector:
13+
matchLabels:
14+
app: {{ template "ethereum.name" . }}-bootnode-registrar
15+
release: {{ .Release.Name }}
16+
template:
17+
metadata:
18+
labels:
19+
app: {{ template "ethereum.name" . }}-bootnode-registrar
20+
release: {{ .Release.Name }}
21+
spec:
22+
containers:
23+
- name: bootnode-registrar
24+
image: {{ .Values.bootnodeRegistrar.image.repository }}:{{ .Values.bootnodeRegistrar.image.tag }}
25+
imagePullPolicy: {{ .Values.imagePullPolicy }}
26+
env:
27+
- name: BOOTNODE_SERVICE
28+
value: {{ template "ethereum.fullname" . }}-bootnode-service.{{ .Release.Namespace }}.svc.cluster.local
29+
ports:
30+
- containerPort: 9898
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
kind: Service
2+
apiVersion: v1
3+
metadata:
4+
name: {{ template "ethereum.fullname" . }}-bootnode-registrar-service
5+
labels:
6+
app: {{ template "ethereum.name" . }}-bootnode-registrar-service
7+
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
8+
release: {{ .Release.Name }}
9+
heritage: {{ .Release.Service }}
10+
spec:
11+
selector:
12+
app: {{ template "ethereum.name" . }}-bootnode-registrar
13+
release: {{ .Release.Name }}
14+
type: ClusterIP
15+
ports:
16+
- port: 80
17+
targetPort: 9898
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ template "ethereum.fullname" . }}-bootnode-deployment
5+
labels:
6+
app: {{ template "ethereum.name" . }}-bootnode-deployment
7+
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
8+
release: {{ .Release.Name }}
9+
heritage: {{ .Release.Service }}
10+
spec:
11+
replicas: {{ .Values.bootnode.replicaCount }}
12+
selector:
13+
matchLabels:
14+
app: {{ template "ethereum.name" . }}-bootnode
15+
release: {{ .Release.Name }}
16+
template:
17+
metadata:
18+
labels:
19+
app: {{ template "ethereum.name" . }}-bootnode
20+
release: {{ .Release.Name }}
21+
spec:
22+
containers:
23+
- name: bootnode
24+
image: {{ .Values.bootnode.image.repository }}:{{ .Values.bootnode.image.tag }}
25+
imagePullPolicy: {{ .Values.imagePullPolicy }}
26+
command: ["/bin/sh"]
27+
args:
28+
- "-c"
29+
- "bootnode --nodekey=/etc/bootnode/node.key --verbosity=4"
30+
volumeMounts:
31+
- name: data
32+
mountPath: /etc/bootnode
33+
ports:
34+
- name: discovery
35+
containerPort: 30301
36+
protocol: UDP
37+
- name: bootnode-server
38+
image: {{ .Values.bootnode.image.repository }}:{{ .Values.bootnode.image.tag }}
39+
imagePullPolicy: {{.Values.imagePullPolicy}}
40+
command: ["/bin/sh"]
41+
args:
42+
- "-c"
43+
- "while [ 1 ]; do echo -e \"HTTP/1.1 200 OK\n\nenode://$(bootnode -writeaddress --nodekey=/etc/bootnode/node.key)@$(POD_IP):30301\" | nc -l -v -p 8080 || break; done;"
44+
volumeMounts:
45+
- name: data
46+
mountPath: /etc/bootnode
47+
env:
48+
- name: POD_IP
49+
valueFrom:
50+
fieldRef:
51+
fieldPath: status.podIP
52+
ports:
53+
- containerPort: 8080
54+
initContainers:
55+
- name: genkey
56+
image: {{ .Values.bootnode.image.repository }}:{{ .Values.bootnode.image.tag }}
57+
imagePullPolicy: {{ .Values.imagePullPolicy }}
58+
command: ["/bin/sh"]
59+
args:
60+
- "-c"
61+
- "bootnode --genkey=/etc/bootnode/node.key"
62+
volumeMounts:
63+
- name: data
64+
mountPath: /etc/bootnode
65+
volumes:
66+
- name: data
67+
emptyDir: {}

0 commit comments

Comments
 (0)