OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / wire / msgblock.go
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         "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.
20 const defaultTransactionAlloc = 2048
21
22 // MaxBlocksPerMsg is the maximum number of blocks allowed per message.
23 const 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.
27 const MaxBlockPayload = 4000000
28
29 // maxTxPerBlock is the maximum number of transactions that could
30 // possibly fit into a block.
31 const 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.
35 type 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.
43 type MsgBlock struct {
44         Header       BlockHeader
45         Transactions []*MsgTx
46 }
47
48 // AddTransaction adds a transaction to the message.
49 func (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.
56 func (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.
64 func (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.
106 func (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.
121 func (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.
129 func (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.
176 func (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.
206 func (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.
222 func (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.
228 func (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).
242 func (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.
256 func (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.
262 func (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.
270 func (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.
275 func (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.
285 func NewMsgBlock(blockHeader *BlockHeader) *MsgBlock {
286         return &MsgBlock{
287                 Header:       *blockHeader,
288                 Transactions: make([]*MsgTx, 0, defaultTransactionAlloc),
289         }
290 }