// subscribes to an AccCall, runs the vm, returns the exception func runVMWaitEvents(t *testing.T, ourVm *VM, caller, callee *Account, subscribeAddr, contractCode []byte, gas int64) string { // we need to catch the event from the CALL to check for exceptions evsw := events.NewEventSwitch() evsw.Start() ch := make(chan interface{}) fmt.Printf("subscribe to %x\n", subscribeAddr) evsw.AddListenerForEvent("test", types.EventStringAccCall(subscribeAddr), func(msg types.EventData) { ch <- msg }) evc := events.NewEventCache(evsw) ourVm.SetFireable(evc) go func() { start := time.Now() output, err := ourVm.Call(caller, callee, contractCode, []byte{}, 0, &gas) fmt.Printf("Output: %v Error: %v\n", output, err) fmt.Println("Call took:", time.Since(start)) if err != nil { ch <- err.Error() } evc.Flush() }() msg := <-ch switch ev := msg.(type) { case types.EventDataTx: return ev.Exception case types.EventDataCall: return ev.Exception case string: return ev } return "" }
// create two contracts, one of which calls the other func TestWSCallCall(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } con := newWSCon(t) amt, gasLim, fee := int64(10000), int64(1000), int64(1000) code, _, returnVal := simpleContract() txid := new([]byte) // deploy the two contracts tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee) receipt := broadcastTx(t, wsTyp, tx) contractAddr1 := receipt.ContractAddr code, _, _ = simpleCallContract(contractAddr1) tx = makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee) receipt = broadcastTx(t, wsTyp, tx) contractAddr2 := receipt.ContractAddr // susbscribe to the new contracts amt = int64(10001) eid1 := types.EventStringAccCall(contractAddr1) subscribe(t, con, eid1) defer func() { unsubscribe(t, con, eid1) con.Close() }() // call contract2, which should call contract1, and wait for ev1 // let the contract get created first waitForEvent(t, con, eid1, true, func() { }, func(eid string, b []byte) error { return nil }) // call it waitForEvent(t, con, eid1, true, func() { tx := makeDefaultCallTx(t, wsTyp, contractAddr2, nil, amt, gasLim, fee) broadcastTx(t, wsTyp, tx) *txid = types.TxID(chainID, tx) }, unmarshalValidateCall(user[0].Address, returnVal, txid)) }