Skip to content

Commit

Permalink
Point ERC20/ERC721 connector at deployed contract address
Browse files Browse the repository at this point in the history
The entire docker-compose.yml file will now be rewritten after first-time setup
is complete. This allows it to pick up on new things such as deployed contracts.

Signed-off-by: Andrew Richardson <andrew.richardson@kaleido.io>
  • Loading branch information
awrichar committed Apr 27, 2022
1 parent f3ee3c5 commit a10d0b1
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 75 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ require (
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988 // indirect
golang.org/x/text v0.3.4 // indirect
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
2 changes: 1 addition & 1 deletion internal/blockchain/ethereum/ethconnect/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

"github.com/hyperledger/firefly-cli/pkg/types"
"github.com/miracl/conflate"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)

type Config struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/blockchain/fabric/cryptogen_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package fabric
import (
"io/ioutil"

"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)

type Template struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/blockchain/fabric/fabconnect/fabconnect_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package fabconnect
import (
"io/ioutil"

"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)

type FabconnectConfig struct {
Expand Down
6 changes: 3 additions & 3 deletions internal/blockchain/fabric/fabric_docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func GenerateDockerServiceDefinitions(s *types.Stack) []*docker.ServiceDefinitio
Service: &docker.Service{
Image: FabricCAImageName,
ContainerName: fmt.Sprintf("%s_fabric_ca", s.Name),
Environment: map[string]string{
Environment: map[string]interface{}{
"FABRIC_CA_HOME": "/etc/hyperledger/fabric-ca-server",
"FABRIC_CA_SERVER_CA_NAME": "fabric_ca",
"FABRIC_CA_SERVER_PORT": "7054",
Expand All @@ -57,7 +57,7 @@ func GenerateDockerServiceDefinitions(s *types.Stack) []*docker.ServiceDefinitio
Service: &docker.Service{
Image: FabricOrdererImageName,
ContainerName: fmt.Sprintf("%s_fabric_orderer", s.Name),
Environment: map[string]string{
Environment: map[string]interface{}{
"FABRIC_LOGGING_SPEC": "INFO",
"ORDERER_GENERAL_LISTENADDRESS": "0.0.0.0",
"ORDERER_GENERAL_LISTENPORT": "7050",
Expand Down Expand Up @@ -103,7 +103,7 @@ func GenerateDockerServiceDefinitions(s *types.Stack) []*docker.ServiceDefinitio
Service: &docker.Service{
Image: FabricPeerImageName,
ContainerName: fmt.Sprintf("%s_fabric_peer", s.Name),
Environment: map[string]string{
Environment: map[string]interface{}{
"CORE_VM_ENDPOINT": "unix:///host/var/run/docker.sock",
"CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE": fmt.Sprintf("%s_default", s.Name),
"FABRIC_LOGGING_SPEC": "INFO",
Expand Down
2 changes: 1 addition & 1 deletion internal/blockchain/fabric/network_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package fabric
import (
"io/ioutil"

"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)

type Registrar struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/core/firefly_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

"github.com/hyperledger/firefly-cli/pkg/types"
"github.com/miracl/conflate"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)

type LogConfig struct {
Expand Down
8 changes: 4 additions & 4 deletions internal/docker/docker_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type Service struct {
Build string `yaml:"build,omitempty"`
User string `yaml:"user,omitempty"`
Command string `yaml:"command,omitempty"`
Environment map[string]string `yaml:"environment,omitempty"`
Environment map[string]interface{} `yaml:"environment,omitempty"`
Volumes []string `yaml:"volumes,omitempty"`
Ports []string `yaml:"ports,omitempty"`
DependsOn map[string]map[string]string `yaml:"depends_on,omitempty"`
Expand Down Expand Up @@ -107,7 +107,7 @@ func CreateDockerCompose(s *types.Stack) *DockerComposeConfig {
Image: constants.PostgresImageName,
ContainerName: fmt.Sprintf("%s_postgres_%s", s.Name, member.ID),
Ports: []string{fmt.Sprintf("%d:5432", member.ExposedDatabasePort)},
Environment: map[string]string{
Environment: map[string]interface{}{
"POSTGRES_PASSWORD": "f1refly",
"PGDATA": "/var/lib/postgresql/data/pgdata",
},
Expand All @@ -132,7 +132,7 @@ func CreateDockerCompose(s *types.Stack) *DockerComposeConfig {
fmt.Sprintf("%d:5001", member.ExposedIPFSApiPort),
fmt.Sprintf("%d:8080", member.ExposedIPFSGWPort),
},
Environment: map[string]string{
Environment: map[string]interface{}{
"IPFS_SWARM_KEY": s.SwarmKey,
"LIBP2P_FORCE_PNET": "1",
},
Expand All @@ -157,7 +157,7 @@ func CreateDockerCompose(s *types.Stack) *DockerComposeConfig {
Image: constants.SandboxImageName,
ContainerName: fmt.Sprintf("%s_sandbox_%s", s.Name, member.ID),
Ports: []string{fmt.Sprintf("%d:3001", member.ExposedSandboxPort)},
Environment: map[string]string{
Environment: map[string]interface{}{
"FF_ENDPOINT": fmt.Sprintf("http://firefly_core_%d:%d", *member.Index, member.ExposedFireflyPort),
},
}
Expand Down
92 changes: 35 additions & 57 deletions internal/stacks/stack_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,19 @@ import (
"github.com/hyperledger/firefly-cli/pkg/types"
"github.com/miracl/conflate"

"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"

"github.com/hyperledger/firefly-cli/internal/log"

"github.com/otiai10/copy"
)

type StackManager struct {
Log log.Logger
Stack *types.Stack
blockchainProvider blockchain.IBlockchainProvider
tokenProviders []tokens.ITokensProvider
fireflyCoreEntrypoints [][]string
IsOldFileStructure bool
Log log.Logger
Stack *types.Stack
blockchainProvider blockchain.IBlockchainProvider
tokenProviders []tokens.ITokensProvider
IsOldFileStructure bool
}

func ListStacks() ([]string, error) {
Expand Down Expand Up @@ -143,6 +142,19 @@ func (s *StackManager) InitStack(stackName string, memberCount int, options *typ
s.Stack.State.Accounts[i] = s.Stack.Members[i].Account
}
}

if err := s.ensureInitDirectories(); err != nil {
return err
}

compose := s.buildDockerCompose()
if err := s.writeDockerCompose(s.Stack.InitDir, compose); err != nil {
return fmt.Errorf("failed to write docker-compose.yml: %s", err)
}
return s.writeConfig(options)
}

func (s *StackManager) buildDockerCompose() *docker.DockerComposeConfig {
compose := docker.CreateDockerCompose(s.Stack)
extraServices := s.blockchainProvider.GetDockerServiceDefinitions()
for i, tp := range s.tokenProviders {
Expand All @@ -168,14 +180,7 @@ func (s *StackManager) InitStack(stackName string, memberCount int, options *typ
}
}
}

if err := s.ensureInitDirectories(); err != nil {
return err
}
if err := s.writeDockerCompose(s.Stack.InitDir, compose); err != nil {
return fmt.Errorf("failed to write docker-compose.yml: %s", err)
}
return s.writeConfig(options)
return compose
}

func CheckExists(stackName string) (bool, error) {
Expand Down Expand Up @@ -344,7 +349,6 @@ func (s *StackManager) writeDockerCompose(workingDir string, compose *docker.Doc
if err != nil {
return err
}

return ioutil.WriteFile(filepath.Join(workingDir, "docker-compose.yml"), bytes, 0755)
}

Expand Down Expand Up @@ -743,6 +747,7 @@ func (s *StackManager) runFirstTimeSetup(verbose bool, options *types.StartOptio
return messages, err
}

// Re-write the docker-compose config to temporariliy short-circuit the core runtimes
if err := s.disableFireflyCoreContainers(verbose, s.Stack.RuntimeDir); err != nil {
return messages, err
}
Expand Down Expand Up @@ -812,12 +817,20 @@ func (s *StackManager) runFirstTimeSetup(verbose bool, options *types.StartOptio
}
}

if err := s.enableFireflyCoreContainers(verbose, s.Stack.RuntimeDir); err != nil {
// Re-write the docker-compose config again, in case new values have been added
compose := s.buildDockerCompose()
if err := s.writeDockerCompose(s.Stack.RuntimeDir, compose); err != nil {
return messages, err
}

// Bring up the FireFly Core containers now that we've finalized the runtime config
docker.RunDockerComposeCommand(s.Stack.InitDir, verbose, verbose, "-p", s.Stack.Name, "up", "-d")
// Restart all containers now that we've finalized the runtime config
s.Log.Info("restarting containers")
if err := docker.RunDockerComposeCommand(s.Stack.InitDir, verbose, verbose, "-p", s.Stack.Name, "stop"); err != nil {
return messages, err
}
if err := s.runStartupSequence(s.Stack.RuntimeDir, verbose, false); err != nil {
return messages, err
}

if err := s.ensureFireflyNodesUp(true); err != nil {
return messages, err
Expand Down Expand Up @@ -905,49 +918,14 @@ func (s *StackManager) PrintStackInfo(verbose bool) error {
}

func (s *StackManager) disableFireflyCoreContainers(verbose bool, workingDir string) error {
d, err := ioutil.ReadFile(filepath.Join(workingDir, "docker-compose.yml"))
if err != nil {
return err
}
var dockerComposeYAML *docker.DockerComposeConfig
if err := yaml.Unmarshal(d, &dockerComposeYAML); err != nil {
return err
}

// Cache any currently set entrypoint
s.fireflyCoreEntrypoints = make([][]string, len(s.Stack.Members))
compose := s.buildDockerCompose()
for _, member := range s.Stack.Members {
if !member.External {
s.fireflyCoreEntrypoints[*member.Index] = dockerComposeYAML.Services[fmt.Sprintf("firefly_core_%v", *member.Index)].EntryPoint
// Temporarily set the entrypoint to not run anything
dockerComposeYAML.Services[fmt.Sprintf("firefly_core_%v", *member.Index)].EntryPoint = []string{"/bin/sh", "-c", "exit", "0"}
}
}
return s.writeDockerCompose(workingDir, dockerComposeYAML)
}

func (s *StackManager) enableFireflyCoreContainers(verbose bool, workingDir string) error {
d, err := ioutil.ReadFile(filepath.Join(workingDir, "docker-compose.yml"))
if err != nil {
return err
}
var dockerComposeYAML *docker.DockerComposeConfig
if err := yaml.Unmarshal(d, &dockerComposeYAML); err != nil {
return err
}

for _, member := range s.Stack.Members {
if !member.External {
// If there was a cached entrypoint for this service, restore it
// Otherwise default to the entrypoint of "firefly" as defined in the Dockerfile for FireFly Core
entrypoint := []string{"firefly"}
if len(s.fireflyCoreEntrypoints[*member.Index]) > 0 {
entrypoint = s.fireflyCoreEntrypoints[*member.Index]
}
dockerComposeYAML.Services[fmt.Sprintf("firefly_core_%v", *member.Index)].EntryPoint = entrypoint
compose.Services[fmt.Sprintf("firefly_core_%v", *member.Index)].EntryPoint = []string{"/bin/sh", "-c", "exit", "0"}
}
}
return s.writeDockerCompose(workingDir, dockerComposeYAML)
return s.writeDockerCompose(workingDir, compose)
}

func (s *StackManager) patchFireFlyCoreConfigs(verbose bool, workingDir string, newConfig *core.FireflyConfig) error {
Expand Down
2 changes: 1 addition & 1 deletion internal/tokens/erc1155/erc1155_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (p *ERC1155Provider) GetDockerServiceDefinitions(tokenIdx int) []*docker.Se
Image: p.Stack.VersionManifest.TokensERC1155.GetDockerImageString(),
ContainerName: fmt.Sprintf("%s_tokens_%v_%v", p.Stack.Name, i, tokenIdx),
Ports: []string{fmt.Sprintf("%d:3000", member.ExposedTokensPorts[tokenIdx])},
Environment: map[string]string{
Environment: map[string]interface{}{
"ETHCONNECT_URL": p.getEthconnectURL(member, member.ExposedTokensPorts[tokenIdx]),
"ETHCONNECT_TOPIC": connectorName,
"AUTO_INIT": "false",
Expand Down
6 changes: 5 additions & 1 deletion internal/tokens/erc20erc721/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import (
"github.com/hyperledger/firefly-cli/pkg/types"
)

func contractName(tokenIndex int) string {
return fmt.Sprintf("erc20erc721_TokenFactory_%d", tokenIndex)
}

func DeployContracts(s *types.Stack, log log.Logger, verbose bool, tokenIndex int) (*types.ContractDeploymentResult, error) {
var containerName string
for _, member := range s.Members {
Expand All @@ -52,7 +56,7 @@ func DeployContracts(s *types.Stack, log log.Logger, verbose bool, tokenIndex in
result := &types.ContractDeploymentResult{
Message: fmt.Sprintf("Deployed TokenFactory contract to: %s\nSource code for this contract can be found at %s", contractAddress, filepath.Join(s.RuntimeDir, "contracts", "source")),
DeployedContract: &types.DeployedContract{
Name: "TokenFactory",
Name: contractName(tokenIndex),
Location: map[string]string{"address": contractAddress},
},
}
Expand Down
32 changes: 28 additions & 4 deletions internal/tokens/erc20erc721/erc20_erc721_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/hyperledger/firefly-cli/internal/docker"
"github.com/hyperledger/firefly-cli/internal/log"
"github.com/hyperledger/firefly-cli/pkg/types"
"gopkg.in/yaml.v3"
)

type ERC20ERC721Provider struct {
Expand All @@ -31,6 +32,17 @@ type ERC20ERC721Provider struct {
Stack *types.Stack
}

type HexAddress string

// Explicitly quote hex addresses so that they are interpreted as string (not int)
func (h HexAddress) MarshalYAML() (interface{}, error) {
return yaml.Node{
Value: string(h),
Kind: yaml.ScalarNode,
Style: yaml.DoubleQuotedStyle,
}, nil
}

func (p *ERC20ERC721Provider) DeploySmartContracts(tokenIndex int) (*types.ContractDeploymentResult, error) {
return DeployContracts(p.Stack, p.Log, p.Verbose, tokenIndex)
}
Expand All @@ -50,16 +62,28 @@ func (p *ERC20ERC721Provider) GetDockerServiceDefinitions(tokenIdx int) []*docke
serviceDefinitions := make([]*docker.ServiceDefinition, 0, len(p.Stack.Members))
for i, member := range p.Stack.Members {
connectorName := fmt.Sprintf("tokens_%v_%v", member.ID, tokenIdx)

var factoryAddress HexAddress
for _, contract := range p.Stack.State.DeployedContracts {
if contract.Name == contractName(tokenIdx) {
switch loc := contract.Location.(type) {
case map[string]string:
factoryAddress = HexAddress(loc["address"])
}
}
}

serviceDefinitions = append(serviceDefinitions, &docker.ServiceDefinition{
ServiceName: connectorName,
Service: &docker.Service{
Image: p.Stack.VersionManifest.TokensERC20ERC721.GetDockerImageString(),
ContainerName: fmt.Sprintf("%s_tokens_%v_%v", p.Stack.Name, i, tokenIdx),
Ports: []string{fmt.Sprintf("%d:3000", member.ExposedTokensPorts[tokenIdx])},
Environment: map[string]string{
"ETHCONNECT_URL": p.getEthconnectURL(member, member.ExposedTokensPorts[tokenIdx]),
"ETHCONNECT_TOPIC": connectorName,
"AUTO_INIT": "false",
Environment: map[string]interface{}{
"ETHCONNECT_URL": p.getEthconnectURL(member, member.ExposedTokensPorts[tokenIdx]),
"ETHCONNECT_TOPIC": connectorName,
"FACTORY_CONTRACT_ADDRESS": factoryAddress,
"AUTO_INIT": "false",
},
DependsOn: map[string]map[string]string{
"ethconnect_" + member.ID: {"condition": "service_started"},
Expand Down

0 comments on commit a10d0b1

Please sign in to comment.