Forráskód Böngészése

e2e: remove

These were testing the token bridge and do not currently pass
(or even compile). We will bring back later some of the code.

Change-Id: I34e9ae5aa901c9b20572d1fc8d87a599fa49ad93
Leo 4 éve
szülő
commit
01564150db
7 módosított fájl, 1 hozzáadás és 1186 törlés
  1. 1 5
      CONTRIBUTING.md
  2. 0 5
      DEVELOP.md
  3. 0 262
      bridge/e2e/e2e_test.go
  4. 0 190
      bridge/e2e/eth.go
  5. 0 149
      bridge/e2e/k8s.go
  6. 0 184
      bridge/e2e/solana.go
  7. 0 391
      bridge/e2e/terra.go

+ 1 - 5
CONTRIBUTING.md

@@ -17,10 +17,6 @@ and code reviews are our most important tools to accomplish that.
   
 - Releases are first tested on a testnet. This involves coordination with the mainnet DAO running the nodes.
 
-- We aim for close to 100% test coverage on all critical paths. Most of Wormhole's complexity is in the
-  external interfaces, therefore, we primarily rely on software-in-the-loop E2E testing that exercises
-  the entire path. Where applicable, we also use faster unit tests for invariant checking.
-  
 - Commits should be small and have a meaningful commit message. One commit should, roughly, be "one idea" and
   be as atomic as possible. A feature can consist of many such commits.
   
@@ -50,7 +46,7 @@ The answer is... maybe? The following things are needed in order to fully suppor
 - The smart contract needs to be built and audited. In some cases, existing contracts can be used, like with
   EVM-compatible chains.
   
-- Support for observing the chain needs to be added to guardiand, along with E2E tests.
+- Support for observing the chain needs to be added to guardiand.
 
 - Web wallet integration needs to be built to actually interact with Wormhole.
 

+ 0 - 5
DEVELOP.md

@@ -61,11 +61,6 @@ Generate test Solana -> Ethereum transfers:
 
     scripts/send-solana-lockups.sh
 
-Run end-to-end tests:
-
-    cd bridge
-    go test github.com/certusone/wormhole/bridge/e2e
-
 Adjust number of nodes in running cluster: (this is only useful if you want to test scenarios where the number
 of nodes diverges from the guardian set - otherwise, `tilt down --delete-namespaces` and restart the cluster)
 

+ 0 - 262
bridge/e2e/e2e_test.go

