Exemplo n.º 1
0
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
	}
}
Exemplo n.º 2
0
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 new event cache to cache all events.
	cs.evc = events.NewEventCache(cs.evsw)

	// Create a copy of the state for staging
	stateCopy := cs.state.Copy()
	stateCopy.SetEventCache(cs.evc)

	// Run the block on the State:
	// + update validator sets
	// + first rolls back proxyAppCtx
	// + run txs on the proxyAppCtx or rollback
	err := stateCopy.ExecBlock(cs.proxyAppCtx, block, blockParts.Header())
	if err != nil {
		return err
	}

	// Everything looks good!
	cs.stagedBlock = block
	cs.stagedState = stateCopy
	return nil
}
Exemplo n.º 3
0
// subscribes to an AccReceive, runs the vm, returns the exception
func runVMWaitEvents(t *testing.T, ourVm *VM, caller, callee *Account, subscribeAddr, contractCode []byte, gas uint64) string {
	// we need to catch the event from the CALL to check for exceptions
	evsw := new(events.EventSwitch)
	evsw.Start()
	ch := make(chan interface{})
	fmt.Printf("subscribe to %x\n", subscribeAddr)
	evsw.AddListenerForEvent("test", types.EventStringAccReceive(subscribeAddr), func(msg interface{}) {
		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.EventMsgCallTx:
		return ev.Exception
	case types.EventMsgCall:
		return ev.Exception
	case string:
		return ev
	}
	return ""
}
Exemplo n.º 4
0
// 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, ""
	}
}