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 5package wire 6 7import ( 8 "bytes" 9 "fmt" 10 "io" 11 12 "github.com/btcsuite/btcd/chaincfg/chainhash" 13) 14 15// defaultTransactionAlloc is the default size used for the backing array 16// for transactions. The transaction array will dynamically grow as needed, but 17// this figure is intended to provide enough space for the number of 18// transactions in the vast majority of blocks without needing to grow the 19// backing array multiple times. 20const defaultTransactionAlloc = 2048 21 22// MaxBlocksPerMsg is the maximum number of blocks allowed per message. 23const MaxBlocksPerMsg = 500 24 25// MaxBlockPayload is the maximum bytes a block message can be in bytes. 26// After Segregated Witness, the max block payload has been raised to 4MB. 27const MaxBlockPayload = 4000000 28 29// maxTxPerBlock is the maximum number of transactions that could 30// possibly fit into a block. 31const maxTxPerBlock = (MaxBlockPayload / minTxPayload) + 1 32 33// TxLoc holds locator data for the offset and length of where a transaction is 34// located within a MsgBlock data buffer. 35type TxLoc struct { 36 TxStart int 37 TxLen int 38} 39 40// MsgBlock implements the Message interface and represents a bitcoin 41// block message. It is used to deliver block and transaction information in 42// response to a getdata message (MsgGetData) for a given block hash. 43type MsgBlock struct { 44 Header BlockHeader 45 Transactions []*MsgTx 46} 47 48// AddTransaction adds a transaction to the message. 49func (msg *MsgBlock) AddTransaction(tx *MsgTx) error { 50 msg.Transactions = append(msg.Transactions, tx) 51 return nil 52 53} 54 55// ClearTransactions removes all transactions from the message. 56func (msg *MsgBlock) ClearTransactions() { 57 msg.Transactions = make([]*MsgTx, 0, defaultTransactionAlloc) 58} 59 60// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 61// This is part of the Message interface implementation. 62// See Deserialize for decoding blocks stored to disk, such as in a database, as 63// opposed to decoding blocks from the wire. 64func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 65 err := readBlockHeader(r, pver, &msg.Header) 66 if err != nil { 67 return err 68 } 69 70 txCount, err := ReadVarInt(r, pver) 71 if err != nil { 72 return err 73 } 74 75 // Prevent more transactions than could possibly fit into a block. 76 // It would be possible to cause memory exhaustion and panics without 77 // a sane upper bound on this count. 78 if txCount > maxTxPerBlock { 79 str := fmt.Sprintf("too many transactions to fit into a block "+ 80 "[count %d, max %d]", txCount, maxTxPerBlock) 81 return messageError("MsgBlock.BtcDecode", str) 82 } 83 84 msg.Transactions = make([]*MsgTx, 0, txCount) 85 for i := uint64(0); i < txCount; i++ { 86 tx := MsgTx{} 87 err := tx.BtcDecode(r, pver, enc) 88 if err != nil { 89 return err 90 } 91 msg.Transactions = append(msg.Transactions, &tx) 92 } 93 94 return nil 95} 96 97// Deserialize decodes a block from r into the receiver using a format that is 98// suitable for long-term storage such as a database while respecting the 99// Version field in the block. This function differs from BtcDecode in that 100// BtcDecode decodes from the bitcoin wire protocol as it was sent across the 101// network. The wire encoding can technically differ depending on the protocol 102// version and doesn't even really need to match the format of a stored block at 103// all. As of the time this comment was written, the encoded block is the same 104// in both instances, but there is a distinct difference and separating the two 105// allows the API to be flexible enough to deal with changes. 106func (msg *MsgBlock) Deserialize(r io.Reader) error { 107 // At the current time, there is no difference between the wire encoding 108 // at protocol version 0 and the stable long-term storage format. As 109 // a result, make use of BtcDecode. 110 // 111 // Passing an encoding type of WitnessEncoding to BtcEncode for the 112 // MessageEncoding parameter indicates that the transactions within the 113 // block are expected to be serialized according to the new 114 // serialization structure defined in BIP0141. 115 return msg.BtcDecode(r, 0, WitnessEncoding) 116} 117 118// DeserializeNoWitness decodes a block from r into the receiver similar to 119// Deserialize, however DeserializeWitness strips all (if any) witness data 120// from the transactions within the block before encoding them. 121func (msg *MsgBlock) DeserializeNoWitness(r io.Reader) error { 122 return msg.BtcDecode(r, 0, BaseEncoding) 123} 124 125// DeserializeTxLoc decodes r in the same manner Deserialize does, but it takes 126// a byte buffer instead of a generic reader and returns a slice containing the 127// start and length of each transaction within the raw data that is being 128// deserialized. 129func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) { 130 fullLen := r.Len() 131 132 // At the current time, there is no difference between the wire encoding 133 // at protocol version 0 and the stable long-term storage format. As 134 // a result, make use of existing wire protocol functions. 135 err := readBlockHeader(r, 0, &msg.Header) 136 if err != nil { 137 return nil, err 138 } 139 140 txCount, err := ReadVarInt(r, 0) 141 if err != nil { 142 return nil, err 143 } 144 145 // Prevent more transactions than could possibly fit into a block. 146 // It would be possible to cause memory exhaustion and panics without 147 // a sane upper bound on this count. 148 if txCount > maxTxPerBlock { 149 str := fmt.Sprintf("too many transactions to fit into a block "+ 150 "[count %d, max %d]", txCount, maxTxPerBlock) 151 return nil, messageError("MsgBlock.DeserializeTxLoc", str) 152 } 153 154 // Deserialize each transaction while keeping track of its location 155 // within the byte stream. 156 msg.Transactions = make([]*MsgTx, 0, txCount) 157 txLocs := make([]TxLoc, txCount) 158 for i := uint64(0); i < txCount; i++ { 159 txLocs[i].TxStart = fullLen - r.Len() 160 tx := MsgTx{} 161 err := tx.Deserialize(r) 162 if err != nil { 163 return nil, err 164 } 165 msg.Transactions = append(msg.Transactions, &tx) 166 txLocs[i].TxLen = (fullLen - r.Len()) - txLocs[i].TxStart 167 } 168 169 return txLocs, nil 170} 171 172// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 173// This is part of the Message interface implementation. 174// See Serialize for encoding blocks to be stored to disk, such as in a 175// database, as opposed to encoding blocks for the wire. 176func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 177 err := writeBlockHeader(w, pver, &msg.Header) 178 if err != nil { 179 return err 180 } 181 182 err = WriteVarInt(w, pver, uint64(len(msg.Transactions))) 183 if err != nil { 184 return err 185 } 186 187 for _, tx := range msg.Transactions { 188 err = tx.BtcEncode(w, pver, enc) 189 if err != nil { 190 return err 191 } 192 } 193 194 return nil 195} 196 197// Serialize encodes the block to w using a format that suitable for long-term 198// storage such as a database while respecting the Version field in the block. 199// This function differs from BtcEncode in that BtcEncode encodes the block to 200// the bitcoin wire protocol in order to be sent across the network. The wire 201// encoding can technically differ depending on the protocol version and doesn't 202// even really need to match the format of a stored block at all. As of the 203// time this comment was written, the encoded block is the same in both 204// instances, but there is a distinct difference and separating the two allows 205// the API to be flexible enough to deal with changes. 206func (msg *MsgBlock) Serialize(w io.Writer) error { 207 // At the current time, there is no difference between the wire encoding 208 // at protocol version 0 and the stable long-term storage format. As 209 // a result, make use of BtcEncode. 210 // 211 // Passing WitnessEncoding as the encoding type here indicates that 212 // each of the transactions should be serialized using the witness 213 // serialization structure defined in BIP0141. 214 return msg.BtcEncode(w, 0, WitnessEncoding) 215} 216 217// SerializeNoWitness encodes a block to w using an identical format to 218// Serialize, with all (if any) witness data stripped from all transactions. 219// This method is provided in additon to the regular Serialize, in order to 220// allow one to selectively encode transaction witness data to non-upgraded 221// peers which are unaware of the new encoding. 222func (msg *MsgBlock) SerializeNoWitness(w io.Writer) error { 223 return msg.BtcEncode(w, 0, BaseEncoding) 224} 225 226// SerializeSize returns the number of bytes it would take to serialize the 227// block, factoring in any witness data within transaction. 228func (msg *MsgBlock) SerializeSize() int { 229 // Block header bytes + Serialized varint size for the number of 230 // transactions. 231 n := blockHeaderLen + VarIntSerializeSize(uint64(len(msg.Transactions))) 232 233 for _, tx := range msg.Transactions { 234 n += tx.SerializeSize() 235 } 236 237 return n 238} 239 240// SerializeSizeStripped returns the number of bytes it would take to serialize 241// the block, excluding any witness data (if any). 242func (msg *MsgBlock) SerializeSizeStripped() int { 243 // Block header bytes + Serialized varint size for the number of 244 // transactions. 245 n := blockHeaderLen + VarIntSerializeSize(uint64(len(msg.Transactions))) 246 247 for _, tx := range msg.Transactions { 248 n += tx.SerializeSizeStripped() 249 } 250 251 return n 252} 253 254// Command returns the protocol command string for the message. This is part 255// of the Message interface implementation. 256func (msg *MsgBlock) Command() string { 257 return CmdBlock 258} 259 260// MaxPayloadLength returns the maximum length the payload can be for the 261// receiver. This is part of the Message interface implementation. 262func (msg *MsgBlock) MaxPayloadLength(pver uint32) uint32 { 263 // Block header at 80 bytes + transaction count + max transactions 264 // which can vary up to the MaxBlockPayload (including the block header 265 // and transaction count). 266 return MaxBlockPayload 267} 268 269// BlockHash computes the block identifier hash for this block. 270func (msg *MsgBlock) BlockHash() chainhash.Hash { 271 return msg.Header.BlockHash() 272} 273 274// TxHashes returns a slice of hashes of all of transactions in this block. 275func (msg *MsgBlock) TxHashes() ([]chainhash.Hash, error) { 276 hashList := make([]chainhash.Hash, 0, len(msg.Transactions)) 277 for _, tx := range msg.Transactions { 278 hashList = append(hashList, tx.TxHash()) 279 } 280 return hashList, nil 281} 282 283// NewMsgBlock returns a new bitcoin block message that conforms to the 284// Message interface. See MsgBlock for details. 285func NewMsgBlock(blockHeader *BlockHeader) *MsgBlock { 286 return &MsgBlock{ 287 Header: *blockHeader, 288 Transactions: make([]*MsgTx, 0, defaultTransactionAlloc), 289 } 290} 291