// 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 "" }
// run ExecTx and wait for the Call event on given addr // returns the msg data and an error/exception func execTxWaitEvent(t *testing.T, blockCache *BlockCache, tx types.Tx, eventid string) (interface{}, string) { evsw := events.NewEventSwitch() evsw.Start() ch := make(chan interface{}) evsw.AddListenerForEvent("test", eventid, func(msg types.EventData) { ch <- msg }) evc := events.NewEventCache(evsw) go func() { if err := ExecTx(blockCache, tx, true, evc); err != nil { ch <- err.Error() } evc.Flush() }() ticker := time.NewTicker(5 * time.Second) var msg interface{} select { case msg = <-ch: case <-ticker.C: return nil, ExceptionTimeOut } switch ev := msg.(type) { case types.EventDataTx: return ev, ev.Exception case types.EventDataCall: return ev, ev.Exception case string: return nil, ev default: return ev, "" } }