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 }