Beispiel #1
0
func testGetStorage(t *testing.T, typ string) {
	con := newWSCon(t)
	eid := types.EventStringNewBlock()
	subscribe(t, con, eid)
	defer func() {
		unsubscribe(t, con, eid)
		con.Close()
	}()

	amt, gasLim, fee := int64(1100), int64(1000), int64(1000)
	code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
	tx := makeDefaultCallTx(t, typ, nil, code, amt, gasLim, fee)
	receipt := broadcastTx(t, typ, tx)
	if receipt.CreatesContract == 0 {
		t.Fatal("This tx creates a contract")
	}
	if len(receipt.TxHash) == 0 {
		t.Fatal("Failed to compute tx hash")
	}
	contractAddr := receipt.ContractAddr
	if len(contractAddr) == 0 {
		t.Fatal("Creates contract but resulting address is empty")
	}

	// allow it to get mined
	waitForEvent(t, con, eid, true, func() {}, doNothing)
	mempoolCount = 0

	v := getStorage(t, typ, contractAddr, []byte{0x1})
	got := LeftPadWord256(v)
	expected := LeftPadWord256([]byte{0x5})
	if got.Compare(expected) != 0 {
		t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(), expected.Bytes())
	}
}
Beispiel #2
0
// Save Block, save the +2/3 Commits we've seen
func (cs *ConsensusState) saveBlock(block *types.Block, blockParts *types.PartSet, commits *types.VoteSet) {

	// The proposal must be valid.
	if err := cs.stageBlock(block, blockParts); err != nil {
		PanicSanity(Fmt("saveBlock() an invalid block: %v", err))
	}

	// Save to blockStore.
	if cs.blockStore.Height() < block.Height {
		seenValidation := commits.MakeValidation()
		cs.blockStore.SaveBlock(block, blockParts, seenValidation)
	}

	// Save the state.
	cs.stagedState.Save()

	// Update mempool.
	cs.mempoolReactor.Mempool.ResetForBlockAndState(block, cs.stagedState)

	// Fire off event
	if cs.evsw != nil && cs.evc != nil {
		cs.evsw.FireEvent(types.EventStringNewBlock(), types.EventDataNewBlock{block})
		go cs.evc.Flush()
	}

}
Beispiel #3
0
// receive a new block message
func TestWSNewBlock(t *testing.T) {
	con := newWSCon(t)
	eid := types.EventStringNewBlock()
	subscribe(t, con, eid)
	defer func() {
		unsubscribe(t, con, eid)
		con.Close()
	}()
	waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error {
		fmt.Println("Check:", string(b))
		return nil
	})
}
Beispiel #4
0
// receive a few new block messages in a row, with increasing height
func TestWSBlockchainGrowth(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	con := newWSCon(t)
	eid := types.EventStringNewBlock()
	subscribe(t, con, eid)
	defer func() {
		unsubscribe(t, con, eid)
		con.Close()
	}()
	// listen for NewBlock, ensure height increases by 1
	unmarshalValidateBlockchain(t, con, eid)
}
Beispiel #5
0
func testCall(t *testing.T, typ string) {
	con := newWSCon(t)
	eid := types.EventStringNewBlock()
	subscribe(t, con, eid)
	defer func() {
		unsubscribe(t, con, eid)
		con.Close()
	}()

	client := clients[typ]

	// create the contract
	amt, gasLim, fee := int64(6969), int64(1000), int64(1000)
	code, _, _ := simpleContract()
	tx := makeDefaultCallTx(t, typ, nil, code, amt, gasLim, fee)
	receipt := broadcastTx(t, typ, tx)

	if receipt.CreatesContract == 0 {
		t.Fatal("This tx creates a contract")
	}
	if len(receipt.TxHash) == 0 {
		t.Fatal("Failed to compute tx hash")
	}
	contractAddr := receipt.ContractAddr
	if len(contractAddr) == 0 {
		t.Fatal("Creates contract but resulting address is empty")
	}

	// allow it to get mined
	waitForEvent(t, con, eid, true, func() {}, doNothing)
	mempoolCount = 0

	// run a call through the contract
	data := []byte{}
	expected := []byte{0xb}
	callContract(t, client, user[0].PubKey.Address(), contractAddr, data, expected)
}
Beispiel #6
0
func testNameReg(t *testing.T, typ string) {
	client := clients[typ]
	con := newWSCon(t)

	types.MinNameRegistrationPeriod = 1

	// register a new name, check if its there
	// since entries ought to be unique and these run against different clients, we append the typ
	name := "ye_old_domain_name_" + typ
	data := "if not now, when"
	fee := int64(1000)
	numDesiredBlocks := int64(2)
	amt := fee + numDesiredBlocks*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data)

	eid := types.EventStringNameReg(name)
	subscribe(t, con, eid)

	tx := makeDefaultNameTx(t, typ, name, data, amt, fee)
	broadcastTx(t, typ, tx)
	// verify the name by both using the event and by checking get_name
	waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error {
		// TODO: unmarshal the response
		tx, err := unmarshalResponseNameReg(b)
		if err != nil {
			return err
		}
		if tx.Name != name {
			t.Fatal(fmt.Sprintf("Err on received event tx.Name: Got %s, expected %s", tx.Name, name))
		}
		if tx.Data != data {
			t.Fatal(fmt.Sprintf("Err on received event tx.Data: Got %s, expected %s", tx.Data, data))
		}
		return nil
	})
	mempoolCount = 0
	entry := getNameRegEntry(t, typ, name)
	if entry.Data != data {
		t.Fatal(fmt.Sprintf("Err on entry.Data: Got %s, expected %s", entry.Data, data))
	}
	if bytes.Compare(entry.Owner, user[0].Address) != 0 {
		t.Fatal(fmt.Sprintf("Err on entry.Owner: Got %s, expected %s", entry.Owner, user[0].Address))
	}

	unsubscribe(t, con, eid)

	// for the rest we just use new block event
	// since we already tested the namereg event
	eid = types.EventStringNewBlock()
	subscribe(t, con, eid)
	defer func() {
		unsubscribe(t, con, eid)
		con.Close()
	}()

	// update the data as the owner, make sure still there
	numDesiredBlocks = int64(2)
	data = "these are amongst the things I wish to bestow upon the youth of generations come: a safe supply of honey, and a better money. For what else shall they need"
	amt = fee + numDesiredBlocks*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data)
	tx = makeDefaultNameTx(t, typ, name, data, amt, fee)
	broadcastTx(t, typ, tx)
	// commit block
	waitForEvent(t, con, eid, true, func() {}, doNothing)
	mempoolCount = 0
	entry = getNameRegEntry(t, typ, name)
	if entry.Data != data {
		t.Fatal(fmt.Sprintf("Err on entry.Data: Got %s, expected %s", entry.Data, data))
	}

	// try to update as non owner, should fail
	nonce := getNonce(t, typ, user[1].Address)
	data2 := "this is not my beautiful house"
	tx = types.NewNameTxWithNonce(user[1].PubKey, name, data2, amt, fee, nonce+1)
	tx.Sign(chainID, user[1])
	_, err := client.BroadcastTx(tx)
	if err == nil {
		t.Fatal("Expected error on NameTx")
	}

	// commit block
	waitForEvent(t, con, eid, true, func() {}, doNothing)

	// now the entry should be expired, so we can update as non owner
	_, err = client.BroadcastTx(tx)
	waitForEvent(t, con, eid, true, func() {}, doNothing)
	mempoolCount = 0
	entry = getNameRegEntry(t, typ, name)
	if entry.Data != data2 {
		t.Fatal(fmt.Sprintf("Error on entry.Data: Got %s, expected %s", entry.Data, data2))
	}
	if bytes.Compare(entry.Owner, user[1].Address) != 0 {
		t.Fatal(fmt.Sprintf("Err on entry.Owner: Got %s, expected %s", entry.Owner, user[1].Address))
	}
}
Beispiel #7
0
func subscribeAndWait(tx types.Tx, chainID, nodeAddr string, inputAddr []byte) (chan Msg, error) {
	// subscribe to event and wait for tx to be committed
	wsAddr := strings.TrimPrefix(nodeAddr, "http://")
	wsAddr = "ws://" + wsAddr + "websocket"
	logger.Debugf("Websocket Address %s\n", wsAddr)
	wsClient := cclient.NewWSClient(wsAddr)
	wsClient.Start()
	eid := types.EventStringAccInput(inputAddr)
	if err := wsClient.Subscribe(eid); err != nil {
		return nil, fmt.Errorf("Error subscribing to AccInput event: %v", err)
	}
	if err := wsClient.Subscribe(types.EventStringNewBlock()); err != nil {
		return nil, fmt.Errorf("Error subscribing to NewBlock event: %v", err)
	}

	resultChan := make(chan Msg, 1)

	var latestBlockHash []byte

	// Read message
	go func() {
		for {
			result := <-wsClient.EventsCh
			// if its a block, remember the block hash
			blockData, ok := result.Data.(types.EventDataNewBlock)
			if ok {
				logger.Infoln(blockData.Block)
				latestBlockHash = blockData.Block.Hash()
				continue
			}

			// we don't accept events unless they came after a new block (ie. in)
			if latestBlockHash == nil {
				continue
			}

			if result.Event != eid {
				logger.Debugf("received unsolicited event! Got %s, expected %s\n", result.Event, eid)
				continue
			}

			data, ok := result.Data.(types.EventDataTx)
			if !ok {
				resultChan <- Msg{Error: fmt.Errorf("response error: expected result.Data to be *types.EventDataTx")}
				return
			}

			if !bytes.Equal(types.TxID(chainID, data.Tx), types.TxID(chainID, tx)) {
				logger.Debugf("Received event for same input from another transaction: %X\n", types.TxID(chainID, data.Tx))
				continue
			}

			if data.Exception != "" {
				resultChan <- Msg{BlockHash: latestBlockHash, Value: data.Return, Exception: data.Exception}
				return
			}

			// GOOD!
			resultChan <- Msg{BlockHash: latestBlockHash, Value: data.Return}
			return
		}
	}()

	// txs should take no more than 10 seconds
	timeoutTicker := time.Tick(time.Duration(MaxCommitWaitTimeSeconds) * time.Second)

	go func() {
		<-timeoutTicker
		resultChan <- Msg{Error: fmt.Errorf("timed out waiting for event")}
		return
	}()
	return resultChan, nil
}