@@ -1,262 +0,0 @@
-package e2e
-
-import (
-	"context"
-	"testing"
-	"time"
-
-	"github.com/ethereum/go-ethereum/accounts/abi/bind"
-	"github.com/mr-tron/base58"
-	"k8s.io/client-go/kubernetes"
-
-	"github.com/certusone/wormhole/bridge/pkg/devnet"
-	"github.com/certusone/wormhole/bridge/pkg/ethereum"
-	"github.com/certusone/wormhole/bridge/pkg/vaa"
-	"github.com/ethereum/go-ethereum/ethclient"
-)
-
-func setup(t *testing.T) (*kubernetes.Clientset, *ethclient.Client, *bind.TransactOpts, *TerraClient) {
-	// List of pods we need in a ready state before we can run tests.
-	want := []string{
-		// Our test guardian set.
-		"guardian-0",
-		//"guardian-1",
-		//"guardian-2",
-		//"guardian-3",
-		//"guardian-4",
-		//"guardian-5",
-
-		// Connected chains
-		"solana-devnet-0",
-
-		"terra-terrad-0",
-		"terra-lcd-0",
-
-		"eth-devnet-0",
-	}
-
-	c := getk8sClient()
-
-	// Wait for all pods to be ready. This blocks until the bridge is ready to receive lockups.
-	ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
-	defer cancel()
-	waitForPods(ctx, c, want)
-	if ctx.Err() != nil {
-		t.Fatal(ctx.Err())
-	}
-
-	// Ethereum client.
-	ec, err := ethclient.Dial(devnet.GanacheRPCURL)
-	if err != nil {
-		t.Fatalf("dialing devnet eth rpc failed: %v", err)
-	}
-	kt := devnet.GetKeyedTransactor(context.Background())
-
-	// Terra client
-	tc, err := NewTerraClient()
-	if err != nil {
-		t.Fatalf("creating devnet terra client failed: %v", err)
-	}
-
-	return c, ec, kt, tc
-}
-
-// Careful about parallel tests - accounts on some chains like Ethereum cannot be
-// used concurrently as they have monotonically increasing nonces that would conflict.
-// Either use different Ethereum account, or do not run Ethereum tests in parallel.
-
-func TestEndToEnd_SOL_ETH(t *testing.T) {
-	c, ec, kt, _ := setup(t)
-
-	t.Run("[SOL] Native -> [ETH] Wrapped", func(t *testing.T) {
-		testSolanaLockup(t, context.Background(), ec, c,
-			// Source SPL account
-			devnet.SolanaExampleTokenOwningAccount,
-			// Source SPL token
-			devnet.SolanaExampleToken,
-			// Our wrapped destination token on Ethereum
-			devnet.GanacheExampleERC20WrappedSOL,
-			// Amount of SPL token value to transfer.
-			50*devnet.SolanaDefaultPrecision,
-			// Same precision - same amount, no precision gained.
-			0,
-		)
-	})
-
-	t.Run("[ETH] Wrapped -> [SOL] Native", func(t *testing.T) {
-		testEthereumLockup(t, context.Background(), ec, kt, c,
-			// Source ERC20 token
-			devnet.GanacheExampleERC20WrappedSOL,
-			// Destination SPL token account
-			devnet.SolanaExampleTokenOwningAccount,
-			// Amount (the reverse of what the previous test did, with the same precision because
-			// the wrapped ERC20 is set to the original asset's 10**9 precision).
-			50*devnet.SolanaDefaultPrecision,
-			// No precision loss
-			0,
-		)
-	})
-
-	t.Run("[ETH] Native -> [SOL] Wrapped", func(t *testing.T) {
-		testEthereumLockup(t, context.Background(), ec, kt, c,
-			// Source ERC20 token
-			devnet.GanacheExampleERC20Token,
-			// Destination SPL token account
-			devnet.SolanaExampleWrappedERCTokenOwningAccount,
-			// Amount
-			0.000000012*devnet.ERC20DefaultPrecision,
-			// We lose 9 digits of precision on this path, as the default ERC20 token has 10**18 precision.
-			9,
-		)
-	})
-
-	t.Run("[SOL] Wrapped -> [ETH] Native", func(t *testing.T) {
-		testSolanaLockup(t, context.Background(), ec, c,
-			// Source SPL account
-			devnet.SolanaExampleWrappedERCTokenOwningAccount,
-			// Source SPL token
-			devnet.SolanaExampleWrappedERCToken,
-			// Our wrapped destination token on Ethereum
-			devnet.GanacheExampleERC20Token,
-			// Amount of SPL token value to transfer.
-			0.000000012*devnet.SolanaDefaultPrecision,
-			// We gain 9 digits of precision on Eth.
-			9,
-		)
-	})
-}
-
-func TestEndToEnd_SOL_Terra(t *testing.T) {
-	c, _, _, tc := setup(t)
-
-	t.Run("[Terra] Native -> [SOL] Wrapped", func(t *testing.T) {
-		testTerraLockup(t, context.Background(), tc, c,
-			// Source CW20 token
-			devnet.TerraTokenAddress,
-			// Destination SPL token account
-			devnet.SolanaExampleWrappedCWTokenOwningAccount,
-			// Amount
-			2*devnet.TerraDefaultPrecision,
-			// Same precision - same amount, no precision gained.
-			0,
-		)
-	})
-
-	t.Run("[SOL] Wrapped -> [Terra] Native", func(t *testing.T) {
-		testSolanaToTerraLockup(t, context.Background(), c,
-			// Source SPL account
-			devnet.SolanaExampleWrappedCWTokenOwningAccount,
-			// Source SPL token
-			devnet.SolanaExampleWrappedCWToken,
-			// Wrapped
-			false,
-			// Amount of SPL token value to transfer.
-			2*devnet.TerraDefaultPrecision,
-			// Same precision - same amount, no precision gained.
-			0,
-		)
-	})
-
-	t.Run("[SOL] Native -> [Terra] Wrapped", func(t *testing.T) {
-		testSolanaToTerraLockup(t, context.Background(), c,
-			// Source SPL account
-			devnet.SolanaExampleTokenOwningAccount,
-			// Source SPL token
-			devnet.SolanaExampleToken,
-			// Native
-			true,
-			// Amount of SPL token value to transfer.
-			50*devnet.SolanaDefaultPrecision,
-			// Same precision - same amount, no precision gained.
-			0,
-		)
-	})
-
-	t.Run("[Terra] Wrapped -> [SOL] Native", func(t *testing.T) {
-
-		tokenSlice, err := base58.Decode(devnet.SolanaExampleToken)
-		if err != nil {
-			t.Fatal(err)
-		}
-		wrappedAsset, err := waitTerraAsset(t, context.Background(), devnet.TerraBridgeAddress, vaa.ChainIDSolana, tokenSlice)
-
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		testTerraLockup(t, context.Background(), tc, c,
-			// Source wrapped token
-			wrappedAsset,
-			// Destination SPL token account
-			devnet.SolanaExampleTokenOwningAccount,
-			// Amount of Terra token value to transfer.
-			50*devnet.SolanaDefaultPrecision,
-			// Same precision
-			0,
-		)
-	})
-}
-
-func TestEndToEnd_ETH_Terra(t *testing.T) {
-	_, ec, kt, tc := setup(t)
-
-	t.Run("[Terra] Native -> [ETH] Wrapped", func(t *testing.T) {
-		testTerraToEthLockup(t, context.Background(), tc, ec,
-			// Source CW20 token
-			devnet.TerraTokenAddress,
-			// Destination ETH token
-			devnet.GanacheExampleERC20WrappedTerra,
-			// Amount
-			2*devnet.TerraDefaultPrecision,
-			// Same precision - same amount, no precision gained.
-			0,
-		)
-	})
-
-	t.Run("[ETH] Wrapped -> [Terra] Native", func(t *testing.T) {
-		testEthereumToTerraLockup(t, context.Background(), ec, kt,
-			// Source Ethereum token
-			devnet.GanacheExampleERC20WrappedTerra,
-			// Wrapped
-			false,
-			// Amount of Ethereum token value to transfer.
-			2*devnet.TerraDefaultPrecision,
-			// Same precision
-			0,
-		)
-	})
-
-	t.Run("[ETH] Native -> [Terra] Wrapped", func(t *testing.T) {
-		testEthereumToTerraLockup(t, context.Background(), ec, kt,
-			// Source Ethereum token
-			devnet.GanacheExampleERC20Token,
-			// Native
-			true,
-			// Amount of Ethereum token value to transfer.
-			0.000000012*devnet.ERC20DefaultPrecision,
-			// We lose 9 digits of precision on this path, as the default ERC20 token has 10**18 precision.
-			9,
-		)
-	})
-
-	t.Run("[Terra] Wrapped -> [ETH] Native", func(t *testing.T) {
-
-		paddedTokenAddress := ethereum.PadAddress(devnet.GanacheExampleERC20Token)
-		wrappedAsset, err := waitTerraAsset(t, context.Background(), devnet.TerraBridgeAddress, vaa.ChainIDEthereum, paddedTokenAddress[:])
-
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		testTerraToEthLockup(t, context.Background(), tc, ec,
-			// Source wrapped token
-			wrappedAsset,
-			// Destination ETH token
-			devnet.GanacheExampleERC20Token,
-			// Amount of Terra token value to transfer.
-			0.000000012*1e9, // 10**9 because default ETH precision is 18 and we lost 9 digits on wrapping
-			// We gain 9 digits of precision on Eth.
-			9,
-		)
-	})
-}

