diff --git a/wire/blockheader.go b/wire/blockheader.go index 99199197e..183c7e1c4 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -18,7 +18,7 @@ import ( // + NumPrevBlocks 1 byte + MerkleRoot hash. // To get total size of block header len(PrevBlocks) * chainhash.HashSize should be // added to this value -const BaseBlockHeaderPayload = 21 + (chainhash.HashSize) +const BaseBlockHeaderPayload = 17 + (chainhash.HashSize) // MaxNumPrevBlocks is the maximum number of previous blocks a block can reference. // Currently set to 255 as the maximum number NumPrevBlocks can be due to it being a byte @@ -29,7 +29,7 @@ const MaxNumPrevBlocks = 255 const MaxBlockHeaderPayload = BaseBlockHeaderPayload + (MaxNumPrevBlocks * chainhash.HashSize) // BlockHeader defines information about a block and is used in the bitcoin -// block (MsgBlock) and headers (MsgHeader ) messages. +// block (MsgBlock) and headers (MsgHeader) messages. type BlockHeader struct { // Version of the block. This is not the same as the protocol version. Version int32 @@ -54,10 +54,6 @@ type BlockHeader struct { Nonce uint32 } -// blockHeaderLen is a constant that represents the number of bytes for a block -// header. -const blockHeaderLen = 80 - // BlockHash computes the block identifier hash for the given block header. func (h *BlockHeader) BlockHash() chainhash.Hash { // Encode the header and double sha256 everything prior to the number of @@ -106,6 +102,12 @@ func (h *BlockHeader) Serialize(w io.Writer) error { return writeBlockHeader(w, 0, h) } +// SerializeSize returns the number of bytes it would take to serialize the +// block header. +func (h *BlockHeader) SerializeSize() int { + return BaseBlockHeaderPayload + int(h.NumPrevBlocks)*chainhash.HashSize +} + // NewBlockHeader returns a new BlockHeader using the provided version, previous // block hash, merkle root hash, difficulty bits, and nonce used to generate the // block with defaults or calclulated values for the remaining fields. @@ -134,13 +136,12 @@ func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { return err } - bh.NumPrevBlocks, err = binarySerializer.Uint8(r) - if err != nil { - return err - } bh.PrevBlocks = make([]chainhash.Hash, bh.NumPrevBlocks) for i := byte(0); i < bh.NumPrevBlocks; i++ { - readElement(r, &bh.PrevBlocks[i]) + err := readElement(r, &bh.PrevBlocks[i]) + if err != nil { + return err + } } return readElements(r, &bh.MerkleRoot, (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) } diff --git a/wire/blockheader_test.go b/wire/blockheader_test.go index 2035b1aa7..5c51d1a64 100644 --- a/wire/blockheader_test.go +++ b/wire/blockheader_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/daglabs/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" ) @@ -21,15 +22,16 @@ func TestBlockHeader(t *testing.T) { } nonce := uint32(nonce64) - hash := mainNetGenesisHash + hashes := []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash} + merkleHash := mainNetGenesisMerkleRoot bits := uint32(0x1d00ffff) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, hashes, &merkleHash, bits, nonce) // Ensure we get the same data back out. - if !bh.PrevBlock.IsEqual(&hash) { - t.Errorf("NewBlockHeader: wrong prev hash - got %v, want %v", - spew.Sprint(bh.PrevBlock), spew.Sprint(hash)) + if !reflect.DeepEqual(bh.PrevBlocks, hashes) { + t.Errorf("NewBlockHeader: wrong prev hashes - got %v, want %v", + spew.Sprint(bh.PrevBlocks), spew.Sprint(hashes)) } if !bh.MerkleRoot.IsEqual(&merkleHash) { t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v", @@ -54,25 +56,31 @@ func TestBlockHeaderWire(t *testing.T) { // baseBlockHdr is used in the various tests as a baseline BlockHeader. bits := uint32(0x1d00ffff) baseBlockHdr := &BlockHeader{ - Version: 1, - PrevBlock: mainNetGenesisHash, - MerkleRoot: mainNetGenesisMerkleRoot, - Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST - Bits: bits, - Nonce: nonce, + Version: 1, + NumPrevBlocks: 2, + PrevBlocks: []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash}, + MerkleRoot: mainNetGenesisMerkleRoot, + Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST + Bits: bits, + Nonce: nonce, } // baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr. baseBlockHdrEncoded := []byte{ 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, + 0x02, // NumPrevBlocks + 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // PrevBlock mainNetGenesisHash 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock - 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, + 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // PrevBlock simNetGenesisHash + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, + 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // MerkleRoot 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, - 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, 0x29, 0xab, 0x5f, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce @@ -187,25 +195,31 @@ func TestBlockHeaderSerialize(t *testing.T) { // baseBlockHdr is used in the various tests as a baseline BlockHeader. bits := uint32(0x1d00ffff) baseBlockHdr := &BlockHeader{ - Version: 1, - PrevBlock: mainNetGenesisHash, - MerkleRoot: mainNetGenesisMerkleRoot, - Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST - Bits: bits, - Nonce: nonce, + Version: 1, + NumPrevBlocks: 2, + PrevBlocks: []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash}, + MerkleRoot: mainNetGenesisMerkleRoot, + Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST + Bits: bits, + Nonce: nonce, } // baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr. baseBlockHdrEncoded := []byte{ 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, + 0x02, // NumPrevBlocks + 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // PrevBlock mainNetGenesisHash 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock - 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, + 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // PrevBlock simNetGenesisHash + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, + 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // MerkleRoot 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, - 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, 0x29, 0xab, 0x5f, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce @@ -253,3 +267,51 @@ func TestBlockHeaderSerialize(t *testing.T) { } } } + +// TestBlockHeaderSerializeSize performs tests to ensure the serialize size for +// various block headers is accurate. +func TestBlockHeaderSerializeSize(t *testing.T) { + nonce := uint32(123123) // 0x1e0f3 + bits := uint32(0x1d00ffff) + timestamp := time.Unix(0x495fab29, 0) // 2009-01-03 12:15:05 -0600 CST + baseBlockHdr := &BlockHeader{ + Version: 1, + NumPrevBlocks: 2, + PrevBlocks: []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash}, + MerkleRoot: mainNetGenesisMerkleRoot, + Timestamp: timestamp, + Bits: bits, + Nonce: nonce, + } + + genesisBlockHdr := &BlockHeader{ + Version: 1, + NumPrevBlocks: 0, + PrevBlocks: []chainhash.Hash{}, + MerkleRoot: mainNetGenesisMerkleRoot, + Timestamp: timestamp, + Bits: bits, + Nonce: nonce, + } + tests := []struct { + in *BlockHeader // Block header to encode + size int // Expected serialized size + }{ + // Block with no transactions. + {genesisBlockHdr, 49}, + + // First block in the mainnet block chain. + {baseBlockHdr, 113}, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + serializedSize := test.in.SerializeSize() + if serializedSize != test.size { + t.Errorf("BlockHeader.SerializeSize: #%d got: %d, want: "+ + "%d", i, serializedSize, test.size) + + continue + } + } +} diff --git a/wire/common_test.go b/wire/common_test.go index afd81665f..279221b94 100644 --- a/wire/common_test.go +++ b/wire/common_test.go @@ -25,6 +25,15 @@ var mainNetGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, }) +// simNetGenesisHash is the hash of the first block in the block chain for the +// simulation test network. +var simNetGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, +}) + // mainNetGenesisMerkleRoot is the hash of the first transaction in the genesis // block for the main network. var mainNetGenesisMerkleRoot = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. diff --git a/wire/message_test.go b/wire/message_test.go index d38fd0e34..c745b8f66 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -66,7 +66,7 @@ func TestMessage(t *testing.T) { msgFilterAdd := NewMsgFilterAdd([]byte{0x01}) msgFilterClear := NewMsgFilterClear() msgFilterLoad := NewMsgFilterLoad([]byte{0x01}, 10, 0, BloomUpdateNone) - bh := NewBlockHeader(1, &chainhash.Hash{}, &chainhash.Hash{}, 0, 0) + bh := NewBlockHeader(1, []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash}, &chainhash.Hash{}, 0, 0) msgMerkleBlock := NewMsgMerkleBlock(bh) msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block") msgGetCFilters := NewMsgGetCFilters(GCSFilterExtended, 0, &chainhash.Hash{}) @@ -89,7 +89,7 @@ func TestMessage(t *testing.T) { {msgGetAddr, msgGetAddr, pver, MainNet, 24}, {msgAddr, msgAddr, pver, MainNet, 25}, {msgGetBlocks, msgGetBlocks, pver, MainNet, 61}, - {msgBlock, msgBlock, pver, MainNet, 239}, + {msgBlock, msgBlock, pver, MainNet, 272}, {msgInv, msgInv, pver, MainNet, 25}, {msgGetData, msgGetData, pver, MainNet, 25}, {msgNotFound, msgNotFound, pver, MainNet, 25}, @@ -103,7 +103,7 @@ func TestMessage(t *testing.T) { {msgFilterAdd, msgFilterAdd, pver, MainNet, 26}, {msgFilterClear, msgFilterClear, pver, MainNet, 24}, {msgFilterLoad, msgFilterLoad, pver, MainNet, 35}, - {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 110}, + {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 143}, {msgReject, msgReject, pver, MainNet, 79}, {msgGetCFilters, msgGetCFilters, pver, MainNet, 61}, {msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61}, diff --git a/wire/msgblock.go b/wire/msgblock.go index d94e6313d..dd4409a94 100644 --- a/wire/msgblock.go +++ b/wire/msgblock.go @@ -202,7 +202,7 @@ func (msg *MsgBlock) Serialize(w io.Writer) error { func (msg *MsgBlock) SerializeSize() int { // Block header bytes + Serialized varint size for the number of // transactions. - n := blockHeaderLen + VarIntSerializeSize(uint64(len(msg.Transactions))) + n := msg.Header.SerializeSize() + VarIntSerializeSize(uint64(len(msg.Transactions))) for _, tx := range msg.Transactions { n += tx.SerializeSize() diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index 2ff6351b3..406e3ff79 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -20,11 +20,11 @@ func TestBlock(t *testing.T) { pver := ProtocolVersion // Block 1 header. - prevHash := &blockOne.Header.PrevBlock + prevHashes := blockOne.Header.PrevBlocks merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHashes, merkleHash, bits, nonce) // Ensure the command is expected value. wantCmd := "block" @@ -92,7 +92,7 @@ func TestBlockTxHashes(t *testing.T) { // TestBlockHash tests the ability to generate the hash of a block accurately. func TestBlockHash(t *testing.T) { // Block 1 hash. - hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048" + hashStr := "2357979742c556c68e90bf624a1139af8c85cafb4ac98d6d1dc367cd661ef67d" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewHashFromStr: %v", err) @@ -211,20 +211,24 @@ func TestBlockWireErrors(t *testing.T) { }{ // Force error in version. {&blockOne, blockOneBytes, pver, 0, io.ErrShortWrite, io.EOF}, - // Force error in prev block hash. + // Force error in num block hashes. {&blockOne, blockOneBytes, pver, 4, io.ErrShortWrite, io.EOF}, + // Force error in prev block hash #1. + {&blockOne, blockOneBytes, pver, 5, io.ErrShortWrite, io.EOF}, + // Force error in prev block hash #2. + {&blockOne, blockOneBytes, pver, 37, io.ErrShortWrite, io.EOF}, // Force error in merkle root. - {&blockOne, blockOneBytes, pver, 36, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, 69, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - {&blockOne, blockOneBytes, pver, 68, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, 101, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, pver, 72, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, 105, io.ErrShortWrite, io.EOF}, // Force error in header nonce. - {&blockOne, blockOneBytes, pver, 76, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, 109, io.ErrShortWrite, io.EOF}, // Force error in transaction count. - {&blockOne, blockOneBytes, pver, 80, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, 113, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, pver, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, 114, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -329,20 +333,24 @@ func TestBlockSerializeErrors(t *testing.T) { }{ // Force error in version. {&blockOne, blockOneBytes, 0, io.ErrShortWrite, io.EOF}, - // Force error in prev block hash. + // Force error in numPrevBlocks. {&blockOne, blockOneBytes, 4, io.ErrShortWrite, io.EOF}, + // Force error in prev block hash #1. + {&blockOne, blockOneBytes, 5, io.ErrShortWrite, io.EOF}, + // Force error in prev block hash #2. + {&blockOne, blockOneBytes, 37, io.ErrShortWrite, io.EOF}, // Force error in merkle root. - {&blockOne, blockOneBytes, 36, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 69, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - {&blockOne, blockOneBytes, 68, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 101, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, 72, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 105, io.ErrShortWrite, io.EOF}, // Force error in header nonce. - {&blockOne, blockOneBytes, 76, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 109, io.ErrShortWrite, io.EOF}, // Force error in transaction count. - {&blockOne, blockOneBytes, 80, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 113, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 114, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -396,14 +404,19 @@ func TestBlockOverflowErrors(t *testing.T) { { []byte{ 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, + 0x02, // NumPrevBlocks + 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // PrevBlock mainNetGenesisHash 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock - 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, - 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, - 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, - 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // PrevBlock simNetGenesisHash + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, + 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // MerkleRoot + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -456,7 +469,7 @@ func TestBlockSerializeSize(t *testing.T) { size int // Expected serialized size }{ // Block with no transactions. - {noTxBlock, 81}, + {noTxBlock, 114}, // First block in the mainnet block chain. {&blockOne, len(blockOneBytes)}, @@ -468,6 +481,7 @@ func TestBlockSerializeSize(t *testing.T) { if serializedSize != test.size { t.Errorf("MsgBlock.SerializeSize: #%d got: %d, want: "+ "%d", i, serializedSize, test.size) + continue } } @@ -476,19 +490,10 @@ func TestBlockSerializeSize(t *testing.T) { // blockOne is the first block in the mainnet block chain. var blockOne = MsgBlock{ Header: BlockHeader{ - Version: 1, - PrevBlock: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, - 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, - 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, - }), - MerkleRoot: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, - 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, - 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, - 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, - }), + Version: 1, + NumPrevBlocks: 2, + PrevBlocks: []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash}, + MerkleRoot: chainhash.Hash(mainNetGenesisMerkleRoot), Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST Bits: 0x1d00ffff, // 486604799 @@ -535,14 +540,19 @@ var blockOne = MsgBlock{ // Block one serialized bytes. var blockOneBytes = []byte{ 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, + 0x02, // NumPrevBlocks + 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // PrevBlock mainNetGenesisHash 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock - 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, - 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, - 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, - 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // PrevBlock simNetGenesisHash + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, + 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // MerkleRoot + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -576,5 +586,5 @@ var blockOneBytes = []byte{ // Transaction location information for block one transactions. var blockOneTxLocs = []TxLoc{ - {TxStart: 81, TxLen: 134}, + {TxStart: 114, TxLen: 134}, } diff --git a/wire/msgheaders_test.go b/wire/msgheaders_test.go index 1e44c56d2..3b363cf09 100644 --- a/wire/msgheaders_test.go +++ b/wire/msgheaders_test.go @@ -10,6 +10,7 @@ import ( "reflect" "testing" + "github.com/daglabs/btcd/chaincfg/chainhash" "github.com/davecgh/go-spew/spew" ) @@ -28,7 +29,7 @@ func TestHeaders(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num headers (varInt) + max allowed headers (header length + 1 byte // for the number of transactions which is always 0). - wantPayload := uint32(162009) + wantPayload := uint32(16420009) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ @@ -60,11 +61,11 @@ func TestHeaders(t *testing.T) { // TestHeadersWire tests the MsgHeaders wire encode and decode for various // numbers of headers and protocol versions. func TestHeadersWire(t *testing.T) { - hash := mainNetGenesisHash + hashes := []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash} merkleHash := blockOne.Header.MerkleRoot bits := uint32(0x1d00ffff) nonce := uint32(0x9962e301) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, hashes, &merkleHash, bits, nonce) bh.Version = blockOne.Header.Version bh.Timestamp = blockOne.Header.Timestamp @@ -80,14 +81,19 @@ func TestHeadersWire(t *testing.T) { oneHeaderEncoded := []byte{ 0x01, // VarInt for number of headers. 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, + 0x02, // NumPrevBlocks + 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // PrevBlock mainNetGenesisHash 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock - 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, - 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, - 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, - 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // PrevBlock simNetGenesisHash + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, + 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // MerkleRoot + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -217,11 +223,11 @@ func TestHeadersWireErrors(t *testing.T) { pver := ProtocolVersion wireErr := &MessageError{} - hash := mainNetGenesisHash + hashes := []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash} merkleHash := blockOne.Header.MerkleRoot bits := uint32(0x1d00ffff) nonce := uint32(0x9962e301) - bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bh := NewBlockHeader(1, hashes, &merkleHash, bits, nonce) bh.Version = blockOne.Header.Version bh.Timestamp = blockOne.Header.Timestamp @@ -231,14 +237,19 @@ func TestHeadersWireErrors(t *testing.T) { oneHeaderEncoded := []byte{ 0x01, // VarInt for number of headers. 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, + 0x02, // NumPrevBlocks + 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // PrevBlock mainNetGenesisHash 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock - 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, - 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, - 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, - 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // PrevBlock simNetGenesisHash + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, + 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // MerkleRoot + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -258,7 +269,7 @@ func TestHeadersWireErrors(t *testing.T) { // Intentionally invalid block header that has a transaction count used // to force errors. - bhTrans := NewBlockHeader(1, &hash, &merkleHash, bits, nonce) + bhTrans := NewBlockHeader(1, hashes, &merkleHash, bits, nonce) bhTrans.Version = blockOne.Header.Version bhTrans.Timestamp = blockOne.Header.Timestamp @@ -267,14 +278,19 @@ func TestHeadersWireErrors(t *testing.T) { transHeaderEncoded := []byte{ 0x01, // VarInt for number of headers. 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, + 0x02, // NumPrevBlocks + 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // PrevBlock mainNetGenesisHash 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock - 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, - 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, - 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, - 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // PrevBlock simNetGenesisHash + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, + 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // MerkleRoot + 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, + 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, + 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce @@ -297,7 +313,7 @@ func TestHeadersWireErrors(t *testing.T) { // Force error with greater than max headers. {maxHeaders, maxHeadersEncoded, pver, 3, wireErr, wireErr}, // Force error with number of transactions. - {transHeader, transHeaderEncoded, pver, 81, io.ErrShortWrite, io.EOF}, + {transHeader, transHeaderEncoded, pver, 114, io.ErrShortWrite, io.EOF}, // Force error with included transactions. {transHeader, transHeaderEncoded, pver, len(transHeaderEncoded), nil, wireErr}, } diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index 1d407f409..3ac7e9145 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -21,11 +21,11 @@ func TestMerkleBlock(t *testing.T) { pver := ProtocolVersion // Block 1 header. - prevHash := &blockOne.Header.PrevBlock + prevHashes := blockOne.Header.PrevBlocks merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHashes, merkleHash, bits, nonce) // Ensure the command is expected value. wantCmd := "merkleblock" @@ -113,11 +113,11 @@ func TestMerkleBlock(t *testing.T) { // the latest protocol version and decoding with BIP0031Version. func TestMerkleBlockCrossProtocol(t *testing.T) { // Block 1 header. - prevHash := &blockOne.Header.PrevBlock + prevHashes := blockOne.Header.PrevBlocks merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce - bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) + bh := NewBlockHeader(1, prevHashes, merkleHash, bits, nonce) msg := NewMsgMerkleBlock(bh) @@ -208,65 +208,33 @@ func TestMerkleBlockWireErrors(t *testing.T) { readErr error // Expected read error }{ // Force error in version. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 0, - io.ErrShortWrite, io.EOF, - }, - // Force error in prev block hash. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 4, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 0, io.ErrShortWrite, io.EOF}, + // Force error in num prev hashes. + {&merkleBlockOne, merkleBlockOneBytes, pver, 4, io.ErrShortWrite, io.EOF}, + // Force error in prev block hash #1. + {&merkleBlockOne, merkleBlockOneBytes, pver, 5, io.ErrShortWrite, io.EOF}, + // Force error in prev block hash #2. + {&merkleBlockOne, merkleBlockOneBytes, pver, 37, io.ErrShortWrite, io.EOF}, // Force error in merkle root. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 36, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 69, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 68, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 101, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 72, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 105, io.ErrShortWrite, io.EOF}, // Force error in header nonce. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 76, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 109, io.ErrShortWrite, io.EOF}, // Force error in transaction count. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 80, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 113, io.ErrShortWrite, io.EOF}, // Force error in num hashes. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 84, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 117, io.ErrShortWrite, io.EOF}, // Force error in hashes. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 85, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 118, io.ErrShortWrite, io.EOF}, // Force error in num flag bytes. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 117, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 150, io.ErrShortWrite, io.EOF}, // Force error in flag bytes. - { - &merkleBlockOne, merkleBlockOneBytes, pver, 118, - io.ErrShortWrite, io.EOF, - }, + {&merkleBlockOne, merkleBlockOneBytes, pver, 151, io.ErrShortWrite, io.EOF}, // Force error due to unsupported protocol version. - { - &merkleBlockOne, merkleBlockOneBytes, pverNoMerkleBlock, - 119, wireErr, wireErr, - }, + {&merkleBlockOne, merkleBlockOneBytes, pverNoMerkleBlock, 151, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) @@ -326,7 +294,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { // allowed tx hashes. var buf bytes.Buffer WriteVarInt(&buf, pver, maxTxPerBlock+1) - numHashesOffset := 84 + numHashesOffset := 117 exceedMaxHashes := make([]byte, numHashesOffset) copy(exceedMaxHashes, merkleBlockOneBytes[:numHashesOffset]) exceedMaxHashes = append(exceedMaxHashes, buf.Bytes()...) @@ -335,7 +303,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { // allowed flag bytes. buf.Reset() WriteVarInt(&buf, pver, maxFlagsPerMerkleBlock+1) - numFlagBytesOffset := 117 + numFlagBytesOffset := 150 exceedMaxFlagBytes := make([]byte, numFlagBytesOffset) copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset]) exceedMaxFlagBytes = append(exceedMaxFlagBytes, buf.Bytes()...) @@ -369,13 +337,9 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { // where the first transaction matches. var merkleBlockOne = MsgMerkleBlock{ Header: BlockHeader{ - Version: 1, - PrevBlock: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, - 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, - 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, - }), + Version: 1, + NumPrevBlocks: 2, + PrevBlocks: []chainhash.Hash{mainNetGenesisHash, simNetGenesisHash}, MerkleRoot: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, @@ -402,14 +366,19 @@ var merkleBlockOne = MsgMerkleBlock{ // block one of the block chain where the first transaction matches. var merkleBlockOneBytes = []byte{ 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, + 0x02, // NumPrevBlocks + 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // PrevBlock mainNetGenesisHash 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock - 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, + 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // PrevBlock simNetGenesisHash + 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, + 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, + 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, + 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, // MerkleRoot 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, - 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot + 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, 0x61, 0xbc, 0x66, 0x49, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce