From 23e528a0cf752bfb1ede7d4f069cf786c9c56391 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 15 Aug 2024 08:12:07 -0300 Subject: [PATCH 1/2] http get with token + github latest release --- teleporter/teleporter.go | 410 ++++++++++++++++++++++++++++++++++++++- utils/github.go | 77 ++++++++ utils/http.go | 33 ++++ 3 files changed, 518 insertions(+), 2 deletions(-) create mode 100644 utils/github.go create mode 100644 utils/http.go diff --git a/teleporter/teleporter.go b/teleporter/teleporter.go index d58889e..9997636 100644 --- a/teleporter/teleporter.go +++ b/teleporter/teleporter.go @@ -1,8 +1,381 @@ -// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2022, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package teleporter -import "math/big" +import ( + "fmt" + "math/big" + "os" + + "github.com/ava-labs/avalanche-cli/pkg/application" + "github.com/ava-labs/avalanche-cli/pkg/binutils" + "github.com/ava-labs/avalanche-cli/pkg/constants" + "github.com/ava-labs/avalanche-cli/pkg/contract" + "github.com/ava-labs/avalanche-cli/pkg/evm" + "github.com/ava-labs/avalanche-cli/pkg/key" + "github.com/ava-labs/avalanche-cli/pkg/models" + "github.com/ava-labs/avalanche-cli/pkg/ux" + "github.com/ava-labs/avalanche-tooling-sdk-go/utils" + "github.com/ethereum/go-ethereum/common" +) + +const ( + releaseURL = "https://github.com/ava-labs/teleporter/releases/download/%s/" + messengerContractAddressURLFmt = releaseURL + "/TeleporterMessenger_Contract_Address_%s.txt" + messengerDeployerAddressURLFmt = releaseURL + "/TeleporterMessenger_Deployer_Address_%s.txt" + messengerDeployerTxURLFmt = releaseURL + "/TeleporterMessenger_Deployment_Transaction_%s.txt" + registryBytecodeURLFmt = releaseURL + "/TeleporterRegistry_Bytecode_%s.txt" +) + +var ( + // 10 AVAX + messengerDeployerRequiredBalance = big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) + // 600 AVAX + InterchainMessagingPrefundedAddressBalance = big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(600)) +) + +func getTeleporterURLs(version string) (string, string, string, string) { + messengerContractAddressURL := fmt.Sprintf( + messengerContractAddressURLFmt, + version, + version, + ) + messengerDeployerAddressURL := fmt.Sprintf( + messengerDeployerAddressURLFmt, + version, + version, + ) + messengerDeployerTxURL := fmt.Sprintf( + messengerDeployerTxURLFmt, + version, + version, + ) + registryBydecodeURL := fmt.Sprintf( + registryBytecodeURLFmt, + version, + version, + ) + return messengerContractAddressURL, messengerDeployerAddressURL, messengerDeployerTxURL, registryBydecodeURL +} + +type Deployer struct { + messengerContractAddress string + messengerDeployerAddress string + messengerDeployerTx string + registryBydecode string +} + +func (t *Deployer) GetAssets( + teleporterInstallDir string, + version string, +) (string, string, string, string, error) { + if err := t.DownloadAssets(teleporterInstallDir, version); err != nil { + return "", "", "", "", err + } + return t.messengerContractAddress, t.messengerDeployerAddress, t.messengerDeployerTx, t.registryBydecode, nil +} + +func (t *Deployer) CheckAssets() error { + if t.messengerContractAddress == "" || t.messengerDeployerAddress == "" || t.messengerDeployerTx == "" || t.registryBydecode == "" { + return fmt.Errorf("teleporter assets has not been initialized") + } + return nil +} + +func (t *Deployer) SetAssetsFromPaths( + messengerContractAddressPath string, + messengerDeployerAddressPath string, + messengerDeployerTxPath string, + registryBydecodePath string, +) error { + if messengerContractAddressPath != "" { + if bs, err := os.ReadFile(messengerContractAddressPath); err != nil { + return err + } else { + t.messengerContractAddress = string(bs) + } + } + if messengerDeployerAddressPath != "" { + if bs, err := os.ReadFile(messengerDeployerAddressPath); err != nil { + return err + } else { + t.messengerDeployerAddress = string(bs) + } + } + if messengerDeployerTxPath != "" { + if bs, err := os.ReadFile(messengerDeployerTxPath); err != nil { + return err + } else { + t.messengerDeployerTx = string(bs) + } + } + if registryBydecodePath != "" { + if bs, err := os.ReadFile(registryBydecodePath); err != nil { + return err + } else { + t.registryBydecode = string(bs) + } + } + return nil +} + +func (t *Deployer) SetAssets( + messengerContractAddress string, + messengerDeployerAddress string, + messengerDeployerTx string, + registryBydecode string, +) { + if messengerContractAddress != "" { + t.messengerContractAddress = messengerContractAddress + } + if messengerDeployerAddress != "" { + t.messengerDeployerAddress = messengerDeployerAddress + } + if messengerDeployerTx != "" { + t.messengerDeployerTx = messengerDeployerTx + } + if registryBydecode != "" { + t.registryBydecode = registryBydecode + } +} + +func (t *Deployer) DownloadAssets(version string) error { + messengerContractAddressURL, messengerDeployerAddressURL, messengerDeployerTxURL, registryBydecodeURL := getTeleporterURLs(version) + if t.messengerContractAddress == "" { + // get target teleporter messenger contract address + messengerContractAddressBytes, err := utils.HTTPGet(messengerContractAddressURL, "") + if err != nil { + return err + } + t.messengerContractAddress = string(messengerContractAddressBytes) + } + if t.messengerDeployerAddress == "" { + // get teleporter deployer address + messengerDeployerAddressBytes, err := utils.HTTPGet(messengerDeployerAddressURL, "") + if err != nil { + return err + } + t.messengerDeployerAddress = string(messengerDeployerAddressBytes) + } + if t.messengerDeployerTx == "" { + messengerDeployerTxBytes, err := utils.HTTPGet(messengerDeployerTxURL, "") + if err != nil { + return err + } + t.messengerDeployerTx = string(messengerDeployerTxBytes) + } + if t.registryBydecode == "" { + registryBytecodeBytes, err := utils.HTTPGet(registryBydecodeURL, "") + if err != nil { + return err + } + t.registryBydecode = string(registryBytecodeBytes) + } + return nil +} + +func (t *Deployer) Deploy( + subnetName string, + rpcURL string, + privateKey string, + deployMessenger bool, + deployRegistry bool, +) (bool, string, string, error) { + var ( + messengerAddress string + registryAddress string + alreadyDeployed bool + err error + ) + if deployMessenger { + alreadyDeployed, messengerAddress, err = t.DeployMessenger( + subnetName, + rpcURL, + privateKey, + ) + } + if err == nil && deployRegistry { + if !deployMessenger || !alreadyDeployed { + registryAddress, err = t.DeployRegistry(subnetName, rpcURL, privateKey) + } + } + return alreadyDeployed, messengerAddress, registryAddress, err +} + +func (t *Deployer) DeployMessenger( + subnetName string, + rpcURL string, + privateKey string, +) (bool, string, error) { + if err := t.CheckAssets(); err != nil { + return false, "", err + } + // check if contract is already deployed + client, err := evm.GetClient(rpcURL) + if err != nil { + return false, "", err + } + if messengerAlreadyDeployed, err := evm.ContractAlreadyDeployed(client, t.messengerContractAddress); err != nil { + return false, "", fmt.Errorf("failure making a request to %s: %w", rpcURL, err) + } else if messengerAlreadyDeployed { + ux.Logger.PrintToUser("Teleporter Messenger has already been deployed to %s", subnetName) + return true, t.messengerContractAddress, nil + } + // get teleporter deployer balance + messengerDeployerBalance, err := evm.GetAddressBalance( + client, + t.messengerDeployerAddress, + ) + if err != nil { + return false, "", err + } + if messengerDeployerBalance.Cmp(messengerDeployerRequiredBalance) < 0 { + toFund := big.NewInt(0). + Sub(messengerDeployerRequiredBalance, messengerDeployerBalance) + if err := evm.FundAddress( + client, + privateKey, + t.messengerDeployerAddress, + toFund, + ); err != nil { + return false, "", err + } + } + if err := evm.IssueTx(client, t.messengerDeployerTx); err != nil { + return false, "", err + } + ux.Logger.PrintToUser( + "Teleporter Messenger successfully deployed to %s (%s)", + subnetName, + t.messengerContractAddress, + ) + return false, t.messengerContractAddress, nil +} + +func (t *Deployer) DeployRegistry( + subnetName string, + rpcURL string, + privateKey string, +) (string, error) { + if err := t.CheckAssets(); err != nil { + return "", err + } + messengerContractAddress := common.HexToAddress(t.messengerContractAddress) + type ProtocolRegistryEntry struct { + Version *big.Int + ProtocolAddress common.Address + } + constructorInput := []ProtocolRegistryEntry{ + { + Version: big.NewInt(1), + ProtocolAddress: messengerContractAddress, + }, + } + registryAddress, err := contract.DeployContract( + rpcURL, + privateKey, + []byte(t.registryBydecode), + "([(uint256, address)])", + constructorInput, + ) + if err != nil { + return "", err + } + ux.Logger.PrintToUser( + "Teleporter Registry successfully deployed to %s (%s)", + subnetName, + registryAddress, + ) + return registryAddress.Hex(), nil +} + +func getPrivateKey( + app *application.Avalanche, + network models.Network, + keyName string, +) (string, error) { + var ( + err error + k *key.SoftKey + ) + if keyName == "" { + if k, err = key.LoadEwoq(network.ID); err != nil { + return "", err + } + } else { + k, err = key.LoadSoft(network.ID, app.GetKeyPath(keyName)) + if err != nil { + return "", err + } + } + return k.PrivKeyHex(), nil +} + +func SetProposerVM( + app *application.Avalanche, + network models.Network, + blockchainID string, + fundedKeyName string, +) error { + privKeyStr, err := getPrivateKey(app, network, fundedKeyName) + if err != nil { + return err + } + wsEndpoint := network.BlockchainWSEndpoint(blockchainID) + return evm.SetupProposerVM(wsEndpoint, privKeyStr) +} + +func DeployAndFundRelayer( + app *application.Avalanche, + td *Deployer, + network models.Network, + subnetName string, + blockchainID string, + fundedKeyName string, +) (bool, string, string, error) { + privKeyStr, err := getPrivateKey(app, network, fundedKeyName) + if err != nil { + return false, "", "", err + } + endpoint := network.BlockchainEndpoint(blockchainID) + alreadyDeployed, messengerAddress, registryAddress, err := td.Deploy( + subnetName, + endpoint, + privKeyStr, + true, + true, + ) + if err != nil { + return false, "", "", err + } + if !alreadyDeployed { + // get relayer address + relayerAddress, _, err := GetRelayerKeyInfo(app.GetKeyPath(constants.AWMRelayerKeyName)) + if err != nil { + return false, "", "", err + } + // fund relayer + if err := FundRelayer( + endpoint, + privKeyStr, + relayerAddress, + ); err != nil { + return false, "", "", err + } + } + return alreadyDeployed, messengerAddress, registryAddress, err +} + +func getTeleporterKeyInfo( + app *application.Avalanche, + keyName string, +) (string, string, *big.Int, error) { + k, err := key.LoadSoftOrCreate(models.NewLocalNetwork().ID, app.GetKeyPath(keyName)) + if err != nil { + return "", "", nil, err + } + return k.C(), k.PrivKeyHex(), InterchainMessagingPrefundedAddressBalance, nil +} type Info struct { Version string @@ -11,3 +384,36 @@ type Info struct { MessengerDeployerAddress string RelayerAddress string } + +func GetInfo( + app *application.Avalanche, +) (*Info, error) { + var err error + ti := Info{} + ti.FundedAddress, _, ti.FundedBalance, err = getTeleporterKeyInfo( + app, + constants.TeleporterKeyName, + ) + if err != nil { + return nil, err + } + ti.Version, err = app.Downloader.GetLatestReleaseVersion( + binutils.GetGithubLatestReleaseURL(constants.AvaLabsOrg, constants.TeleporterRepoName), + ) + if err != nil { + return nil, err + } + deployer := Deployer{} + _, ti.MessengerDeployerAddress, _, _, err = deployer.GetAssets( + app.GetTeleporterBinDir(), + ti.Version, + ) + if err != nil { + return nil, err + } + ti.RelayerAddress, _, err = GetRelayerKeyInfo(app.GetKeyPath(constants.AWMRelayerKeyName)) + if err != nil { + return nil, err + } + return &ti, nil +} diff --git a/utils/github.go b/utils/github.go new file mode 100644 index 0000000..9081dd8 --- /dev/null +++ b/utils/github.go @@ -0,0 +1,77 @@ +// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. +package utils + +import ( + "encoding/json" + "fmt" + + "golang.org/x/mod/semver" +) + +const githubVersionTagName = "tag_name" + +func GetLatestGithubReleaseURL(org, repo string) string { + return fmt.Sprintf("%s/%s", GetGithubReleasesURL(org, repo), "latest") +} + +func GetGithubReleasesURL(org, repo string) string { + return fmt.Sprintf("https://api.github.com/repos/%s/%s/releases", org, repo) +} + +// GetLatestGithubReleaseVersion returns the latest available release version from github +func GetLatestGithubReleaseVersion(org, repo, authToken string) (string, error) { + url := GetLatestGithubReleaseURL(org, repo) + jsonBytes, err := HTTPGet(url, authToken) + if err != nil { + return "", err + } + + var jsonStr map[string]interface{} + if err := json.Unmarshal(jsonBytes, &jsonStr); err != nil { + return "", fmt.Errorf("failed to unmarshal binary json version string: %w", err) + } + + version := jsonStr[githubVersionTagName].(string) + if !semver.IsValid(version) { + return "", fmt.Errorf("invalid version string: %s", version) + } + + return version, nil +} + +func GetAllGithubReleaseVersions(org, repo, authToken string) ([]string, error) { + url := GetGithubReleasesURL(org, repo) + jsonBytes, err := HTTPGet(url, authToken) + if err != nil { + return nil, err + } + + var releaseArr []map[string]interface{} + if err := json.Unmarshal(jsonBytes, &releaseArr); err != nil { + return nil, fmt.Errorf("failed to unmarshal binary json version string: %w", err) + } + + releases := make([]string, len(releaseArr)) + for i, r := range releaseArr { + version := r[githubVersionTagName].(string) + if !semver.IsValid(version) { + return nil, fmt.Errorf("invalid version string: %s", version) + } + releases[i] = version + } + + return releases, nil +} + +// GetLatestGithubPreReleaseVersion returns the latest available pre release version from github +func GetLatestGithubPreReleaseVersion(org, repo, authToken string) (string, error) { + releases, err := GetAllGithubReleaseVersions(org, repo, authToken) + if err != nil { + return "", err + } + if len(releases) == 0 { + return "", fmt.Errorf("no releases found for org %s repo %s", org, repo) + } + return releases[0], nil +} diff --git a/utils/http.go b/utils/http.go new file mode 100644 index 0000000..2dc157a --- /dev/null +++ b/utils/http.go @@ -0,0 +1,33 @@ +// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. +package utils + +import ( + "fmt" + "io" + "net/http" +) + +func HTTPGet(url, authToken string) ([]byte, error) { + request, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, fmt.Errorf("failed downloading %s: %w", url, err) + } + if authToken != "" { + // to avoid rate limitation issues + request.Header.Set("authorization", fmt.Sprintf("Bearer %s", authToken)) + } + resp, err := http.DefaultClient.Do(request) + if err != nil { + return nil, fmt.Errorf("failed downloading %s: %w", url, err) + } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed downloading %s: unexpected http status code: %d", url, resp.StatusCode) + } + defer resp.Body.Close() + bs, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed downloading %s: %w", url, err) + } + return bs, nil +} From a064ff8d288d860f9f6dcebf591991abab134a57 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 15 Aug 2024 12:41:41 -0300 Subject: [PATCH 2/2] lint --- constants/constants.go | 4 + go.mod | 1 + go.sum | 2 + teleporter/teleporter.go | 348 +++++++++------------------------------ 4 files changed, 81 insertions(+), 274 deletions(-) diff --git a/constants/constants.go b/constants/constants.go index 9b7f88d..db382c2 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -79,4 +79,8 @@ const ( StakerCertFileName = "staker.crt" StakerKeyFileName = "staker.key" BLSKeyFileName = "signer.key" + + // github + AvaLabsOrg = "ava-labs" + TeleporterRepoName = "teleporter" ) diff --git a/go.mod b/go.mod index 66338ed..0e34ac7 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( require ( github.com/onsi/gomega v1.33.1 // indirect + golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.26.0 // indirect ) diff --git a/go.sum b/go.sum index 33da1dd..f8cb748 100644 --- a/go.sum +++ b/go.sum @@ -588,6 +588,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/teleporter/teleporter.go b/teleporter/teleporter.go index 9997636..cb08230 100644 --- a/teleporter/teleporter.go +++ b/teleporter/teleporter.go @@ -7,14 +7,8 @@ import ( "math/big" "os" - "github.com/ava-labs/avalanche-cli/pkg/application" - "github.com/ava-labs/avalanche-cli/pkg/binutils" - "github.com/ava-labs/avalanche-cli/pkg/constants" - "github.com/ava-labs/avalanche-cli/pkg/contract" - "github.com/ava-labs/avalanche-cli/pkg/evm" - "github.com/ava-labs/avalanche-cli/pkg/key" - "github.com/ava-labs/avalanche-cli/pkg/models" - "github.com/ava-labs/avalanche-cli/pkg/ux" + "github.com/ava-labs/avalanche-tooling-sdk-go/constants" + "github.com/ava-labs/avalanche-tooling-sdk-go/evm" "github.com/ava-labs/avalanche-tooling-sdk-go/utils" "github.com/ethereum/go-ethereum/common" ) @@ -28,239 +22,179 @@ const ( ) var ( - // 10 AVAX + // 10 TOKENS messengerDeployerRequiredBalance = big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) - // 600 AVAX - InterchainMessagingPrefundedAddressBalance = big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(600)) + // 600 TOKENS + ICMRequiredBalance = big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(600)) ) -func getTeleporterURLs(version string) (string, string, string, string) { - messengerContractAddressURL := fmt.Sprintf( - messengerContractAddressURLFmt, - version, - version, - ) - messengerDeployerAddressURL := fmt.Sprintf( - messengerDeployerAddressURLFmt, - version, - version, - ) - messengerDeployerTxURL := fmt.Sprintf( - messengerDeployerTxURLFmt, - version, - version, - ) - registryBydecodeURL := fmt.Sprintf( - registryBytecodeURLFmt, - version, - version, - ) - return messengerContractAddressURL, messengerDeployerAddressURL, messengerDeployerTxURL, registryBydecodeURL +func GetLatestVersion() (string, error) { + return utils.GetLatestGithubReleaseVersion(constants.AvaLabsOrg, constants.TeleporterRepoName, "") } -type Deployer struct { - messengerContractAddress string - messengerDeployerAddress string - messengerDeployerTx string - registryBydecode string +func getURLs(version string) (string, string, string, string) { + messengerContractAddressURL := fmt.Sprintf(messengerContractAddressURLFmt, version, version) + messengerDeployerAddressURL := fmt.Sprintf(messengerDeployerAddressURLFmt, version, version) + messengerDeployerTxURL := fmt.Sprintf(messengerDeployerTxURLFmt, version, version) + registryBytecodeURL := fmt.Sprintf(registryBytecodeURLFmt, version, version) + return messengerContractAddressURL, messengerDeployerAddressURL, messengerDeployerTxURL, registryBytecodeURL } -func (t *Deployer) GetAssets( - teleporterInstallDir string, - version string, -) (string, string, string, string, error) { - if err := t.DownloadAssets(teleporterInstallDir, version); err != nil { - return "", "", "", "", err - } - return t.messengerContractAddress, t.messengerDeployerAddress, t.messengerDeployerTx, t.registryBydecode, nil +type Deployer struct { + messengerContractAddress []byte + messengerDeployerAddress []byte + messengerDeployerTx []byte + registryBytecode []byte } func (t *Deployer) CheckAssets() error { - if t.messengerContractAddress == "" || t.messengerDeployerAddress == "" || t.messengerDeployerTx == "" || t.registryBydecode == "" { + if len(t.messengerContractAddress) == 0 || len(t.messengerDeployerAddress) == 0 || len(t.messengerDeployerTx) == 0 || len(t.registryBytecode) == 0 { return fmt.Errorf("teleporter assets has not been initialized") } return nil } -func (t *Deployer) SetAssetsFromPaths( +func (t *Deployer) GetAssets() ([]byte, []byte, []byte, []byte) { + return t.messengerContractAddress, t.messengerDeployerAddress, t.messengerDeployerTx, t.registryBytecode +} + +func (t *Deployer) SetAssets( + messengerContractAddress []byte, + messengerDeployerAddress []byte, + messengerDeployerTx []byte, + registryBytecode []byte, +) { + t.messengerContractAddress = messengerContractAddress + t.messengerDeployerAddress = messengerDeployerAddress + t.messengerDeployerTx = messengerDeployerTx + t.registryBytecode = registryBytecode +} + +func (t *Deployer) LoadAssets( messengerContractAddressPath string, messengerDeployerAddressPath string, messengerDeployerTxPath string, - registryBydecodePath string, + registryBytecodePath string, ) error { + var err error if messengerContractAddressPath != "" { - if bs, err := os.ReadFile(messengerContractAddressPath); err != nil { + if t.messengerContractAddress, err = os.ReadFile(messengerContractAddressPath); err != nil { return err - } else { - t.messengerContractAddress = string(bs) } } if messengerDeployerAddressPath != "" { - if bs, err := os.ReadFile(messengerDeployerAddressPath); err != nil { + if t.messengerDeployerAddress, err = os.ReadFile(messengerDeployerAddressPath); err != nil { return err - } else { - t.messengerDeployerAddress = string(bs) } } if messengerDeployerTxPath != "" { - if bs, err := os.ReadFile(messengerDeployerTxPath); err != nil { + if t.messengerDeployerTx, err = os.ReadFile(messengerDeployerTxPath); err != nil { return err - } else { - t.messengerDeployerTx = string(bs) } } - if registryBydecodePath != "" { - if bs, err := os.ReadFile(registryBydecodePath); err != nil { + if registryBytecodePath != "" { + if t.registryBytecode, err = os.ReadFile(registryBytecodePath); err != nil { return err - } else { - t.registryBydecode = string(bs) } } return nil } -func (t *Deployer) SetAssets( - messengerContractAddress string, - messengerDeployerAddress string, - messengerDeployerTx string, - registryBydecode string, -) { - if messengerContractAddress != "" { - t.messengerContractAddress = messengerContractAddress - } - if messengerDeployerAddress != "" { - t.messengerDeployerAddress = messengerDeployerAddress - } - if messengerDeployerTx != "" { - t.messengerDeployerTx = messengerDeployerTx - } - if registryBydecode != "" { - t.registryBydecode = registryBydecode - } -} - func (t *Deployer) DownloadAssets(version string) error { - messengerContractAddressURL, messengerDeployerAddressURL, messengerDeployerTxURL, registryBydecodeURL := getTeleporterURLs(version) - if t.messengerContractAddress == "" { - // get target teleporter messenger contract address - messengerContractAddressBytes, err := utils.HTTPGet(messengerContractAddressURL, "") - if err != nil { - return err - } - t.messengerContractAddress = string(messengerContractAddressBytes) + var err error + messengerContractAddressURL, messengerDeployerAddressURL, messengerDeployerTxURL, registryBytecodeURL := getURLs(version) + if t.messengerContractAddress, err = utils.HTTPGet(messengerContractAddressURL, ""); err != nil { + return err } - if t.messengerDeployerAddress == "" { - // get teleporter deployer address - messengerDeployerAddressBytes, err := utils.HTTPGet(messengerDeployerAddressURL, "") - if err != nil { - return err - } - t.messengerDeployerAddress = string(messengerDeployerAddressBytes) + if t.messengerDeployerAddress, err = utils.HTTPGet(messengerDeployerAddressURL, ""); err != nil { + return err } - if t.messengerDeployerTx == "" { - messengerDeployerTxBytes, err := utils.HTTPGet(messengerDeployerTxURL, "") - if err != nil { - return err - } - t.messengerDeployerTx = string(messengerDeployerTxBytes) + if t.messengerDeployerTx, err = utils.HTTPGet(messengerDeployerTxURL, ""); err != nil { + return err } - if t.registryBydecode == "" { - registryBytecodeBytes, err := utils.HTTPGet(registryBydecodeURL, "") - if err != nil { - return err - } - t.registryBydecode = string(registryBytecodeBytes) + if t.registryBytecode, err = utils.HTTPGet(registryBytecodeURL, ""); err != nil { + return err } return nil } +// Deploys messenger and registry +// If messenger is already deployed, will avoid deploying registry +// (to force, set deployMessenger to false) func (t *Deployer) Deploy( - subnetName string, rpcURL string, privateKey string, deployMessenger bool, deployRegistry bool, ) (bool, string, string, error) { var ( - messengerAddress string - registryAddress string - alreadyDeployed bool - err error + messengerAddress string + registryAddress string + messengerAlreadyDeployed bool + err error ) if deployMessenger { - alreadyDeployed, messengerAddress, err = t.DeployMessenger( - subnetName, + messengerAlreadyDeployed, messengerAddress, err = t.DeployMessenger( rpcURL, privateKey, ) } if err == nil && deployRegistry { - if !deployMessenger || !alreadyDeployed { - registryAddress, err = t.DeployRegistry(subnetName, rpcURL, privateKey) + if !deployMessenger || !messengerAlreadyDeployed { + registryAddress, err = t.DeployRegistry(rpcURL, privateKey) } } - return alreadyDeployed, messengerAddress, registryAddress, err + return messengerAlreadyDeployed, messengerAddress, registryAddress, err } func (t *Deployer) DeployMessenger( - subnetName string, rpcURL string, privateKey string, ) (bool, string, error) { if err := t.CheckAssets(); err != nil { return false, "", err } - // check if contract is already deployed client, err := evm.GetClient(rpcURL) if err != nil { return false, "", err } - if messengerAlreadyDeployed, err := evm.ContractAlreadyDeployed(client, t.messengerContractAddress); err != nil { + if messengerAlreadyDeployed, err := evm.ContractAlreadyDeployed(client, string(t.messengerContractAddress)); err != nil { return false, "", fmt.Errorf("failure making a request to %s: %w", rpcURL, err) } else if messengerAlreadyDeployed { - ux.Logger.PrintToUser("Teleporter Messenger has already been deployed to %s", subnetName) - return true, t.messengerContractAddress, nil + return true, string(t.messengerContractAddress), nil } - // get teleporter deployer balance messengerDeployerBalance, err := evm.GetAddressBalance( client, - t.messengerDeployerAddress, + string(t.messengerDeployerAddress), ) if err != nil { return false, "", err } if messengerDeployerBalance.Cmp(messengerDeployerRequiredBalance) < 0 { - toFund := big.NewInt(0). - Sub(messengerDeployerRequiredBalance, messengerDeployerBalance) + toFund := big.NewInt(0).Sub(messengerDeployerRequiredBalance, messengerDeployerBalance) if err := evm.FundAddress( client, privateKey, - t.messengerDeployerAddress, + string(t.messengerDeployerAddress), toFund, ); err != nil { return false, "", err } } - if err := evm.IssueTx(client, t.messengerDeployerTx); err != nil { + if err := evm.IssueTx(client, string(t.messengerDeployerTx)); err != nil { return false, "", err } - ux.Logger.PrintToUser( - "Teleporter Messenger successfully deployed to %s (%s)", - subnetName, - t.messengerContractAddress, - ) - return false, t.messengerContractAddress, nil + return false, string(t.messengerContractAddress), nil } func (t *Deployer) DeployRegistry( - subnetName string, rpcURL string, privateKey string, ) (string, error) { if err := t.CheckAssets(); err != nil { return "", err } - messengerContractAddress := common.HexToAddress(t.messengerContractAddress) + messengerContractAddress := common.HexToAddress(string(t.messengerContractAddress)) type ProtocolRegistryEntry struct { Version *big.Int ProtocolAddress common.Address @@ -271,149 +205,15 @@ func (t *Deployer) DeployRegistry( ProtocolAddress: messengerContractAddress, }, } - registryAddress, err := contract.DeployContract( + registryAddress, err := evm.DeployContract( rpcURL, privateKey, - []byte(t.registryBydecode), + t.registryBytecode, "([(uint256, address)])", constructorInput, ) if err != nil { return "", err } - ux.Logger.PrintToUser( - "Teleporter Registry successfully deployed to %s (%s)", - subnetName, - registryAddress, - ) return registryAddress.Hex(), nil } - -func getPrivateKey( - app *application.Avalanche, - network models.Network, - keyName string, -) (string, error) { - var ( - err error - k *key.SoftKey - ) - if keyName == "" { - if k, err = key.LoadEwoq(network.ID); err != nil { - return "", err - } - } else { - k, err = key.LoadSoft(network.ID, app.GetKeyPath(keyName)) - if err != nil { - return "", err - } - } - return k.PrivKeyHex(), nil -} - -func SetProposerVM( - app *application.Avalanche, - network models.Network, - blockchainID string, - fundedKeyName string, -) error { - privKeyStr, err := getPrivateKey(app, network, fundedKeyName) - if err != nil { - return err - } - wsEndpoint := network.BlockchainWSEndpoint(blockchainID) - return evm.SetupProposerVM(wsEndpoint, privKeyStr) -} - -func DeployAndFundRelayer( - app *application.Avalanche, - td *Deployer, - network models.Network, - subnetName string, - blockchainID string, - fundedKeyName string, -) (bool, string, string, error) { - privKeyStr, err := getPrivateKey(app, network, fundedKeyName) - if err != nil { - return false, "", "", err - } - endpoint := network.BlockchainEndpoint(blockchainID) - alreadyDeployed, messengerAddress, registryAddress, err := td.Deploy( - subnetName, - endpoint, - privKeyStr, - true, - true, - ) - if err != nil { - return false, "", "", err - } - if !alreadyDeployed { - // get relayer address - relayerAddress, _, err := GetRelayerKeyInfo(app.GetKeyPath(constants.AWMRelayerKeyName)) - if err != nil { - return false, "", "", err - } - // fund relayer - if err := FundRelayer( - endpoint, - privKeyStr, - relayerAddress, - ); err != nil { - return false, "", "", err - } - } - return alreadyDeployed, messengerAddress, registryAddress, err -} - -func getTeleporterKeyInfo( - app *application.Avalanche, - keyName string, -) (string, string, *big.Int, error) { - k, err := key.LoadSoftOrCreate(models.NewLocalNetwork().ID, app.GetKeyPath(keyName)) - if err != nil { - return "", "", nil, err - } - return k.C(), k.PrivKeyHex(), InterchainMessagingPrefundedAddressBalance, nil -} - -type Info struct { - Version string - FundedAddress string - FundedBalance *big.Int - MessengerDeployerAddress string - RelayerAddress string -} - -func GetInfo( - app *application.Avalanche, -) (*Info, error) { - var err error - ti := Info{} - ti.FundedAddress, _, ti.FundedBalance, err = getTeleporterKeyInfo( - app, - constants.TeleporterKeyName, - ) - if err != nil { - return nil, err - } - ti.Version, err = app.Downloader.GetLatestReleaseVersion( - binutils.GetGithubLatestReleaseURL(constants.AvaLabsOrg, constants.TeleporterRepoName), - ) - if err != nil { - return nil, err - } - deployer := Deployer{} - _, ti.MessengerDeployerAddress, _, _, err = deployer.GetAssets( - app.GetTeleporterBinDir(), - ti.Version, - ) - if err != nil { - return nil, err - } - ti.RelayerAddress, _, err = GetRelayerKeyInfo(app.GetKeyPath(constants.AWMRelayerKeyName)) - if err != nil { - return nil, err - } - return &ti, nil -}