+ 0 - 190
bridge/e2e/eth.go

@@ -1,190 +0,0 @@
-package e2e
-
-import (
-	"context"
-	"encoding/hex"
-	"math"
-	"math/big"
-	"testing"
-	"time"
-
-	"github.com/ethereum/go-ethereum/accounts/abi/bind"
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/ethclient"
-	"github.com/tendermint/tendermint/libs/rand"
-	"k8s.io/apimachinery/pkg/util/wait"
-	"k8s.io/client-go/kubernetes"
-
-	"github.com/certusone/wormhole/bridge/pkg/devnet"
-	"github.com/certusone/wormhole/bridge/pkg/ethereum"
-	"github.com/certusone/wormhole/bridge/pkg/ethereum/abi"
-	"github.com/certusone/wormhole/bridge/pkg/ethereum/erc20"
-	"github.com/certusone/wormhole/bridge/pkg/vaa"
-)
-
-// waitEthBalance waits for target account before to increase.
-func waitEthBalance(t *testing.T, ctx context.Context, token *erc20.Erc20, before *big.Int, target int64) {
-	ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
-	defer cancel()
-
-	err := wait.PollUntil(1*time.Second, func() (bool, error) {
-		after, err := token.BalanceOf(nil, devnet.GanacheClientDefaultAccountAddress)
-		if err != nil {
-			t.Log(err)
-			return false, nil
-		}
-
-		d := new(big.Int).Sub(after, before)
-		t.Logf("ERC20 balance after: %d -> %d, delta %d", before, after, d)
-
-		if after.Cmp(before) != 0 {
-			if d.Cmp(new(big.Int).SetInt64(target)) != 0 {
-				t.Errorf("expected ERC20 delta of %v, got: %v", target, d)
-			}
-			return true, nil
-		}
-		return false, nil
-	}, ctx.Done())
-
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func testEthereumLockup(t *testing.T, ctx context.Context, ec *ethclient.Client, kt *bind.TransactOpts,
-	c *kubernetes.Clientset, tokenAddr common.Address, destination string, amount int64, precisionLoss int) {
-
-	// Bridge client
-	ethBridge, err := abi.NewAbi(devnet.GanacheBridgeContractAddress, ec)
-	if err != nil {
-		panic(err)
-	}
-
-	// Source token client
-	token, err := erc20.NewErc20(tokenAddr, ec)
-	if err != nil {
-		panic(err)
-	}
-
-	// Store balance of source ERC20 token
-	beforeErc20, err := token.BalanceOf(nil, devnet.GanacheClientDefaultAccountAddress)
-	if err != nil {
-		t.Log(err) // account may not yet exist, defaults to 0
-	}
-	t.Logf("ERC20 balance: %v", beforeErc20)
-
-	// Store balance of destination SPL token
-	beforeSPL, err := getSPLBalance(ctx, c, destination)
-	if err != nil {
-		t.Fatal(err)
-	}
-	t.Logf("SPL balance: %d", beforeSPL)
-
-	// Send lockup
-	tx, err := ethBridge.LockAssets(kt,
-		// asset address
-		tokenAddr,
-		// token amount
-		new(big.Int).SetInt64(amount),
-		// recipient address on target chain
-		devnet.MustBase58ToEthAddress(destination),
-		// target chain
-		vaa.ChainIDSolana,
-		// random nonce
-		rand.Uint32(),
-		// refund dust?
-		false,
-	)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	t.Logf("sent lockup tx: %v", tx.Hash().Hex())
-
-	// Destination account increases by full amount.
-	waitSPLBalance(t, ctx, c, destination, beforeSPL, int64(float64(amount)/math.Pow10(precisionLoss)))
-
-	// Source account decreases by the full amount.
-	waitEthBalance(t, ctx, token, beforeErc20, -int64(amount))
-}
-
-func testEthereumToTerraLockup(t *testing.T, ctx context.Context, ec *ethclient.Client, kt *bind.TransactOpts,
-	tokenAddr common.Address, isNative bool, amount int64, precisionLoss int) {
-
-	// Bridge client
-	ethBridge, err := abi.NewAbi(devnet.GanacheBridgeContractAddress, ec)
-	if err != nil {
-		panic(err)
-	}
-
-	// Source token client
-	token, err := erc20.NewErc20(tokenAddr, ec)
-	if err != nil {
-		panic(err)
-	}
-
-	// Store balance of source ERC20 token
-	beforeErc20, err := token.BalanceOf(nil, devnet.GanacheClientDefaultAccountAddress)
-	if err != nil {
-		beforeErc20 = new(big.Int)
-		t.Log(err) // account may not yet exist, defaults to 0
-	}
-	t.Logf("ERC20 balance: %v", beforeErc20)
-
-	// Store balance of destination CW20 token
-	paddedTokenAddress := ethereum.PadAddress(tokenAddr)
-	var terraToken string
-	if isNative {
-		terraToken, err = getAssetAddress(ctx, devnet.TerraBridgeAddress, vaa.ChainIDEthereum, paddedTokenAddress[:])
-		if err != nil {
-			t.Log(err)
-		}
-	} else {
-		terraToken = devnet.TerraTokenAddress
-	}
-
-	// Get balance if deployed
-	beforeCw20, err := getTerraBalance(ctx, terraToken)
-	if err != nil {
-		beforeCw20 = new(big.Int)
-		t.Log(err) // account may not yet exist, defaults to 0
-	}
-	t.Logf("CW20 balance: %v", beforeCw20)
-
-	// Send lockup
-	dstAddress, err := hex.DecodeString(devnet.TerraMainTestAddressHex)
-	if err != nil {
-		t.Fatal(err)
-	}
-	var dstAddressBytes [32]byte
-	copy(dstAddressBytes[:], dstAddress)
-	tx, err := ethBridge.LockAssets(kt,
-		// asset address
-		tokenAddr,
-		// token amount
-		new(big.Int).SetInt64(amount),
-		// recipient address on target chain
-		dstAddressBytes,
-		// target chain
-		vaa.ChainIDTerra,
-		// random nonce
-		rand.Uint32(),
-		// refund dust?
-		false,
-	)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	t.Logf("sent lockup tx: %v", tx.Hash().Hex())
-
-	// Destination account increases by the full amount.
-	if isNative {
-		waitTerraUnknownBalance(t, ctx, devnet.TerraBridgeAddress, vaa.ChainIDEthereum, paddedTokenAddress[:], beforeCw20, int64(float64(amount)/math.Pow10(precisionLoss)))
-	} else {
-		waitTerraBalance(t, ctx, devnet.TerraTokenAddress, beforeCw20, int64(float64(amount)/math.Pow10(precisionLoss)))
-	}
-
-	// Source account decreases by the full amount.
-	waitEthBalance(t, ctx, token, beforeErc20, -int64(amount))
-}

+ 0 - 149
bridge/e2e/k8s.go

@@ -1,149 +0,0 @@
-package e2e
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"log"
-	"strings"
-
-	"github.com/golang/glog"
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/fields"
-	"k8s.io/client-go/kubernetes"
-	"k8s.io/client-go/kubernetes/scheme"
-	"k8s.io/client-go/rest"
-	"k8s.io/client-go/tools/cache"
-	"k8s.io/client-go/tools/clientcmd"
-	"k8s.io/client-go/tools/remotecommand"
-)
-
-const (
-	TiltDefaultNamespace = "wormhole" // hardcoded in Tiltfile
-)
-
-func getk8sClient() *kubernetes.Clientset {
-	config, err := getk8sConfig()
-
-	c, err := kubernetes.NewForConfig(config)
-	if err != nil {
-		glog.Errorln(err)
-	}
-	return c
-}
-
-func getk8sConfig() (*rest.Config, error) {
-	// Load local default kubeconfig.
-	rules := clientcmd.NewDefaultClientConfigLoadingRules()
-	rules.DefaultClientConfig = &clientcmd.DefaultClientConfig
-	return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
-		clientcmd.ClientConfigLoader(rules), nil).ClientConfig()
-}
-
-func hasPodReadyCondition(conditions []corev1.PodCondition) bool {
-	for _, condition := range conditions {
-		if condition.Type == corev1.PodReady && condition.Status == corev1.ConditionTrue {
-			return true
-		}
-	}
-	return false
-}
-
-func waitForPods(ctx context.Context, c *kubernetes.Clientset, want []string) {
-	found := make(map[string]bool)
-	ctx, cancel := context.WithCancel(ctx)
-
-	watchlist := cache.NewListWatchFromClient(
-		c.CoreV1().RESTClient(),
-		"pods",
-		TiltDefaultNamespace,
-		fields.Everything(),
-	)
-
-	handle := func(pod *corev1.Pod) {
-		ready := hasPodReadyCondition(pod.Status.Conditions)
-		log.Printf("pod added/changed: %s is %s, ready: %v", pod.Name, pod.Status.Phase, ready)
-
-		if ready {
-			found[pod.Name] = true
-		}
-
-		missing := 0
-		for _, v := range want {
-			if found[v] == false {
-				missing += 1
-			}
-		}
-
-		if missing == 0 {
-			cancel()
-		}
-	}
-
-	_, controller := cache.NewInformer(
-		watchlist,
-		&corev1.Pod{},
-		0,
-		cache.ResourceEventHandlerFuncs{
-			AddFunc:    func(obj interface{}) { handle(obj.(*corev1.Pod)) },
-			UpdateFunc: func(oldObj, newObj interface{}) { handle(newObj.(*corev1.Pod)) },
-		},
-	)
-
-	controller.Run(ctx.Done())
-}
-
-func executeCommandInPod(ctx context.Context, c *kubernetes.Clientset, podName string, container string, cmd []string) ([]byte, error) {
-	p, err := c.CoreV1().Pods(TiltDefaultNamespace).Get(ctx, podName, metav1.GetOptions{})
-	if err != nil {
-		return nil, fmt.Errorf("failed to get pod %s: %w", p, err)
-	}
-
-	req := c.CoreV1().RESTClient().Post().
-		Resource("pods").
-		Name(podName).
-		Namespace(TiltDefaultNamespace).
-		SubResource("exec")
-
-	req = req.VersionedParams(&corev1.PodExecOptions{
-		Stdin:     false,
-		Stdout:    true,
-		Stderr:    true,
-		TTY:       false,
-		Container: container,
-		Command:   cmd,
-	}, scheme.ParameterCodec)
-
-	config, err := getk8sConfig()
-	if err != nil {
-		return nil, fmt.Errorf("failed to get config: %w", err)
-	}
-
-	exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
-	if err != nil {
-		return nil, fmt.Errorf("failed to init executor: %w", err)
-	}
-
-	var (
-		execOut bytes.Buffer
-		execErr bytes.Buffer
-	)
-
-	err = exec.Stream(remotecommand.StreamOptions{
-		Stdout: &execOut,
-		Stderr: &execErr,
-		Tty:    false,
-	})
-
-	log.Printf("command: %s", strings.Join(cmd, " "))
-	if execErr.Len() > 0 {
-		log.Printf("stderr: %s", execErr.String())
-	}
-
-	if err != nil {
-		return nil, fmt.Errorf("failed to execute remote command: %w", err)
-	}
-
-	return execOut.Bytes(), nil
-}

