OSDN Git Service

fix conflict
[bytom/bytom.git] / protocol / bc / types / block.go
1 package types
2
3 import (
4         "encoding/hex"
5         "fmt"
6         "io"
7
8         "github.com/bytom/bytom/encoding/blockchain"
9         "github.com/bytom/bytom/encoding/bufpool"
10         "github.com/bytom/bytom/errors"
11 )
12
13 // serflag variables, start with 1
14 const (
15         _ = iota
16         SerBlockHeader
17         SerBlockTransactions
18         SerBlockFull
19 )
20
21 // Block describes a complete block, including its header and the transactions
22 // it contains.
23 type Block struct {
24         BlockHeader
25         Transactions []*Tx
26 }
27
28 func (b *Block) marshalText(serflags uint8) ([]byte, error) {
29         buf := bufpool.Get()
30         defer bufpool.Put(buf)
31
32         ew := errors.NewWriter(buf)
33         if err := b.writeTo(ew, serflags); err != nil {
34                 return nil, err
35         }
36
37         if err := ew.Err(); err != nil {
38                 return nil, err
39         }
40
41         enc := make([]byte, hex.EncodedLen(buf.Len()))
42         hex.Encode(enc, buf.Bytes())
43         return enc, nil
44 }
45
46 // MarshalText fulfills the json.Marshaler interface. This guarantees that
47 // blocks will get deserialized correctly when being parsed from HTTP requests.
48 func (b *Block) MarshalText() ([]byte, error) {
49         return b.marshalText(SerBlockFull)
50 }
51
52 // MarshalTextForBlockHeader fulfills the json.Marshaler interface.
53 func (b *Block) MarshalTextForBlockHeader() ([]byte, error) {
54         return b.marshalText(SerBlockHeader)
55 }
56
57 // MarshalTextForTransactions fulfills the json.Marshaler interface.
58 func (b *Block) MarshalTextForTransactions() ([]byte, error) {
59         return b.marshalText(SerBlockTransactions)
60 }
61
62 // UnmarshalText fulfills the encoding.TextUnmarshaler interface.
63 func (b *Block) UnmarshalText(text []byte) error {
64         decoded := make([]byte, hex.DecodedLen(len(text)))
65         if _, err := hex.Decode(decoded, text); err != nil {
66                 return err
67         }
68
69         r := blockchain.NewReader(decoded)
70         if err := b.readFrom(r); err != nil {
71                 return err
72         }
73
74         if trailing := r.Len(); trailing > 0 {
75                 return fmt.Errorf("trailing garbage (%d bytes)", trailing)
76         }
77         return nil
78 }
79
80 func (b *Block) readFrom(r *blockchain.Reader) error {
81         serflag, err := b.BlockHeader.readFrom(r)
82         if err != nil {
83                 return err
84         }
85
86         if serflag == SerBlockHeader {
87                 return nil
88         }
89
90         n, err := blockchain.ReadVarint31(r)
91         if err != nil {
92                 return errors.Wrap(err, "reading number of transactions")
93         }
94
95         for ; n > 0; n-- {
96                 data := TxData{}
97                 if err = data.readFrom(r); err != nil {
98                         return errors.Wrapf(err, "reading transaction %d", len(b.Transactions))
99                 }
100
101                 b.Transactions = append(b.Transactions, NewTx(data))
102         }
103         return nil
104 }
105
106 // WriteTo write block to io.Writer
107 func (b *Block) WriteTo(w io.Writer) (int64, error) {
108         ew := errors.NewWriter(w)
109         if err := b.writeTo(ew, SerBlockFull); err != nil {
110                 return 0, err
111         }
112         return ew.Written(), ew.Err()
113 }
114
115 func (b *Block) writeTo(w io.Writer, serflags uint8) error {
116         if err := b.BlockHeader.writeTo(w, serflags); err != nil {
117                 return err
118         }
119
120         if serflags == SerBlockHeader {
121                 return nil
122         }
123
124         if _, err := blockchain.WriteVarint31(w, uint64(len(b.Transactions))); err != nil {
125                 return err
126         }
127
128         for _, tx := range b.Transactions {
129                 if _, err := tx.WriteTo(w); err != nil {
130                         return err
131                 }
132         }
133         return nil
134 }