github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/cmd/u2u/launcher/txtracer_test.go (about) 1 package launcher 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io/ioutil" 7 "log" 8 "net/http" 9 "strconv" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/require" 15 "github.com/unicornultrafoundation/go-u2u/evmcore/txtracer" 16 ) 17 18 func TestTxTracing(t *testing.T) { 19 20 // Start test node on random ports and keep it running for another requests 21 port := strconv.Itoa(trulyRandInt(10000, 65536)) 22 wsport := strconv.Itoa(trulyRandInt(10000, 65536)) 23 cliNode := exec(t, 24 "--fakenet", "1/1", "--enabletxtracer", "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", 25 "--ws", "--ws.port", wsport, "--http", "--http.api", "eth,web3,net,txpool,trace", "--http.port", port, "--allow-insecure-unlock") 26 27 // Wait for node to start 28 endpoint := "ws://127.0.0.1:" + wsport 29 waitForEndpoint(t, endpoint, 60*time.Second) 30 31 // Deploy a smart contract from the testdata javascript file 32 cliConsoleDeploy := exec(t, "attach", "--datadir", cliNode.Datadir, "--exec", "loadScript('testdata/txtracer_test.js')") 33 contractAddress := string(*cliConsoleDeploy.GetOutPipeData()) 34 contractAddress = contractAddress[strings.Index(contractAddress, "0x") : len(contractAddress)-1] 35 cliConsoleDeploy.WaitExit() 36 37 abi := `[{"inputs":[],"name":"deploy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getA","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_a","type":"uint256"}],"name":"setA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_a","type":"uint256"}],"name":"setInA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tst","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]` 38 39 cliConsole := exec(t, "attach", "--datadir", cliNode.Datadir) 40 cliConsoleOutput := *cliConsole.GetOutDataTillCursor() 41 42 // Initialize test contract for interaction 43 cliConsole.InputLine("var abi=" + abi) 44 cliConsoleOutput = *cliConsole.GetOutDataTillCursor() 45 cliConsole.InputLine(`var testContract = u2u.contract(abi)`) 46 cliConsoleOutput = *cliConsole.GetOutDataTillCursor() 47 cliConsole.InputLine("testContract = testContract.at('" + contractAddress + "')") 48 cliConsoleOutput = *cliConsole.GetOutDataTillCursor() 49 50 // Call simple contract call to check created trace 51 cliConsole.InputLine("testContract.setA.sendTransaction(24, {from:u2u.accounts[1]})") 52 cliConsoleOutput = *cliConsole.GetOutDataTillCursor() 53 txHashCall := cliConsoleOutput[strings.Index(cliConsoleOutput, "0x") : len(cliConsoleOutput)-3] 54 55 cliConsole.InputLine("testContract.deploy.sendTransaction({from:u2u.accounts[1]})") 56 cliConsoleOutput = *cliConsole.GetOutDataTillCursor() 57 txHashDeploy := cliConsoleOutput[strings.Index(cliConsoleOutput, "0x") : len(cliConsoleOutput)-3] 58 time.Sleep(5000 * time.Millisecond) 59 60 // Close node console 61 cliConsole.InputLine("exit") 62 cliConsole.WaitExit() 63 64 traceResult1, err := getTrace(txHashCall, port) 65 if err != nil { 66 log.Fatalln(err) 67 } 68 69 traceResult2, err := getTrace(txHashDeploy, port) 70 if err != nil { 71 log.Fatalln(err) 72 } 73 74 // Stop test node 75 cliNode.Kill() 76 cliNode.WaitExit() 77 78 // Compare results 79 // Test first transaction result trace, which should be 80 // just a simple call to a contract function 81 require.Equal(t, traceResult1.Result[0].TraceType, "call") 82 83 // Test second transaction result trace, which should be 84 // call to a contract, which will create a new contract and 85 // call a two other functions on new contract 86 require.Equal(t, traceResult2.Result[0].TraceType, "call") 87 require.Equal(t, traceResult2.Result[1].TraceType, "create") 88 require.Equal(t, traceResult2.Result[2].TraceType, "call") 89 require.Equal(t, traceResult2.Result[2].TraceType, "call") 90 91 // Check the addresses of inner traces 92 require.Equal(t, len(traceResult2.Result[0].TraceAddress), 0) 93 require.Equal(t, int(traceResult2.Result[1].TraceAddress[0]), 0) 94 require.Equal(t, int(traceResult2.Result[2].TraceAddress[0]), 1) 95 require.Equal(t, int(traceResult2.Result[3].TraceAddress[0]), 2) 96 } 97 98 func getTrace(txHash string, nodePort string) (response, error) { 99 jsonStr := []byte(`{"method":"trace_transaction","params":["` + txHash + `"],"id":1,"jsonrpc":"2.0"}`) 100 resp, err := http.Post("http://127.0.0.1:"+nodePort, "application/json", bytes.NewBuffer(jsonStr)) 101 if err != nil { 102 log.Fatalln(err) 103 } 104 105 //We Read the response body on the line below. 106 body, err := ioutil.ReadAll(resp.Body) 107 if err != nil { 108 log.Fatalln(err) 109 } 110 111 //Convert the body to type string 112 var res response 113 err = json.Unmarshal(body, &res) 114 return res, err 115 } 116 117 type response struct { 118 Jsonrpc string 119 Id int64 120 Result []txtracer.ActionTrace 121 }