+ 0 - 184
bridge/e2e/solana.go

@@ -1,184 +0,0 @@
-package e2e
-
-import (
-	"context"
-	"fmt"
-	"math"
-	"math/big"
-	"regexp"
-	"strconv"
-	"testing"
-	"time"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/ethclient"
-	"github.com/mr-tron/base58"
-	"github.com/tendermint/tendermint/libs/rand"
-	"k8s.io/apimachinery/pkg/util/wait"
-	"k8s.io/client-go/kubernetes"
-
-	"github.com/certusone/wormhole/bridge/pkg/devnet"
-	"github.com/certusone/wormhole/bridge/pkg/ethereum/erc20"
-	"github.com/certusone/wormhole/bridge/pkg/vaa"
-)
-
-func getSPLBalance(ctx context.Context, c *kubernetes.Clientset, hexAddr string) (*big.Int, error) {
-	b, err := executeCommandInPod(ctx, c, "solana-devnet-0", "setup",
-		[]string{"cli", "balance", hexAddr})
-	if err != nil {
-		return nil, fmt.Errorf("error running 'cli balance': %w", err)
-	}
-
-	re := regexp.MustCompile("(?m)^amount: (.*)$")
-	m := re.FindStringSubmatch(string(b))
-	if len(m) == 0 {
-		return nil, fmt.Errorf("invalid 'cli balance' output: %s", string(b))
-	}
-
-	n, ok := new(big.Int).SetString(m[1], 10)
-	if !ok {
-		return nil, fmt.Errorf("invalid int: %s", m[1])
-	}
-
-	return n, nil
-}
-
-func waitSPLBalance(t *testing.T, ctx context.Context, c *kubernetes.Clientset, hexAddr string, before *big.Int, target int64) {
-	// Wait for target account balance to increase.
-	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
-	defer cancel()
-	err := wait.PollUntil(1*time.Second, func() (bool, error) {
-		after, err := getSPLBalance(ctx, c, hexAddr)
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		d := new(big.Int).Sub(after, before)
-		t.Logf("SPL balance after: %d -> %d, delta %d", before, after, d)
-
-		if after.Cmp(before) != 0 {
-			if d.Cmp(new(big.Int).SetInt64(target)) != 0 {
-				t.Errorf("expected SPL delta of %v, got: %v", target, d)
-			}
-			return true, nil
-		}
-		return false, nil
-	}, ctx.Done())
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func testSolanaLockup(t *testing.T, ctx context.Context, ec *ethclient.Client, c *kubernetes.Clientset,
-	sourceAcct string, tokenAddr string, destination common.Address, amount int, precisionGain int) {
-	token, err := erc20.NewErc20(destination, ec)
-	if err != nil {
-		panic(err)
-	}
-
-	// Store balance of wrapped destination token
-	beforeErc20, err := token.BalanceOf(nil, devnet.GanacheClientDefaultAccountAddress)
-	if err != nil {
-		beforeErc20 = new(big.Int)
-		t.Log(err) // account may not yet exist, defaults to 0
-	}
-	t.Logf("ERC20 balance: %v", beforeErc20)
-
-	// Store balance of source SPL token
-	beforeSPL, err := getSPLBalance(ctx, c, sourceAcct)
-	if err != nil {
-		t.Fatal(err)
-	}
-	t.Logf("SPL balance: %d", beforeSPL)
-
-	_, err = executeCommandInPod(ctx, c, "solana-devnet-0", "setup",
-		[]string{"cli", "lock",
-			// Address of the Wormhole bridge.
-			devnet.SolanaBridgeContract,
-			// Account which holds the SPL tokens to be sent.
-			sourceAcct,
-			// The SPL token.
-			tokenAddr,
-			// Token amount.
-			strconv.Itoa(amount),
-			// Destination chain ID.
-			strconv.Itoa(vaa.ChainIDEthereum),
-			// Random nonce.
-			strconv.Itoa(int(rand.Uint16())),
-			// Destination account on Ethereum
-			devnet.GanacheClientDefaultAccountAddress.Hex()[2:],
-		})
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Destination account increases by the full amount.
-	waitEthBalance(t, ctx, token, beforeErc20, int64(float64(amount)*math.Pow10(precisionGain)))
-
-	// Source account decreases by full amount.
-	waitSPLBalance(t, ctx, c, sourceAcct, beforeSPL, -int64(amount))
-}
-
-func testSolanaToTerraLockup(t *testing.T, ctx context.Context, c *kubernetes.Clientset,
-	sourceAcct string, tokenAddr string, isNative bool, amount int, precisionGain int) {
-
-	tokenSlice, err := base58.Decode(tokenAddr)
-	if err != nil {
-		t.Fatal(err)
-	}
-	var terraToken string
-	if isNative {
-		terraToken, err = getAssetAddress(ctx, devnet.TerraBridgeAddress, vaa.ChainIDSolana, tokenSlice)
-		if err != nil {
-			t.Log(err)
-		}
-	} else {
-		terraToken = devnet.TerraTokenAddress
-	}
-
-	// Get balance if deployed
-	beforeCw20, err := getTerraBalance(ctx, terraToken)
-	if err != nil {
-		beforeCw20 = new(big.Int)
-		t.Log(err) // account may not yet exist, defaults to 0
-	}
-	t.Logf("CW20 balance: %v", beforeCw20)
-
-	// Store balance of source SPL token
-	beforeSPL, err := getSPLBalance(ctx, c, sourceAcct)
-	if err != nil {
-		t.Fatal(err)
-	}
-	t.Logf("SPL balance: %d", beforeSPL)
-
-	_, err = executeCommandInPod(ctx, c, "solana-devnet-0", "setup",
-		[]string{"cli", "lock",
-			// Address of the Wormhole bridge.
-			devnet.SolanaBridgeContract,
-			// Account which holds the SPL tokens to be sent.
-			sourceAcct,
-			// The SPL token.
-			tokenAddr,
-			// Token amount.
-			strconv.Itoa(amount),
-			// Destination chain ID.
-			strconv.Itoa(vaa.ChainIDTerra),
-			// Random nonce.
-			strconv.Itoa(int(rand.Uint16())),
-			// Destination account on Terra
-			devnet.TerraMainTestAddressHex,
-		})
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Source account decreases by full amount.
-	waitSPLBalance(t, ctx, c, sourceAcct, beforeSPL, -int64(amount))
-
-	// Destination account increases by the full amount.
-	if isNative {
-		waitTerraUnknownBalance(t, ctx, devnet.TerraBridgeAddress, vaa.ChainIDSolana, tokenSlice, beforeCw20, int64(float64(amount)*math.Pow10(precisionGain)))
-	} else {
-		waitTerraBalance(t, ctx, devnet.TerraTokenAddress, beforeCw20, int64(float64(amount)*math.Pow10(precisionGain)))
-	}
-}

+ 0 - 391
bridge/e2e/terra.go

@@ -1,391 +0,0 @@
-package e2e
-
-import (
-	"context"
-	"encoding/base64"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"math"
-	"math/big"
-	"net/http"
-	"net/url"
-	"testing"
-	"time"
-
-	"github.com/certusone/wormhole/bridge/pkg/devnet"
-	"github.com/certusone/wormhole/bridge/pkg/ethereum"
-	"github.com/certusone/wormhole/bridge/pkg/ethereum/erc20"
-	"github.com/certusone/wormhole/bridge/pkg/vaa"
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/ethclient"
-	"github.com/tendermint/tendermint/libs/rand"
-	"github.com/terra-project/terra.go/client"
-	"github.com/terra-project/terra.go/key"
-	"github.com/terra-project/terra.go/msg"
-	"github.com/terra-project/terra.go/tx"
-	"github.com/tidwall/gjson"
-	"k8s.io/apimachinery/pkg/util/wait"
-	"k8s.io/client-go/kubernetes"
-)
-
-type lockAssetsMsg struct {
-	Params lockAssetsParams `json:"lock_assets"`
-}
-
-type increaseAllowanceMsg struct {
-	Params increaseAllowanceParams `json:"increase_allowance"`
-}
-
-type lockAssetsParams struct {
-	Asset       string `json:"asset"`
-	Amount      string `json:"amount"`
-	Recipient   []byte `json:"recipient"`
-	TargetChain uint8  `json:"target_chain"`
-	Nonce       uint32 `json:"nonce"`
-}
-
-type increaseAllowanceParams struct {
-	Spender string `json:"spender"`
-	Amount  string `json:"amount"`
-}
-
-// TerraClient encapsulates Terra LCD client and fee payer signing address
-type TerraClient struct {
-	lcdClient client.LCDClient
-	address   msg.AccAddress
-}
-
-const (
-	feeAmount       = 10000
-	feeDenomination = "uluna"
-)
-
-func (tc TerraClient) lockAssets(t *testing.T, ctx context.Context, token string, amount *big.Int, recipient [32]byte, targetChain uint8, nonce uint32) (*client.TxResponse, error) {
-	bridgeContract, err := msg.AccAddressFromBech32(devnet.TerraBridgeAddress)
-	if err != nil {
-		return nil, err
-	}
-
-	tokenContract, err := msg.AccAddressFromBech32(token)
-	if err != nil {
-		return nil, err
-	}
-
-	// Create tx
-	increaseAllowanceCall, err := json.Marshal(increaseAllowanceMsg{
-		Params: increaseAllowanceParams{
-			Spender: devnet.TerraBridgeAddress,
-			Amount:  amount.String(),
-		}})
-
-	if err != nil {
-		return nil, err
-	}
-
-	lockAssetsCall, err := json.Marshal(lockAssetsMsg{
-		Params: lockAssetsParams{
-			Asset:       token,
-			Amount:      amount.String(),
-			Recipient:   recipient[:],
-			TargetChain: targetChain,
-			Nonce:       nonce,
-		}})
-
-	if err != nil {
-		return nil, err
-	}
-
-	t.Logf("increaseAllowanceCall\n %s", increaseAllowanceCall)
-	t.Logf("lockAssetsCall\n %s", lockAssetsCall)
-
-	executeIncreaseAllowance := msg.NewExecuteContract(tc.address, tokenContract, increaseAllowanceCall, msg.NewCoins())
-	executeLockAssets := msg.NewExecuteContract(tc.address, bridgeContract, lockAssetsCall, msg.NewCoins(msg.NewInt64Coin(feeDenomination, feeAmount)))
-
-	transaction, err := tc.lcdClient.CreateAndSignTx(ctx, client.CreateTxOptions{
-		Msgs: []msg.Msg{
-			executeIncreaseAllowance,
-			executeLockAssets,
-		},
-		Fee: tx.StdFee{
-			Gas:    msg.NewInt(0),
-			Amount: msg.NewCoins(),
-		},
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	// Broadcast
-	return tc.lcdClient.Broadcast(ctx, transaction)
-}
-
-// NewTerraClient creates new TerraClient instance to work
-func NewTerraClient() (*TerraClient, error) {
-	// Derive Raw Private Key
-	privKey, err := key.DerivePrivKey(devnet.TerraFeePayerKey, key.CreateHDPath(0, 0))
-	if err != nil {
-		return nil, err
-	}
-
-	// Generate StdPrivKey
-	tmKey, err := key.StdPrivKeyGen(privKey)
-	if err != nil {
-		return nil, err
-	}
-
-	// Generate Address from Public Key
-	address := msg.AccAddress(tmKey.PubKey().Address())
-
-	// Terra client
-	lcdClient := client.NewLCDClient(
-		devnet.TerraLCDURL,
-		devnet.TerraChainID,
-		msg.NewDecCoinFromDec("uusd", msg.NewDecFromIntWithPrec(msg.NewInt(15), 2)), // 0.15uusd
-		msg.NewDecFromIntWithPrec(msg.NewInt(15), 1), tmKey, time.Second*15,
-	)
-
-	return &TerraClient{
-		lcdClient: *lcdClient,
-		address:   address,
-	}, nil
-}
-
-func getTerraBalance(ctx context.Context, token string) (*big.Int, error) {
-	json, err := terraQuery(ctx, token, fmt.Sprintf("{\"balance\":{\"address\":\"%s\"}}", devnet.TerraMainTestAddress))
-	if err != nil {
-		return nil, err
-	}
-	balance := gjson.Get(json, "result.balance").String()
-	parsed, success := new(big.Int).SetString(balance, 10)
-
-	if !success {
-		return nil, fmt.Errorf("cannot parse balance: %s", balance)
-	}
-
-	return parsed, nil
-}
-
-func getAssetAddress(ctx context.Context, contract string, chain uint8, asset []byte) (string, error) {
-	json, err := terraQuery(ctx, contract, fmt.Sprintf("{\"wrapped_registry\":{\"chain\":%d,\"address\":\"%s\"}}",
-		chain,
-		base64.StdEncoding.EncodeToString(asset)))
-	if err != nil {
-		return "", err
-	}
-	return gjson.Get(json, "result.address").String(), nil
-}
-
-func terraQuery(ctx context.Context, contract string, query string) (string, error) {
-
-	requestURL := fmt.Sprintf("%s/wasm/contracts/%s/store?query_msg=%s", devnet.TerraLCDURL, contract, url.QueryEscape(query))
-
-	req, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)
-	if err != nil {
-		return "", fmt.Errorf("http request error: %w", err)
-	}
-
-	client := &http.Client{
-		Timeout: time.Second * 15,
-	}
-	resp, err := client.Do(req)
-	if err != nil {
-		return "", fmt.Errorf("http execution error: %w", err)
-	}
-
-	body, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return "", fmt.Errorf("http read error: %w", err)
-	}
-
-	return string(body), nil
-}
-
-// waitTerraAsset waits for asset contract to be deployed on terra
-func waitTerraAsset(t *testing.T, ctx context.Context, contract string, chain uint8, asset []byte) (string, error) {
-	ctx, cancel := context.WithTimeout(ctx, 90*time.Second)
-	defer cancel()
-
-	assetAddress := ""
-
-	err := wait.PollUntil(3*time.Second, func() (bool, error) {
-
-		address, err := getAssetAddress(ctx, contract, chain, asset)
-		if err != nil {
-			t.Log(err)
-			return false, nil
-		}
-
-		// Check the case if request was successful, but asset address is not yet in the registry
-		if address == "" {
-			return false, nil
-		}
-		t.Logf("Returning asset: %s", address)
-
-		assetAddress = address
-		return true, nil
-	}, ctx.Done())
-
-	if err != nil {
-		t.Error(err)
-	}
-	return assetAddress, err
-}
-
-// waitTerraBalance waits for target account before to increase.
-func waitTerraBalance(t *testing.T, ctx context.Context, token string, before *big.Int, target int64) {
-	ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
-	defer cancel()
-
-	err := wait.PollUntil(1*time.Second, func() (bool, error) {
-
-		after, err := getTerraBalance(ctx, token)
-		if err != nil {
-			return false, err
-		}
-
-		d := new(big.Int).Sub(after, before)
-		t.Logf("CW20 balance after: %d -> %d, delta %d", before, after, d)
-
-		if after.Cmp(before) != 0 {
-			if d.Cmp(new(big.Int).SetInt64(target)) != 0 {
-				t.Errorf("expected CW20 delta of %v, got: %v", target, d)
-			}
-			return true, nil
-		}
-		return false, nil
-	}, ctx.Done())
-
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func waitTerraUnknownBalance(t *testing.T, ctx context.Context, contract string, chain uint8, asset []byte, before *big.Int, target int64) {
-
-	token, err := waitTerraAsset(t, ctx, contract, chain, asset)
-	if err != nil {
-		return
-	}
-
-	ctx, cancel := context.WithTimeout(ctx, 90*time.Second)
-	defer cancel()
-
-	err = wait.PollUntil(3*time.Second, func() (bool, error) {
-
-		after, err := getTerraBalance(ctx, token)
-		if err != nil {
-			return false, err
-		}
-
-		d := new(big.Int).Sub(after, before)
-		t.Logf("CW20 balance after: %d -> %d, delta %d", before, after, d)
-
-		if after.Cmp(before) != 0 {
-			if d.Cmp(new(big.Int).SetInt64(target)) != 0 {
-				t.Errorf("expected CW20 delta of %v, got: %v", target, d)
-			}
-			return true, nil
-		}
-		return false, nil
-	}, ctx.Done())
-
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func testTerraLockup(t *testing.T, ctx context.Context, tc *TerraClient,
-	c *kubernetes.Clientset, token string, destination string, amount int64, precisionLoss int) {
-
-	// Store balance of source CW20 token
-	beforeCw20, err := getTerraBalance(ctx, token)
-	if err != nil {
-		t.Log(err) // account may not yet exist, defaults to 0
-	}
-	t.Logf("CW20 balance: %v", beforeCw20)
-
-	// Store balance of destination SPL token
-	beforeSPL, err := getSPLBalance(ctx, c, destination)
-	if err != nil {
-		t.Fatal(err)
-	}
-	t.Logf("SPL balance: %d", beforeSPL)
-
-	// Send lockup
-	tx, err := tc.lockAssets(
-		t, ctx,
-		// asset address
-		token,
-		// token amount
-		new(big.Int).SetInt64(amount),
-		// recipient address on target chain
-		devnet.MustBase58ToEthAddress(destination),
-		// target chain
-		vaa.ChainIDSolana,
-		// random nonce
-		rand.Uint32(),
-	)
-	if err != nil {
-		t.Error(err)
-	}
-
-	t.Logf("sent lockup tx: %s", tx.TxHash)
-
-	// Destination account increases by full amount.
-	waitSPLBalance(t, ctx, c, destination, beforeSPL, int64(float64(amount)/math.Pow10(precisionLoss)))
-
-	// Source account decreases by the full amount.
-	waitTerraBalance(t, ctx, token, beforeCw20, -int64(amount))
-}
-
-func testTerraToEthLockup(t *testing.T, ctx context.Context, tc *TerraClient,
-	ec *ethclient.Client, tokenAddr string, destination common.Address, amount int64, precisionGain int) {
-
-	token, err := erc20.NewErc20(destination, ec)
-	if err != nil {
-		panic(err)
-	}
-
-	// Store balance of source CW20 token
-	beforeCw20, err := getTerraBalance(ctx, tokenAddr)
-	if err != nil {
-		t.Log(err) // account may not yet exist, defaults to 0
-		beforeCw20 = new(big.Int)
-	}
-	t.Logf("CW20 balance: %v", beforeCw20)
-
-	/// Store balance of wrapped destination token
-	beforeErc20, err := token.BalanceOf(nil, devnet.GanacheClientDefaultAccountAddress)
-	if err != nil {
-		t.Log(err) // account may not yet exist, defaults to 0
-		beforeErc20 = new(big.Int)
-	}
-	t.Logf("ERC20 balance: %v", beforeErc20)
-
-	// Send lockup
-	tx, err := tc.lockAssets(
-		t, ctx,
-		// asset address
-		tokenAddr,
-		// token amount
-		new(big.Int).SetInt64(amount),
-		// recipient address on target chain
-		ethereum.PadAddress(devnet.GanacheClientDefaultAccountAddress),
-		// target chain
-		vaa.ChainIDEthereum,
-		// random nonce
-		rand.Uint32(),
-	)
-	if err != nil {
-		t.Error(err)
-	}
-
-	t.Logf("sent lockup tx: %s", tx.TxHash)
-
-	// Destination account increases by full amount.
-	waitEthBalance(t, ctx, token, beforeErc20, int64(float64(amount)*math.Pow10(precisionGain)))
-
-	// Source account decreases by the full amount.
-	waitTerraBalance(t, ctx, tokenAddr, beforeCw20, -int64(amount))
-}