// 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 "" }
func (vm *VM) fireCallEvent(exception *string, output *[]byte, caller, callee *Account, input []byte, value int64, gas *int64) { // fire the post call event (including exception if applicable) if vm.evc != nil { vm.evc.FireEvent(types.EventStringAccCall(callee.Address.Postfix(20)), types.EventDataCall{ &types.CallData{caller.Address.Postfix(20), callee.Address.Postfix(20), input, value, *gas}, vm.origin.Postfix(20), vm.txid, *output, *exception, }) } }