Beispiel #1
0
// 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))
}