github.com/cgcardona/r-subnet-evm@v0.1.5/tests/utils/subnet.go (about)

     1  // Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package utils
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"fmt"
    10  	"os"
    11  	"os/exec"
    12  	"time"
    13  
    14  	"github.com/ava-labs/avalanchego/api/info"
    15  	"github.com/ava-labs/avalanchego/genesis"
    16  	"github.com/ava-labs/avalanchego/ids"
    17  	"github.com/ava-labs/avalanchego/vms/secp256k1fx"
    18  	wallet "github.com/ava-labs/avalanchego/wallet/subnet/primary"
    19  	"github.com/cgcardona/r-subnet-evm/core"
    20  	"github.com/cgcardona/r-subnet-evm/plugin/evm"
    21  	"github.com/ethereum/go-ethereum/common"
    22  	"github.com/ethereum/go-ethereum/log"
    23  	"github.com/onsi/gomega"
    24  )
    25  
    26  // RunTestCMD runs a given test command with the given rpcURI
    27  // It also waits for the test ping to succeed before running the test command
    28  func RunTestCMD(testCMD *exec.Cmd, rpcURI string) {
    29  	log.Info("Sleeping to wait for test ping", "rpcURI", rpcURI)
    30  	client, err := NewEvmClient(rpcURI, 225, 2)
    31  	gomega.Expect(err).Should(gomega.BeNil())
    32  
    33  	bal, err := client.FetchBalance(context.Background(), common.HexToAddress(""))
    34  	gomega.Expect(err).Should(gomega.BeNil())
    35  	gomega.Expect(bal.Cmp(common.Big0)).Should(gomega.Equal(0))
    36  
    37  	err = os.Setenv("RPC_URI", rpcURI)
    38  	gomega.Expect(err).Should(gomega.BeNil())
    39  	log.Info("Running test command", "cmd", testCMD.String())
    40  
    41  	out, err := testCMD.CombinedOutput()
    42  	fmt.Printf("\nCombined output:\n\n%s\n", string(out))
    43  	if err != nil {
    44  		fmt.Printf("\nErr: %s\n", err.Error())
    45  	}
    46  	gomega.Expect(err).Should(gomega.BeNil())
    47  }
    48  
    49  // CreateNewSubnet creates a new subnet and Subnet-EVM blockchain with the given genesis file.
    50  // returns the ID of the new created blockchain.
    51  func CreateNewSubnet(ctx context.Context, genesisFilePath string) string {
    52  	kc := secp256k1fx.NewKeychain(genesis.EWOQKey)
    53  
    54  	// NewWalletFromURI fetches the available UTXOs owned by [kc] on the network
    55  	// that [LocalAPIURI] is hosting.
    56  	wallet, err := wallet.NewWalletFromURI(ctx, DefaultLocalNodeURI, kc)
    57  	gomega.Expect(err).Should(gomega.BeNil())
    58  
    59  	pWallet := wallet.P()
    60  
    61  	owner := &secp256k1fx.OutputOwners{
    62  		Threshold: 1,
    63  		Addrs: []ids.ShortID{
    64  			genesis.EWOQKey.PublicKey().Address(),
    65  		},
    66  	}
    67  
    68  	wd, err := os.Getwd()
    69  	gomega.Expect(err).Should(gomega.BeNil())
    70  	log.Info("Reading genesis file", "filePath", genesisFilePath, "wd", wd)
    71  	genesisBytes, err := os.ReadFile(genesisFilePath)
    72  	gomega.Expect(err).Should(gomega.BeNil())
    73  
    74  	log.Info("Creating new subnet")
    75  	createSubnetTxID, err := pWallet.IssueCreateSubnetTx(owner)
    76  	gomega.Expect(err).Should(gomega.BeNil())
    77  
    78  	genesis := &core.Genesis{}
    79  	err = json.Unmarshal(genesisBytes, genesis)
    80  	gomega.Expect(err).Should(gomega.BeNil())
    81  
    82  	log.Info("Creating new Subnet-EVM blockchain", "genesis", genesis)
    83  	createChainTxID, err := pWallet.IssueCreateChainTx(
    84  		createSubnetTxID,
    85  		genesisBytes,
    86  		evm.ID,
    87  		nil,
    88  		"testChain",
    89  	)
    90  	gomega.Expect(err).Should(gomega.BeNil())
    91  
    92  	// Confirm the new blockchain is ready by waiting for the readiness endpoint
    93  	infoClient := info.NewClient(DefaultLocalNodeURI)
    94  	bootstrapped, err := info.AwaitBootstrapped(ctx, infoClient, createChainTxID.String(), 2*time.Second)
    95  	gomega.Expect(err).Should(gomega.BeNil())
    96  	gomega.Expect(bootstrapped).Should(gomega.BeTrue())
    97  
    98  	// Return the blockchainID of the newly created blockchain
    99  	return createChainTxID.String()
   100  }
   101  
   102  // GetDefaultChainURI returns the default chain URI for a given blockchainID
   103  func GetDefaultChainURI(blockchainID string) string {
   104  	return fmt.Sprintf("%s/ext/bc/%s/rpc", DefaultLocalNodeURI, blockchainID)
   105  }
   106  
   107  // RunDefaultHardhatTests runs the hardhat tests on a given blockchain ID
   108  // with default parameters. Default parameters are:
   109  // 1. Hardhat contract environment is located at ./contracts
   110  // 2. Hardhat test file is located at ./contracts/test/<test>.ts
   111  // 3. npx is available in the ./contracts directory
   112  func RunDefaultHardhatTests(ctx context.Context, blockchainID string, test string) {
   113  	chainURI := GetDefaultChainURI(blockchainID)
   114  	log.Info("Executing HardHat tests on a new blockchain", "blockchainID", blockchainID, "test", test)
   115  	log.Info("Using subnet", "ChainURI", chainURI)
   116  
   117  	cmdPath := "./contracts"
   118  	// test path is relative to the cmd path
   119  	testPath := fmt.Sprintf("./test/%s.ts", test)
   120  	cmd := exec.Command("npx", "hardhat", "test", testPath, "--network", "local")
   121  	cmd.Dir = cmdPath
   122  
   123  	RunTestCMD(cmd, chainURI)
   124  }