github.com/palcoin-project/palcd@v1.0.0/wire/blockheader.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package wire 6 7 import ( 8 "bytes" 9 "io" 10 "time" 11 12 "github.com/palcoin-project/palcd/chaincfg/chainhash" 13 ) 14 15 // MaxBlockHeaderPayload is the maximum number of bytes a block header can be. 16 // Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes + 17 // PrevBlock and MerkleRoot hashes. 18 const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2) 19 20 // BlockHeader defines information about a block and is used in the bitcoin 21 // block (MsgBlock) and headers (MsgHeaders) messages. 22 type BlockHeader struct { 23 // Version of the block. This is not the same as the protocol version. 24 Version int32 25 26 // Hash of the previous block header in the block chain. 27 PrevBlock chainhash.Hash 28 29 // Merkle tree reference to hash of all transactions for the block. 30 MerkleRoot chainhash.Hash 31 32 // Time the block was created. This is, unfortunately, encoded as a 33 // uint32 on the wire and therefore is limited to 2106. 34 Timestamp time.Time 35 36 // Difficulty target for the block. 37 Bits uint32 38 39 // Nonce used to generate the block. 40 Nonce uint32 41 } 42 43 // blockHeaderLen is a constant that represents the number of bytes for a block 44 // header. 45 const blockHeaderLen = 80 46 47 // BlockHash computes the block identifier hash for the given block header. 48 func (h *BlockHeader) BlockHash() chainhash.Hash { 49 // Encode the header and double sha256 everything prior to the number of 50 // transactions. Ignore the error returns since there is no way the 51 // encode could fail except being out of memory which would cause a 52 // run-time panic. 53 buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload)) 54 _ = writeBlockHeader(buf, 0, h) 55 56 return chainhash.DoubleHashH(buf.Bytes()) 57 } 58 59 // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 60 // This is part of the Message interface implementation. 61 // See Deserialize for decoding block headers stored to disk, such as in a 62 // database, as opposed to decoding block headers from the wire. 63 func (h *BlockHeader) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 64 return readBlockHeader(r, pver, h) 65 } 66 67 // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 68 // This is part of the Message interface implementation. 69 // See Serialize for encoding block headers to be stored to disk, such as in a 70 // database, as opposed to encoding block headers for the wire. 71 func (h *BlockHeader) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 72 return writeBlockHeader(w, pver, h) 73 } 74 75 // Deserialize decodes a block header from r into the receiver using a format 76 // that is suitable for long-term storage such as a database while respecting 77 // the Version field. 78 func (h *BlockHeader) Deserialize(r io.Reader) error { 79 // At the current time, there is no difference between the wire encoding 80 // at protocol version 0 and the stable long-term storage format. As 81 // a result, make use of readBlockHeader. 82 return readBlockHeader(r, 0, h) 83 } 84 85 // Serialize encodes a block header from r into the receiver using a format 86 // that is suitable for long-term storage such as a database while respecting 87 // the Version field. 88 func (h *BlockHeader) Serialize(w io.Writer) error { 89 // At the current time, there is no difference between the wire encoding 90 // at protocol version 0 and the stable long-term storage format. As 91 // a result, make use of writeBlockHeader. 92 return writeBlockHeader(w, 0, h) 93 } 94 95 // NewBlockHeader returns a new BlockHeader using the provided version, previous 96 // block hash, merkle root hash, difficulty bits, and nonce used to generate the 97 // block with defaults for the remaining fields. 98 func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, 99 bits uint32, nonce uint32) *BlockHeader { 100 101 // Limit the timestamp to one second precision since the protocol 102 // doesn't support better. 103 return &BlockHeader{ 104 Version: version, 105 PrevBlock: *prevHash, 106 MerkleRoot: *merkleRootHash, 107 Timestamp: time.Unix(time.Now().Unix(), 0), 108 Bits: bits, 109 Nonce: nonce, 110 } 111 } 112 113 // readBlockHeader reads a bitcoin block header from r. See Deserialize for 114 // decoding block headers stored to disk, such as in a database, as opposed to 115 // decoding from the wire. 116 func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { 117 return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot, 118 (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) 119 } 120 121 // writeBlockHeader writes a bitcoin block header to w. See Serialize for 122 // encoding block headers to be stored to disk, such as in a database, as 123 // opposed to encoding for the wire. 124 func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error { 125 sec := uint32(bh.Timestamp.Unix()) 126 return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot, 127 sec, bh.Bits, bh.Nonce) 128 }