Example #1
0
// TestNewBlockFromBytes tests creation of a Block from serialized bytes.
func TestNewBlockFromBytes(t *testing.T) {
	// Serialize the test block.
	var block100000Buf bytes.Buffer
	err := Block100000.Serialize(&block100000Buf)
	if err != nil {
		t.Errorf("Serialize: %v", err)
	}
	block100000Bytes := block100000Buf.Bytes()

	// Create a new block from the serialized bytes.
	b, err := btcutil.NewBlockFromBytes(block100000Bytes)
	if err != nil {
		t.Errorf("NewBlockFromBytes: %v", err)
		return
	}

	// Ensure we get the same data back out.
	serializedBytes, err := b.Bytes()
	if err != nil {
		t.Errorf("Bytes: %v", err)
		return
	}
	if !bytes.Equal(serializedBytes, block100000Bytes) {
		t.Errorf("Bytes: wrong bytes - got %v, want %v",
			spew.Sdump(serializedBytes),
			spew.Sdump(block100000Bytes))
	}

	// Ensure the generated MsgBlock is correct.
	if msgBlock := b.MsgBlock(); !reflect.DeepEqual(msgBlock, &Block100000) {
		t.Errorf("MsgBlock: mismatched MsgBlock - got %v, want %v",
			spew.Sdump(msgBlock), spew.Sdump(&Block100000))
	}
}
Example #2
0
// processBlock potentially imports the block into the database.  It first
// deserializes the raw block while checking for errors.  Already known blocks
// are skipped and orphan blocks are considered errors.  Finally, it runs the
// block through the chain rules to ensure it follows all rules and matches
// up to the known checkpoint.  Returns whether the block was imported along
// with any potential errors.
func (bi *blockImporter) processBlock(serializedBlock []byte) (bool, error) {
	// Deserialize the block which includes checks for malformed blocks.
	block, err := btcutil.NewBlockFromBytes(serializedBlock)
	if err != nil {
		return false, err
	}

	blockSha, err := block.Sha()
	if err != nil {
		return false, err
	}

	// update progress statistics
	bi.lastBlockTime = block.MsgBlock().Header.Timestamp
	bi.receivedLogTx += int64(len(block.MsgBlock().Transactions))

	// Skip blocks that already exist.
	exists, err := bi.db.ExistsSha(blockSha)
	if err != nil {
		return false, err
	}
	if exists {
		return false, nil
	}

	// Don't bother trying to process orphans.
	prevHash := &block.MsgBlock().Header.PrevBlock
	if !prevHash.IsEqual(&zeroHash) {
		exists, err := bi.db.ExistsSha(prevHash)
		if err != nil {
			return false, err
		}
		if !exists {
			return false, fmt.Errorf("import file contains block "+
				"%v which does not link to the available "+
				"block chain", prevHash)
		}
	}

	// Ensure the blocks follows all of the chain rules and match up to the
	// known checkpoints.
	isOrphan, err := bi.chain.ProcessBlock(block, btcchain.BFFastAdd)
	if err != nil {
		return false, err
	}
	if isOrphan {
		return false, fmt.Errorf("import file contains an orphan "+
			"block: %v", blockSha)
	}

	return true, nil
}
Example #3
0
// TestBlockErrors tests the error paths for the Block API.
func TestBlockErrors(t *testing.T) {
	// Ensure out of range errors are as expected.
	wantErr := "transaction index -1 is out of range - max 3"
	testErr := btcutil.OutOfRangeError(wantErr)
	if testErr.Error() != wantErr {
		t.Errorf("OutOfRangeError: wrong error - got %v, want %v",
			testErr.Error(), wantErr)
	}

	// Serialize the test block.
	var block100000Buf bytes.Buffer
	err := Block100000.Serialize(&block100000Buf)
	if err != nil {
		t.Errorf("Serialize: %v", err)
	}
	block100000Bytes := block100000Buf.Bytes()

	// Create a new block from the serialized bytes.
	b, err := btcutil.NewBlockFromBytes(block100000Bytes)
	if err != nil {
		t.Errorf("NewBlockFromBytes: %v", err)
		return
	}

	// Truncate the block byte buffer to force errors.
	shortBytes := block100000Bytes[:80]
	_, err = btcutil.NewBlockFromBytes(shortBytes)
	if err != io.EOF {
		t.Errorf("NewBlockFromBytes: did not get expected error - "+
			"got %v, want %v", err, io.EOF)
	}

	// Ensure TxSha returns expected error on invalid indices.
	_, err = b.TxSha(-1)
	if _, ok := err.(btcutil.OutOfRangeError); !ok {
		t.Errorf("TxSha: wrong error - got: %v <%T>, "+
			"want: <%T>", err, err, btcutil.OutOfRangeError(""))
	}
	_, err = b.TxSha(len(Block100000.Transactions) + 1)
	if _, ok := err.(btcutil.OutOfRangeError); !ok {
		t.Errorf("TxSha: wrong error - got: %v <%T>, "+
			"want: <%T>", err, err, btcutil.OutOfRangeError(""))
	}

	// Ensure Tx returns expected error on invalid indices.
	_, err = b.Tx(-1)
	if _, ok := err.(btcutil.OutOfRangeError); !ok {
		t.Errorf("Tx: wrong error - got: %v <%T>, "+
			"want: <%T>", err, err, btcutil.OutOfRangeError(""))
	}
	_, err = b.Tx(len(Block100000.Transactions) + 1)
	if _, ok := err.(btcutil.OutOfRangeError); !ok {
		t.Errorf("Tx: wrong error - got: %v <%T>, "+
			"want: <%T>", err, err, btcutil.OutOfRangeError(""))
	}

	// Ensure TxLoc returns expected error with short byte buffer.
	// This makes use of the test package only function, SetBlockBytes, to
	// inject a short byte buffer.
	b.SetBlockBytes(shortBytes)
	_, err = b.TxLoc()
	if err != io.EOF {
		t.Errorf("TxLoc: did not get expected error - "+
			"got %v, want %v", err, io.EOF)
	}
}