Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add relayer #124

Merged
merged 14 commits into from
Aug 30, 2024
14 changes: 14 additions & 0 deletions avalanche/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
package avalanche

import (
"fmt"
"strings"

"github.com/ava-labs/avalanche-tooling-sdk-go/utils"
"github.com/ava-labs/avalanchego/genesis"
"github.com/ava-labs/avalanchego/ids"
Expand Down Expand Up @@ -94,6 +97,17 @@ func (n Network) GenesisParams() *genesis.Params {
return nil
}

func (n Network) BlockchainEndpoint(blockchainID string) string {
return fmt.Sprintf("%s/ext/bc/%s/rpc", n.Endpoint, blockchainID)
}

func (n Network) BlockchainWSEndpoint(blockchainID string) string {
trimmedURI := n.Endpoint
trimmedURI = strings.TrimPrefix(trimmedURI, "http://")
trimmedURI = strings.TrimPrefix(trimmedURI, "https://")
return fmt.Sprintf("ws://%s/ext/bc/%s/ws", trimmedURI, blockchainID)
}

func (n Network) GetMinStakingAmount() (uint64, error) {
pClient := platformvm.NewClient(n.Endpoint)
ctx, cancel := utils.GetAPIContext()
Expand Down
6 changes: 4 additions & 2 deletions constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ const (
BLSKeyFileName = "signer.key"

// github
AvaLabsOrg = "ava-labs"
TeleporterRepoName = "teleporter"
AvaLabsOrg = "ava-labs"
ICMRepoName = "teleporter"
RelayerRepoName = "awm-relayer"
RelayerBinName = "awm-relayer"
)
27 changes: 26 additions & 1 deletion evm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,32 @@ func EstimateBaseFee(
)
}

func FundAddress(
func SetMinBalance(
client ethclient.Client,
privateKey string,
address string,
requiredMinBalance *big.Int,
) error {
balance, err := GetAddressBalance(client, address)
if err != nil {
return err
}
if balance.Cmp(requiredMinBalance) < 0 {
toFund := big.NewInt(0).Sub(requiredMinBalance, balance)
err := Transfer(
client,
privateKey,
address,
toFund,
)
if err != nil {
return err
}
}
return nil
}

func Transfer(
client ethclient.Client,
sourceAddressPrivateKeyStr string,
targetAddressStr string,
Expand Down
21 changes: 16 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
module github.com/ava-labs/avalanche-tooling-sdk-go

go 1.21.10
go 1.21.11

toolchain go1.22.1
toolchain go1.22.6

require (
github.com/ava-labs/avalanchego v1.11.5
github.com/ava-labs/awm-relayer v1.3.3
github.com/ava-labs/coreth v0.13.3-rc.2
github.com/ava-labs/subnet-evm v0.6.4
github.com/aws/aws-sdk-go-v2 v1.30.0
Expand All @@ -16,14 +17,24 @@ require (
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.24.0
golang.org/x/exp v0.0.0-20231127185646-65229373498e
golang.org/x/mod v0.20.0
golang.org/x/net v0.26.0
golang.org/x/sync v0.7.0
google.golang.org/api v0.182.0
)

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
github.com/ava-labs/teleporter v1.0.1 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.32.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.16.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

require (
Expand Down
329 changes: 329 additions & 0 deletions go.sum

Large diffs are not rendered by default.

172 changes: 172 additions & 0 deletions install/archive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// Copyright (C) 2022, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package install

import (
"archive/tar"
"archive/zip"
"bytes"
"compress/gzip"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"

"github.com/ava-labs/avalanche-tooling-sdk-go/constants"
)

type ArchiveKind int64

const (
UndefinedArchive ArchiveKind = iota
Zip
TarGz
)

const maxCopy = 2147483648 // 2 GB

// Sanitize archive file pathing from "G305: Zip Slip vulnerability"
func sanitizeArchivePath(d, t string) (v string, err error) {
v = filepath.Join(d, t)
if strings.HasPrefix(v, filepath.Clean(d)) {
return v, nil
}

return "", fmt.Errorf("%s: %s", "content filepath is tainted", t)
}

// ExtractArchive extracts the archive given as bytes slice [archive], into [outputDir]
func ExtractArchive(kind ArchiveKind, archive []byte, outputDir string) error {
if err := os.MkdirAll(outputDir, constants.DefaultPerms755); err != nil {
return err
}
switch kind {
case Zip:
return extractZip(archive, outputDir)
case TarGz:
return extractTarGz(archive, outputDir)
}
return fmt.Errorf("unsupported archive kind: %d", kind)
}

// extractZip expects a byte stream of a zip file
func extractZip(zipfile []byte, outputDir string) error {
bytesReader := bytes.NewReader(zipfile)
zipReader, err := zip.NewReader(bytesReader, int64(len(zipfile)))
if err != nil {
return fmt.Errorf("failed creating zip reader from binary stream: %w", err)
}

// Closure to address file descriptors issue, uses Close to to not leave open descriptors
extractAndWriteFile := func(f *zip.File) error {
rc, err := f.Open()
if err != nil {
return fmt.Errorf("failed opening zip file: %w", err)
}

// check for zip slip
path, err := sanitizeArchivePath(outputDir, f.Name)
if err != nil {
return err
}

if f.FileInfo().IsDir() {
if err := os.MkdirAll(path, f.Mode()); err != nil {
return fmt.Errorf("failed creating directory from zip entry: %w", err)
}
} else {
if err := os.MkdirAll(filepath.Dir(path), f.Mode()); err != nil {
return fmt.Errorf("failed creating file from zip entry: %w", err)
}
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return fmt.Errorf("failed opening file from zip entry: %w", err)
}

_, err = io.CopyN(f, rc, maxCopy)
if err != nil && !errors.Is(err, io.EOF) {
return fmt.Errorf("failed writing zip file entry to disk: %w", err)
}
if err := f.Close(); err != nil {
return err
}
}
if err := rc.Close(); err != nil {
return err
}
return nil
}

for _, f := range zipReader.File {
err := extractAndWriteFile(f)
if err != nil {
return err
}
}

return nil
}

// extractTarGz expects a byte array in targz format
func extractTarGz(targz []byte, outputDir string) error {
byteReader := bytes.NewReader(targz)
uncompressedStream, err := gzip.NewReader(byteReader)
if err != nil {
return fmt.Errorf("failed creating gzip reader from avalanchego binary stream: %w", err)
}

tarReader := tar.NewReader(uncompressedStream)
for {
header, err := tarReader.Next()
switch {
// if no more files are found return
case errors.Is(err, io.EOF):
return nil
case err != nil:
return fmt.Errorf("failed reading next tar entry: %w", err)
// if the header is nil, just skip it (not sure how this happens)
case header == nil:
continue
}

// the target location where the dir/file should be created
// check for zip slip
target, err := sanitizeArchivePath(outputDir, header.Name)
if err != nil {
return err
}

// check the file type
switch header.Typeflag {
// if its a dir and it doesn't exist create it
case tar.TypeDir:
if _, err := os.Stat(target); err != nil {
if err := os.MkdirAll(target, constants.DefaultPerms755); err != nil {
return fmt.Errorf("failed creating directory from tar entry %w", err)
}
}
// if it's a file create it
case tar.TypeReg:
// if the containing directory doesn't exist yet, create it
containingDir := filepath.Dir(target)
if err := os.MkdirAll(containingDir, constants.DefaultPerms755); err != nil {
return fmt.Errorf("failed creating directory from tar entry %w", err)
}
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
if err != nil {
return fmt.Errorf("failed opening new file from tar entry %w", err)
}
// copy over contents
if _, err := io.CopyN(f, tarReader, maxCopy); err != nil && !errors.Is(err, io.EOF) {
return fmt.Errorf("failed writing tar entry contents to disk: %w", err)
}
// manually close here after each file operation; defering would cause each file close
// to wait until all operations have completed.
if err := f.Close(); err != nil {
return err
}
}
}
}
Loading
Loading