Skip to content

Commit

Permalink
Refactor quorum docker entrypoint creation to its own file
Browse files Browse the repository at this point in the history
Signed-off-by: rodion <[email protected]>
  • Loading branch information
rodion-lim-partior committed Jun 28, 2024
1 parent cad70ac commit 3fea393
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 94 deletions.
14 changes: 7 additions & 7 deletions internal/blockchain/ethereum/quorum/geth_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func (p *GethProvider) GetDockerServiceDefinitions() []*docker.ServiceDefinition
ContainerName: fmt.Sprintf("member%dtessera", i),
Volumes: []string{fmt.Sprintf("tessera_%d:/data", i)},
Logging: docker.StandardLogOptions,
Ports: []string{fmt.Sprintf("%d:%s", p.stack.ExposedPtmPort+(i*exposedBlockchainPortMultiplier), ethereum.TmTpPort)}, // defaults 4100, 4110, 4120, 4130
Ports: []string{fmt.Sprintf("%d:%s", p.stack.ExposedPtmPort+(i*exposedBlockchainPortMultiplier), TmTpPort)}, // defaults 4100, 4110, 4120, 4130
Environment: p.stack.EnvironmentVars,
EntryPoint: []string{"/bin/sh", "-c", "/data/docker-entrypoint.sh"},
Deploy: map[string]interface{}{"restart_policy": map[string]string{"condition": "on-failure", "max_attempts": "3"}},
Expand Down Expand Up @@ -340,21 +340,21 @@ func (p *GethProvider) CreateAccount(args []string) (interface{}, error) {
if p.stack.TesseraEnabled {
tesseraVolumeName := fmt.Sprintf("%s_tessera_%s", p.stack.Name, memberIndex)
tesseraKeysOutputDirectory := filepath.Join(directory, "tessera", fmt.Sprintf("tessera_%s", memberIndex), "keystore")
_, tesseraPubKey, tesseraKeysPath, err = ethereum.CreateTesseraKeys(p.ctx, tesseraImage, tesseraKeysOutputDirectory, "", "tm", keyPassword)
_, tesseraPubKey, tesseraKeysPath, err = CreateTesseraKeys(p.ctx, tesseraImage, tesseraKeysOutputDirectory, "", "tm", keyPassword)
if err != nil {
return nil, err
}
l.Info(fmt.Sprintf("keys generated in %s", tesseraKeysPath))
l.Info(fmt.Sprintf("generating tessera entrypoint file for member %s", memberIndex))
l.Info(fmt.Sprintf("generating tessera docker-entrypoint file for member %s", memberIndex))
tesseraEntrypointOutputDirectory := filepath.Join(directory, "tessera", fmt.Sprintf("tessera_%s", memberIndex))
if err := ethereum.CreateTesseraEntrypoint(p.ctx, tesseraEntrypointOutputDirectory, tesseraVolumeName, memberCount); err != nil {
if err := CreateTesseraEntrypoint(p.ctx, tesseraEntrypointOutputDirectory, tesseraVolumeName, memberCount); err != nil {
return nil, err
}
}

l.Info(fmt.Sprintf("generating quorum entrypoint file for member %s", memberIndex))
l.Info(fmt.Sprintf("generating quorum docker-entrypoint file for member %s", memberIndex))
quorumEntrypointOutputDirectory := filepath.Join(directory, "blockchain", fmt.Sprintf("geth_%s", memberIndex))
if err := ethereum.CreateQuorumEntrypoint(p.ctx, quorumEntrypointOutputDirectory, gethVolumeName, memberIndex, p.stack.QuorumConsensus.String(), int(p.stack.ChainID()), p.stack.TesseraEnabled); err != nil {
if err := CreateQuorumEntrypoint(p.ctx, quorumEntrypointOutputDirectory, gethVolumeName, memberIndex, p.stack.QuorumConsensus.String(), int(p.stack.ChainID()), p.stack.TesseraEnabled); err != nil {
return nil, err
}

Expand All @@ -369,7 +369,7 @@ func (p *GethProvider) CreateAccount(args []string) (interface{}, error) {
return nil, err
}
}
if err := ethereum.CopyQuorumEntrypointToVolume(p.ctx, quorumEntrypointOutputDirectory, gethVolumeName); err != nil {
if err := CopyQuorumEntrypointToVolume(p.ctx, quorumEntrypointOutputDirectory, gethVolumeName); err != nil {
return nil, err
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package ethereum
package quorum

import (
"context"
Expand Down Expand Up @@ -167,89 +167,3 @@ func CopyTesseraEntrypointToVolume(ctx context.Context, tesseraEntrypointDirecto
}
return nil
}

func CreateQuorumEntrypoint(ctx context.Context, outputDirectory, volumeName, memberIndex, consensus string, chainId int, tesseraEnabled bool) error {
discoveryCmd := "BOOTNODE_CMD=\"\""
connectTimeout := 15
if memberIndex != "0" {
discoveryCmd = fmt.Sprintf(`bootnode=$(curl http://geth_0:%s -s --connect-timeout %[2]d --max-time %[2]d --retry 5 --retry-connrefused --retry-delay 0 --retry-max-time 60 --fail --header "Content-Type: application/json" --data '{"jsonrpc":"2.0", "method": "admin_nodeInfo", "params": [], "id": 1}' | grep -o "enode://[a-z0-9@.:]*")
BOOTNODE_CMD="--bootnodes $bootnode"
BOOTNODE_CMD=${BOOTNODE_CMD/127.0.0.1/geth_0}`, GethPort, connectTimeout)
}

tesseraCmd := ""
if tesseraEnabled {
tesseraCmd = fmt.Sprintf(`TESSERA_URL=http://member%stessera
TESSERA_TP_PORT=%s
TESSERA_Q2T_PORT=%s
TESSERA_UPCHECK_URL=$TESSERA_URL:$TESSERA_TP_PORT/upcheck
ADDITIONAL_ARGS="${ADDITIONAL_ARGS:-} --ptm.timeout 5 --ptm.url ${TESSERA_URL}:${TESSERA_Q2T_PORT} --ptm.http.writebuffersize 4096 --ptm.http.readbuffersize 4096 --ptm.tls.mode off"
echo -n "Checking tessera is up ... "
curl --connect-timeout %[4]d --max-time %[4]d --retry 5 --retry-connrefused --retry-delay 0 --retry-max-time 60 --silent --fail "$TESSERA_UPCHECK_URL"
echo ""
`, memberIndex, TmTpPort, TmQ2tPort, connectTimeout)
}

content := fmt.Sprintf(`#!/bin/sh
set -o errexit
set -o nounset
set -o pipefail
set -o xtrace
GOQUORUM_CONS_ALGO=%s
if [ "istanbul" == "$GOQUORUM_CONS_ALGO" ];
then
echo "Using istanbul for consensus algorithm..."
export CONSENSUS_ARGS="--istanbul.blockperiod 5 --mine --miner.threads 1 --miner.gasprice 0 --emitcheckpoints"
export QUORUM_API="istanbul"
elif [ "qbft" == "$GOQUORUM_CONS_ALGO" ];
then
echo "Using qbft for consensus algorithm..."
export CONSENSUS_ARGS="--mine --miner.threads 1 --miner.gasprice 0 --emitcheckpoints"
export QUORUM_API="istanbul"
elif [ "raft" == "$GOQUORUM_CONS_ALGO" ];
then
echo "Using raft for consensus algorithm..."
export CONSENSUS_ARGS="--raft --raftblocktime 300 --raftport 53000"
export QUORUM_API="raft"
elif [ "clique" == "$GOQUORUM_CONS_ALGO" ];
then
echo "Using clique for consensus algorithm..."
export CONSENSUS_ARGS=""
export QUORUM_API="clique"
fi
ADDITIONAL_ARGS=${ADDITIONAL_ARGS:-}
%s
# discovery
%s
echo "bootnode discovery command :: $BOOTNODE_CMD"
IP_ADDR=$(cat /etc/hosts | tail -n 1 | awk '{print $1}')
exec geth --datadir /data --nat extip:$IP_ADDR --syncmode 'full' --revertreason --port 30311 --http --http.addr "0.0.0.0" --http.corsdomain="*" -http.port %s --http.vhosts "*" --http.api admin,personal,eth,net,web3,txpool,miner,debug,$QUORUM_API --networkid %d --miner.gasprice 0 --password /data/password --mine --allow-insecure-unlock --verbosity 4 $CONSENSUS_ARGS --miner.gaslimit 16777215 $BOOTNODE_CMD $ADDITIONAL_ARGS`, consensus, tesseraCmd, discoveryCmd, GethPort, chainId)
filename := filepath.Join(outputDirectory, entrypoint)
if err := os.MkdirAll(outputDirectory, 0755); err != nil {
return err
}
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
return err
}
defer file.Close()
_, err = file.WriteString(content)
if err != nil {
return err
}
CopyQuorumEntrypointToVolume(ctx, outputDirectory, volumeName)
return nil
}

func CopyQuorumEntrypointToVolume(ctx context.Context, quorumEntrypointDirectory, volumeName string) error {
if err := docker.CopyFileToVolume(ctx, volumeName, filepath.Join(quorumEntrypointDirectory, entrypoint), ""); err != nil {
return err
}
return nil
}
112 changes: 112 additions & 0 deletions internal/blockchain/ethereum/quorum/quorum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright © 2024 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package quorum

import (
"context"
"fmt"
"os"
"path/filepath"

"github.com/hyperledger/firefly-cli/internal/docker"
)

func CreateQuorumEntrypoint(ctx context.Context, outputDirectory, volumeName, memberIndex, consensus string, chainId int, tesseraEnabled bool) error {
discoveryCmd := "BOOTNODE_CMD=\"\""
connectTimeout := 15
if memberIndex != "0" {
discoveryCmd = fmt.Sprintf(`bootnode=$(curl http://geth_0:%s -s --connect-timeout %[2]d --max-time %[2]d --retry 5 --retry-connrefused --retry-delay 0 --retry-max-time 60 --fail --header "Content-Type: application/json" --data '{"jsonrpc":"2.0", "method": "admin_nodeInfo", "params": [], "id": 1}' | grep -o "enode://[a-z0-9@.:]*")
BOOTNODE_CMD="--bootnodes $bootnode"
BOOTNODE_CMD=${BOOTNODE_CMD/127.0.0.1/geth_0}`, GethPort, connectTimeout)
}

tesseraCmd := ""
if tesseraEnabled {
tesseraCmd = fmt.Sprintf(`TESSERA_URL=http://member%stessera
TESSERA_TP_PORT=%s
TESSERA_Q2T_PORT=%s
TESSERA_UPCHECK_URL=$TESSERA_URL:$TESSERA_TP_PORT/upcheck
ADDITIONAL_ARGS="${ADDITIONAL_ARGS:-} --ptm.timeout 5 --ptm.url ${TESSERA_URL}:${TESSERA_Q2T_PORT} --ptm.http.writebuffersize 4096 --ptm.http.readbuffersize 4096 --ptm.tls.mode off"
echo -n "Checking tessera is up ... "
curl --connect-timeout %[4]d --max-time %[4]d --retry 5 --retry-connrefused --retry-delay 0 --retry-max-time 60 --silent --fail "$TESSERA_UPCHECK_URL"
echo ""
`, memberIndex, TmTpPort, TmQ2tPort, connectTimeout)
}

content := fmt.Sprintf(`#!/bin/sh
set -o errexit
set -o nounset
set -o pipefail
set -o xtrace
GOQUORUM_CONS_ALGO=%s
if [ "istanbul" == "$GOQUORUM_CONS_ALGO" ];
then
echo "Using istanbul for consensus algorithm..."
export CONSENSUS_ARGS="--istanbul.blockperiod 5 --mine --miner.threads 1 --miner.gasprice 0 --emitcheckpoints"
export QUORUM_API="istanbul"
elif [ "qbft" == "$GOQUORUM_CONS_ALGO" ];
then
echo "Using qbft for consensus algorithm..."
export CONSENSUS_ARGS="--mine --miner.threads 1 --miner.gasprice 0 --emitcheckpoints"
export QUORUM_API="istanbul"
elif [ "raft" == "$GOQUORUM_CONS_ALGO" ];
then
echo "Using raft for consensus algorithm..."
export CONSENSUS_ARGS="--raft --raftblocktime 300 --raftport 53000"
export QUORUM_API="raft"
elif [ "clique" == "$GOQUORUM_CONS_ALGO" ];
then
echo "Using clique for consensus algorithm..."
export CONSENSUS_ARGS=""
export QUORUM_API="clique"
fi
ADDITIONAL_ARGS=${ADDITIONAL_ARGS:-}
%s
# discovery
%s
echo "bootnode discovery command :: $BOOTNODE_CMD"
IP_ADDR=$(cat /etc/hosts | tail -n 1 | awk '{print $1}')
exec geth --datadir /data --nat extip:$IP_ADDR --syncmode 'full' --revertreason --port 30311 --http --http.addr "0.0.0.0" --http.corsdomain="*" -http.port %s --http.vhosts "*" --http.api admin,personal,eth,net,web3,txpool,miner,debug,$QUORUM_API --networkid %d --miner.gasprice 0 --password /data/password --mine --allow-insecure-unlock --verbosity 4 $CONSENSUS_ARGS --miner.gaslimit 16777215 $BOOTNODE_CMD $ADDITIONAL_ARGS`, consensus, tesseraCmd, discoveryCmd, GethPort, chainId)
filename := filepath.Join(outputDirectory, entrypoint)
if err := os.MkdirAll(outputDirectory, 0755); err != nil {
return err
}
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
return err
}
defer file.Close()
_, err = file.WriteString(content)
if err != nil {
return err
}
CopyQuorumEntrypointToVolume(ctx, outputDirectory, volumeName)
return nil
}

func CopyQuorumEntrypointToVolume(ctx context.Context, quorumEntrypointDirectory, volumeName string) error {
if err := docker.CopyFileToVolume(ctx, volumeName, filepath.Join(quorumEntrypointDirectory, entrypoint), ""); err != nil {
return err
}
return nil
}

0 comments on commit 3fea393

Please sign in to comment.