dcrutil: Block does not cache the header bytes

This fixes a bug in dcrutil where (*Block).BlockHeaderBytes would
incorrectly return a cached byte slice of the serialized block instead
of just the header. This would only happen after the cache had been
set, such as through a call to block.Bytes(), or construction via
NewBlockFromBytes or NewBlockFromBlockAndBytes.

The comments are also changed accordingly and wrapped after 80 columns.

Update TestBlock with a test for (*Block).BlockHeaderBytes that follows
(*Block).Bytes.
This commit is contained in:
Jonathan Chappelow 2019-01-18 16:04:14 -06:00
parent 0774a31682
commit 3a5281156b
2 changed files with 29 additions and 14 deletions

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -75,26 +75,19 @@ func (b *Block) Bytes() ([]byte, error) {
return serializedBlock, nil
}
// BlockHeaderBytes returns the serialized bytes for the Block's header. This is
// equivalent to calling Serialize on the underlying wire.MsgBlock, but it
// returns a byte slice.
// BlockHeaderBytes returns the serialized bytes for the Block's header. This
// is equivalent to calling Serialize on the underlying wire.MsgBlock.Header,
// but it returns a byte slice.
func (b *Block) BlockHeaderBytes() ([]byte, error) {
// Return the cached serialized bytes if it has already been generated.
if len(b.serializedBlock) != 0 {
return b.serializedBlock, nil
}
// Serialize the MsgBlock.
// Serialize the BlockHeader.
var w bytes.Buffer
w.Grow(wire.MaxBlockHeaderPayload)
err := b.msgBlock.Header.Serialize(&w)
if err != nil {
return nil, err
}
serializedBlockHeader := w.Bytes()
// Cache the serialized bytes and return them.
return serializedBlockHeader, nil
return w.Bytes(), nil
}
// Hash returns the block identifier hash for the Block. This is equivalent to

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -144,6 +144,28 @@ func TestBlock(t *testing.T) {
}
}
// Serialize the test block's header.
var block100000HeaderBuf bytes.Buffer
block100000HeaderBuf.Grow(wire.MaxBlockHeaderPayload)
err = Block100000.Header.Serialize(&block100000HeaderBuf)
if err != nil {
t.Errorf("Serialize: %v", err)
}
block100000HeaderBytes := block100000HeaderBuf.Bytes()
// Request serialized header bytes after the previous calls to block.Bytes
// to ensure the correct bytes are returned (not the cached copy of the full
// serialized block).
serializedHeaderBytes, err := b.BlockHeaderBytes()
if err != nil {
t.Errorf("Bytes: %v", err)
}
if !bytes.Equal(serializedHeaderBytes, block100000HeaderBytes) {
t.Errorf("BlockHeaderBytes wrong bytes - got %v, want %v",
spew.Sdump(serializedHeaderBytes),
spew.Sdump(block100000HeaderBytes))
}
// Transaction offsets and length for the transaction in Block100000.
wantTxLocs := []wire.TxLoc{
{TxStart: 181, TxLen: 159},