| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- package e2e
- import (
- "context"
- "fmt"
- "math"
- "math/big"
- "math/rand"
- "regexp"
- "strconv"
- "testing"
- "time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethclient"
- "k8s.io/apimachinery/pkg/util/wait"
- "k8s.io/client-go/kubernetes"
- "github.com/certusone/wormhole/node/pkg/devnet"
- "github.com/certusone/wormhole/node/pkg/ethereum/erc20"
- "github.com/certusone/wormhole/node/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.Uint32())),
- // 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))
- }
|