|
|
@ -42,7 +42,7 @@ ADD genesis.json /genesis.json |
|
|
|
RUN \
|
|
|
|
RUN \
|
|
|
|
echo 'geth --cache 512 init /genesis.json' > geth.sh && \{{if .Unlock}} |
|
|
|
echo 'geth --cache 512 init /genesis.json' > geth.sh && \{{if .Unlock}} |
|
|
|
echo 'mkdir -p /root/.ethereum/keystore/ && cp /signer.json /root/.ethereum/keystore/' >> geth.sh && \{{end}} |
|
|
|
echo 'mkdir -p /root/.ethereum/keystore/ && cp /signer.json /root/.ethereum/keystore/' >> geth.sh && \{{end}} |
|
|
|
echo $'geth --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .BootV4}}--bootnodesv4 {{.BootV4}}{{end}} {{if .BootV5}}--bootnodesv5 {{.BootV5}}{{end}} {{if .Etherbase}}--etherbase {{.Etherbase}} --mine --minerthreads 1{{end}} {{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}} --targetgaslimit {{.GasTarget}} --gasprice {{.GasPrice}}' >> geth.sh |
|
|
|
echo $'geth --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .Bootnodes}}--bootnodes {{.Bootnodes}}{{end}} {{if .Etherbase}}--etherbase {{.Etherbase}} --mine --minerthreads 1{{end}} {{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}} --targetgaslimit {{.GasTarget}} --gasprice {{.GasPrice}}' >> geth.sh |
|
|
|
|
|
|
|
|
|
|
|
ENTRYPOINT ["/bin/sh", "geth.sh"] |
|
|
|
ENTRYPOINT ["/bin/sh", "geth.sh"] |
|
|
|
` |
|
|
|
` |
|
|
@ -56,15 +56,13 @@ services: |
|
|
|
build: . |
|
|
|
build: . |
|
|
|
image: {{.Network}}/{{.Type}} |
|
|
|
image: {{.Network}}/{{.Type}} |
|
|
|
ports: |
|
|
|
ports: |
|
|
|
- "{{.FullPort}}:{{.FullPort}}" |
|
|
|
- "{{.Port}}:{{.Port}}" |
|
|
|
- "{{.FullPort}}:{{.FullPort}}/udp"{{if .Light}} |
|
|
|
- "{{.Port}}:{{.Port}}/udp" |
|
|
|
- "{{.LightPort}}:{{.LightPort}}/udp"{{end}} |
|
|
|
|
|
|
|
volumes: |
|
|
|
volumes: |
|
|
|
- {{.Datadir}}:/root/.ethereum{{if .Ethashdir}} |
|
|
|
- {{.Datadir}}:/root/.ethereum{{if .Ethashdir}} |
|
|
|
- {{.Ethashdir}}:/root/.ethash{{end}} |
|
|
|
- {{.Ethashdir}}:/root/.ethash{{end}} |
|
|
|
environment: |
|
|
|
environment: |
|
|
|
- FULL_PORT={{.FullPort}}/tcp |
|
|
|
- PORT={{.Port}}/tcp |
|
|
|
- LIGHT_PORT={{.LightPort}}/udp |
|
|
|
|
|
|
|
- TOTAL_PEERS={{.TotalPeers}} |
|
|
|
- TOTAL_PEERS={{.TotalPeers}} |
|
|
|
- LIGHT_PEERS={{.LightPeers}} |
|
|
|
- LIGHT_PEERS={{.LightPeers}} |
|
|
|
- STATS_NAME={{.Ethstats}} |
|
|
|
- STATS_NAME={{.Ethstats}} |
|
|
@ -82,12 +80,11 @@ services: |
|
|
|
// deployNode deploys a new Ethereum node container to a remote machine via SSH,
|
|
|
|
// deployNode deploys a new Ethereum node container to a remote machine via SSH,
|
|
|
|
// docker and docker-compose. If an instance with the specified network name
|
|
|
|
// docker and docker-compose. If an instance with the specified network name
|
|
|
|
// already exists there, it will be overwritten!
|
|
|
|
// already exists there, it will be overwritten!
|
|
|
|
func deployNode(client *sshClient, network string, bootv4, bootv5 []string, config *nodeInfos, nocache bool) ([]byte, error) { |
|
|
|
func deployNode(client *sshClient, network string, bootnodes []string, config *nodeInfos, nocache bool) ([]byte, error) { |
|
|
|
kind := "sealnode" |
|
|
|
kind := "sealnode" |
|
|
|
if config.keyJSON == "" && config.etherbase == "" { |
|
|
|
if config.keyJSON == "" && config.etherbase == "" { |
|
|
|
kind = "bootnode" |
|
|
|
kind = "bootnode" |
|
|
|
bootv4 = make([]string, 0) |
|
|
|
bootnodes = make([]string, 0) |
|
|
|
bootv5 = make([]string, 0) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
// Generate the content to upload to the server
|
|
|
|
// Generate the content to upload to the server
|
|
|
|
workdir := fmt.Sprintf("%d", rand.Int63()) |
|
|
|
workdir := fmt.Sprintf("%d", rand.Int63()) |
|
|
@ -100,11 +97,10 @@ func deployNode(client *sshClient, network string, bootv4, bootv5 []string, conf |
|
|
|
dockerfile := new(bytes.Buffer) |
|
|
|
dockerfile := new(bytes.Buffer) |
|
|
|
template.Must(template.New("").Parse(nodeDockerfile)).Execute(dockerfile, map[string]interface{}{ |
|
|
|
template.Must(template.New("").Parse(nodeDockerfile)).Execute(dockerfile, map[string]interface{}{ |
|
|
|
"NetworkID": config.network, |
|
|
|
"NetworkID": config.network, |
|
|
|
"Port": config.portFull, |
|
|
|
"Port": config.port, |
|
|
|
"Peers": config.peersTotal, |
|
|
|
"Peers": config.peersTotal, |
|
|
|
"LightFlag": lightFlag, |
|
|
|
"LightFlag": lightFlag, |
|
|
|
"BootV4": strings.Join(bootv4, ","), |
|
|
|
"Bootnodes": strings.Join(bootnodes, ","), |
|
|
|
"BootV5": strings.Join(bootv5, ","), |
|
|
|
|
|
|
|
"Ethstats": config.ethstats, |
|
|
|
"Ethstats": config.ethstats, |
|
|
|
"Etherbase": config.etherbase, |
|
|
|
"Etherbase": config.etherbase, |
|
|
|
"GasTarget": uint64(1000000 * config.gasTarget), |
|
|
|
"GasTarget": uint64(1000000 * config.gasTarget), |
|
|
@ -119,10 +115,9 @@ func deployNode(client *sshClient, network string, bootv4, bootv5 []string, conf |
|
|
|
"Datadir": config.datadir, |
|
|
|
"Datadir": config.datadir, |
|
|
|
"Ethashdir": config.ethashdir, |
|
|
|
"Ethashdir": config.ethashdir, |
|
|
|
"Network": network, |
|
|
|
"Network": network, |
|
|
|
"FullPort": config.portFull, |
|
|
|
"Port": config.port, |
|
|
|
"TotalPeers": config.peersTotal, |
|
|
|
"TotalPeers": config.peersTotal, |
|
|
|
"Light": config.peersLight > 0, |
|
|
|
"Light": config.peersLight > 0, |
|
|
|
"LightPort": config.portFull + 1, |
|
|
|
|
|
|
|
"LightPeers": config.peersLight, |
|
|
|
"LightPeers": config.peersLight, |
|
|
|
"Ethstats": config.ethstats[:strings.Index(config.ethstats, ":")], |
|
|
|
"Ethstats": config.ethstats[:strings.Index(config.ethstats, ":")], |
|
|
|
"Etherbase": config.etherbase, |
|
|
|
"Etherbase": config.etherbase, |
|
|
@ -157,10 +152,8 @@ type nodeInfos struct { |
|
|
|
datadir string |
|
|
|
datadir string |
|
|
|
ethashdir string |
|
|
|
ethashdir string |
|
|
|
ethstats string |
|
|
|
ethstats string |
|
|
|
portFull int |
|
|
|
port int |
|
|
|
portLight int |
|
|
|
enode string |
|
|
|
enodeFull string |
|
|
|
|
|
|
|
enodeLight string |
|
|
|
|
|
|
|
peersTotal int |
|
|
|
peersTotal int |
|
|
|
peersLight int |
|
|
|
peersLight int |
|
|
|
etherbase string |
|
|
|
etherbase string |
|
|
@ -175,15 +168,11 @@ type nodeInfos struct { |
|
|
|
func (info *nodeInfos) Report() map[string]string { |
|
|
|
func (info *nodeInfos) Report() map[string]string { |
|
|
|
report := map[string]string{ |
|
|
|
report := map[string]string{ |
|
|
|
"Data directory": info.datadir, |
|
|
|
"Data directory": info.datadir, |
|
|
|
"Listener port (full nodes)": strconv.Itoa(info.portFull), |
|
|
|
"Listener port": strconv.Itoa(info.port), |
|
|
|
"Peer count (all total)": strconv.Itoa(info.peersTotal), |
|
|
|
"Peer count (all total)": strconv.Itoa(info.peersTotal), |
|
|
|
"Peer count (light nodes)": strconv.Itoa(info.peersLight), |
|
|
|
"Peer count (light nodes)": strconv.Itoa(info.peersLight), |
|
|
|
"Ethstats username": info.ethstats, |
|
|
|
"Ethstats username": info.ethstats, |
|
|
|
} |
|
|
|
} |
|
|
|
if info.peersLight > 0 { |
|
|
|
|
|
|
|
// Light server enabled
|
|
|
|
|
|
|
|
report["Listener port (light nodes)"] = strconv.Itoa(info.portLight) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if info.gasTarget > 0 { |
|
|
|
if info.gasTarget > 0 { |
|
|
|
// Miner or signer node
|
|
|
|
// Miner or signer node
|
|
|
|
report["Gas limit (baseline target)"] = fmt.Sprintf("%0.3f MGas", info.gasTarget) |
|
|
|
report["Gas limit (baseline target)"] = fmt.Sprintf("%0.3f MGas", info.gasTarget) |
|
|
@ -250,7 +239,7 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error) |
|
|
|
keyPass = string(bytes.TrimSpace(out)) |
|
|
|
keyPass = string(bytes.TrimSpace(out)) |
|
|
|
} |
|
|
|
} |
|
|
|
// Run a sanity check to see if the devp2p is reachable
|
|
|
|
// Run a sanity check to see if the devp2p is reachable
|
|
|
|
port := infos.portmap[infos.envvars["FULL_PORT"]] |
|
|
|
port := infos.portmap[infos.envvars["PORT"]] |
|
|
|
if err = checkPort(client.server, port); err != nil { |
|
|
|
if err = checkPort(client.server, port); err != nil { |
|
|
|
log.Warn(fmt.Sprintf("%s devp2p port seems unreachable", strings.Title(kind)), "server", client.server, "port", port, "err", err) |
|
|
|
log.Warn(fmt.Sprintf("%s devp2p port seems unreachable", strings.Title(kind)), "server", client.server, "port", port, "err", err) |
|
|
|
} |
|
|
|
} |
|
|
@ -259,8 +248,7 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error) |
|
|
|
genesis: genesis, |
|
|
|
genesis: genesis, |
|
|
|
datadir: infos.volumes["/root/.ethereum"], |
|
|
|
datadir: infos.volumes["/root/.ethereum"], |
|
|
|
ethashdir: infos.volumes["/root/.ethash"], |
|
|
|
ethashdir: infos.volumes["/root/.ethash"], |
|
|
|
portFull: infos.portmap[infos.envvars["FULL_PORT"]], |
|
|
|
port: port, |
|
|
|
portLight: infos.portmap[infos.envvars["LIGHT_PORT"]], |
|
|
|
|
|
|
|
peersTotal: totalPeers, |
|
|
|
peersTotal: totalPeers, |
|
|
|
peersLight: lightPeers, |
|
|
|
peersLight: lightPeers, |
|
|
|
ethstats: infos.envvars["STATS_NAME"], |
|
|
|
ethstats: infos.envvars["STATS_NAME"], |
|
|
@ -270,9 +258,7 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error) |
|
|
|
gasTarget: gasTarget, |
|
|
|
gasTarget: gasTarget, |
|
|
|
gasPrice: gasPrice, |
|
|
|
gasPrice: gasPrice, |
|
|
|
} |
|
|
|
} |
|
|
|
stats.enodeFull = fmt.Sprintf("enode://%s@%s:%d", id, client.address, stats.portFull) |
|
|
|
stats.enode = fmt.Sprintf("enode://%s@%s:%d", id, client.address, stats.port) |
|
|
|
if stats.portLight != 0 { |
|
|
|
|
|
|
|
stats.enodeLight = fmt.Sprintf("enode://%s@%s:%d?discport=%d", id, client.address, stats.portFull, stats.portLight) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return stats, nil |
|
|
|
return stats, nil |
|
|
|
} |
|
|
|
} |
|
|
|