// 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, "" } }
// 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 (cs *ConsensusState) stageBlock(block *types.Block, blockParts *types.PartSet) error { if block == nil { PanicSanity("Cannot stage nil block") } // Already staged? blockHash := block.Hash() if cs.stagedBlock != nil && len(blockHash) != 0 && bytes.Equal(cs.stagedBlock.Hash(), blockHash) { return nil } // Create a copy of the state for staging stateCopy := cs.state.Copy() // reset the event cache and pass it into the state cs.evc = events.NewEventCache(cs.evsw) stateCopy.SetFireable(cs.evc) // Commit block onto the copied state. // NOTE: Basic validation is done in state.AppendBlock(). err := sm.ExecBlock(stateCopy, block, blockParts.Header()) if err != nil { return err } else { cs.stagedBlock = block cs.stagedState = stateCopy return nil } }
// run ExecTx and wait for the Receive 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 := new(events.EventSwitch) evsw.Start() ch := make(chan interface{}) evsw.AddListenerForEvent("test", eventid, func(msg interface{}) { ch <- msg }) evc := events.NewEventCache(evsw) go func() { if err := ExecTx(blockCache, tx, true, evc); err != nil { ch <- err.Error() } evc.Flush() }() msg := <-ch switch ev := msg.(type) { case types.EventMsgCallTx: return ev, ev.Exception case types.EventMsgCall: return ev, ev.Exception case string: return nil, ev default: return ev, "" } }