diff --git a/.gitignore b/.gitignore index f5cabd49..46254230 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,7 @@ dist/ *.iml .idea/ docs/command_docs -coverage.txt \ No newline at end of file +coverage.txt +.vscode +!.vscode/launch.json +!.vscode/settings.json \ No newline at end of file diff --git a/internal/blockchain/ethereum/ethsigner/config.go b/internal/blockchain/ethereum/ethsigner/config.go index 7abbc445..6755bbaa 100644 --- a/internal/blockchain/ethereum/ethsigner/config.go +++ b/internal/blockchain/ethereum/ethsigner/config.go @@ -19,7 +19,7 @@ package ethsigner import ( "os" - "gopkg.in/yaml.v2" + "gopkg.in/yaml.v3" ) type FileWalletFilenamesConfig struct { diff --git a/internal/blockchain/ethereum/quorum/quorum.go b/internal/blockchain/ethereum/quorum/quorum.go index 06bd2fd8..ea572ad2 100644 --- a/internal/blockchain/ethereum/quorum/quorum.go +++ b/internal/blockchain/ethereum/quorum/quorum.go @@ -22,11 +22,15 @@ import ( "os" "path/filepath" + "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/tessera" "github.com/hyperledger/firefly-cli/internal/docker" "github.com/hyperledger/firefly-cli/pkg/types" "github.com/hyperledger/firefly-common/pkg/fftypes" ) +var DockerEntrypoint = "docker-entrypoint.sh" +var QuorumPort = "8545" + func CreateQuorumEntrypoint(ctx context.Context, outputDirectory, consensus, stackName string, memberIndex, chainID, blockPeriodInSeconds int, privateTransactionManager fftypes.FFEnum) error { discoveryCmd := "BOOTNODE_CMD=\"\"" connectTimeout := 15 @@ -47,7 +51,7 @@ ADDITIONAL_ARGS="${ADDITIONAL_ARGS:-} --ptm.timeout 5 --ptm.url ${TESSERA_URL}:$ 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, stackName) +`, memberIndex, tessera.TmTpPort, tessera.TmQ2tPort, connectTimeout, stackName) } blockPeriod := blockPeriodInSeconds @@ -94,7 +98,7 @@ ADDITIONAL_ARGS=${ADDITIONAL_ARGS:-} 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 %[4]s --http.vhosts "*" --http.api admin,personal,eth,net,web3,txpool,miner,debug,$QUORUM_API --networkid %[5]d --miner.gasprice 0 --password /data/password --mine --allow-insecure-unlock --verbosity 4 $CONSENSUS_ARGS $BOOTNODE_CMD $ADDITIONAL_ARGS`, consensus, tesseraCmd, discoveryCmd, QuorumPort, chainID, blockPeriod, blockPeriodInMs) +exec geth --datadir /data --nat extip:$IP_ADDR --syncmode 'full' --revertreason --port 30311 --http --http.addr "0.0.0.0" --http.corsdomain="*" -http.port %[4]s --http.vhosts "*" --http.api admin,personal,eth,net,web3,txpool,miner,debug,$QUORUM_API --networkid %[5]d --miner.gasprice 0 --password /data/password --mine --allow-insecure-unlock --nodiscover --verbosity 4 $CONSENSUS_ARGS $BOOTNODE_CMD $ADDITIONAL_ARGS`, consensus, tesseraCmd, discoveryCmd, QuorumPort, chainID, blockPeriod, blockPeriodInMs) filename := filepath.Join(outputDirectory, DockerEntrypoint) if err := os.MkdirAll(outputDirectory, 0755); err != nil { return err diff --git a/internal/blockchain/ethereum/quorum/quorum_provider.go b/internal/blockchain/ethereum/quorum/quorum_provider.go index d5e99383..7ad2c2a7 100644 --- a/internal/blockchain/ethereum/quorum/quorum_provider.go +++ b/internal/blockchain/ethereum/quorum/quorum_provider.go @@ -31,6 +31,7 @@ import ( "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/connector" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/connector/ethconnect" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/connector/evmconnect" + "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/tessera" "github.com/hyperledger/firefly-cli/internal/docker" "github.com/hyperledger/firefly-cli/internal/log" "github.com/hyperledger/firefly-cli/pkg/types" @@ -78,10 +79,10 @@ func (p *QuorumProvider) WriteConfig(options *types.InitOptions) error { } // Generate tessera docker-entrypoint for each member - if !p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerNone) { + if p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerTessera) { l.Info(fmt.Sprintf("generating tessera docker-entrypoint file for member %d", i)) tesseraEntrypointOutputDirectory := filepath.Join(initDir, "tessera", fmt.Sprintf("tessera_%d", i)) - if err := CreateTesseraEntrypoint(p.ctx, tesseraEntrypointOutputDirectory, p.stack.Name, len(p.stack.Members)); err != nil { + if err := tessera.CreateTesseraEntrypoint(p.ctx, tesseraEntrypointOutputDirectory, p.stack.Name, len(p.stack.Members)); err != nil { return err } } @@ -143,7 +144,7 @@ func (p *QuorumProvider) FirstTimeSetup() error { return err } - if !p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerNone) { + if p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerTessera) { // Copy member specific tessera key files if err := p.dockerMgr.MkdirInVolume(p.ctx, tesseraVolumeNameMember, rootDir); err != nil { return err @@ -153,14 +154,14 @@ func (p *QuorumProvider) FirstTimeSetup() error { return err } // Copy tessera docker-entrypoint file - tmEntrypointPath := filepath.Join(tesseraDir, fmt.Sprintf("tessera_%d", i), DockerEntrypoint) + tmEntrypointPath := filepath.Join(tesseraDir, fmt.Sprintf("tessera_%d", i), tessera.DockerEntrypoint) if err := p.dockerMgr.CopyFileToVolume(p.ctx, tesseraVolumeNameMember, tmEntrypointPath, rootDir); err != nil { return err } } // Copy quorum docker-entrypoint file - quorumEntrypointPath := filepath.Join(blockchainDir, fmt.Sprintf("quorum_%d", i), DockerEntrypoint) + quorumEntrypointPath := filepath.Join(blockchainDir, fmt.Sprintf("quorum_%d", i), tessera.DockerEntrypoint) if err := p.dockerMgr.CopyFileToVolume(p.ctx, quorumVolumeNameMember, quorumEntrypointPath, rootDir); err != nil { return err } @@ -236,43 +237,46 @@ func (p *QuorumProvider) DeployFireFlyContract() (*types.ContractDeploymentResul return p.connector.DeployContract(contract, "FireFly", p.stack.Members[0], nil) } +func (p *QuorumProvider) buildTesseraServiceDefinition(memberIdx int) *docker.ServiceDefinition { + return &docker.ServiceDefinition{ + ServiceName: fmt.Sprintf("tessera_%d", memberIdx), + Service: &docker.Service{ + Image: tesseraImage, + ContainerName: fmt.Sprintf("%s_member%dtessera", p.stack.Name, memberIdx), + Volumes: []string{fmt.Sprintf("tessera_%d:/data", memberIdx)}, + Logging: docker.StandardLogOptions, + Ports: []string{fmt.Sprintf("%d:%s", p.stack.ExposedPtmPort+(memberIdx*ExposedBlockchainPortMultiplier), tessera.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]interface{}{"condition": "on-failure", "max_attempts": int64(3)}}, + HealthCheck: &docker.HealthCheck{ + Test: []string{ + "CMD", + "curl", + "--fail", + fmt.Sprintf("http://localhost:%s/upcheck", tessera.TmTpPort), + }, + Interval: "15s", // 6000 requests in a day + Retries: 30, + }, + }, + VolumeNames: []string{fmt.Sprintf("tessera_%d", memberIdx)}, + } +} + func (p *QuorumProvider) GetDockerServiceDefinitions() []*docker.ServiceDefinition { memberCount := len(p.stack.Members) serviceDefinitionsCount := memberCount - if !p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerNone) { + if p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerTessera) { serviceDefinitionsCount *= 2 } serviceDefinitions := make([]*docker.ServiceDefinition, serviceDefinitionsCount) connectorDependents := map[string]string{} for i := 0; i < memberCount; i++ { var quorumDependsOn map[string]map[string]string - if !p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerNone) { + if p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerTessera) { quorumDependsOn = map[string]map[string]string{fmt.Sprintf("tessera_%d", i): {"condition": "service_healthy"}} - serviceDefinitions[i+memberCount] = &docker.ServiceDefinition{ - ServiceName: fmt.Sprintf("tessera_%d", i), - Service: &docker.Service{ - Image: tesseraImage, - ContainerName: fmt.Sprintf("%s_member%dtessera", p.stack.Name, i), - Volumes: []string{fmt.Sprintf("tessera_%d:/data", i)}, - Logging: docker.StandardLogOptions, - 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]interface{}{"condition": "on-failure", "max_attempts": int64(3)}}, - HealthCheck: &docker.HealthCheck{ - Test: []string{ - "CMD", - "curl", - "--fail", - fmt.Sprintf("http://localhost:%s/upcheck", TmTpPort), - }, - Interval: "15s", // 6000 requests in a day - Retries: 30, - }, - }, - VolumeNames: []string{fmt.Sprintf("tessera_%d", i)}, - } - + serviceDefinitions[i+memberCount] = p.buildTesseraServiceDefinition(i) // No arm64 images for Tessera if runtime.GOARCH == "arm64" { serviceDefinitions[i+memberCount].Service.Platform = "linux/amd64" @@ -377,9 +381,9 @@ func (p *QuorumProvider) CreateAccount(args []string) (interface{}, error) { // Tessera is an optional add-on to the quorum blockchain node provider var tesseraPubKey, tesseraKeysPath string - if !p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerNone) { + if p.stack.PrivateTransactionManager.Equals(types.PrivateTransactionManagerTessera) { tesseraKeysOutputDirectory := filepath.Join(directory, "tessera", fmt.Sprintf("tessera_%s", memberIndex), "keystore") - _, tesseraPubKey, tesseraKeysPath, err = CreateTesseraKeys(p.ctx, tesseraImage, tesseraKeysOutputDirectory, "", "tm") + _, tesseraPubKey, tesseraKeysPath, err = tessera.CreateTesseraKeys(p.ctx, tesseraImage, tesseraKeysOutputDirectory, "", "tm") if err != nil { return nil, err } diff --git a/internal/blockchain/ethereum/quorum/private_transaction_manager.go b/internal/blockchain/ethereum/tessera/tessera.go similarity index 99% rename from internal/blockchain/ethereum/quorum/private_transaction_manager.go rename to internal/blockchain/ethereum/tessera/tessera.go index 421404bd..251b6fc0 100644 --- a/internal/blockchain/ethereum/quorum/private_transaction_manager.go +++ b/internal/blockchain/ethereum/tessera/tessera.go @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package quorum +package tessera import ( "context" @@ -32,7 +32,6 @@ var DockerEntrypoint = "docker-entrypoint.sh" var TmQ2tPort = "9101" var TmTpPort = "9080" var TmP2pPort = "9000" -var QuorumPort = "8545" type PrivateKeyData struct { Bytes string `json:"bytes"` diff --git a/internal/blockchain/ethereum/quorum/private_transaction_manager_test.go b/internal/blockchain/ethereum/tessera/tessera_test.go similarity index 99% rename from internal/blockchain/ethereum/quorum/private_transaction_manager_test.go rename to internal/blockchain/ethereum/tessera/tessera_test.go index 938f7604..d96422cc 100644 --- a/internal/blockchain/ethereum/quorum/private_transaction_manager_test.go +++ b/internal/blockchain/ethereum/tessera/tessera_test.go @@ -1,4 +1,4 @@ -package quorum +package tessera import ( "context"