8 "github.com/vapor/encoding/blockchain"
9 "github.com/vapor/encoding/bufpool"
10 "github.com/vapor/errors"
13 // serflag variables, start with 1
21 // Block describes a complete block, including its header and the transactions
28 // MarshalText fulfills the json.Marshaler interface. This guarantees that
29 // blocks will get deserialized correctly when being parsed from HTTP requests.
30 func (b *Block) MarshalText() ([]byte, error) {
32 defer bufpool.Put(buf)
34 if _, err := b.WriteTo(buf); err != nil {
38 enc := make([]byte, hex.EncodedLen(buf.Len()))
39 hex.Encode(enc, buf.Bytes())
43 // UnmarshalText fulfills the encoding.TextUnmarshaler interface.
44 func (b *Block) UnmarshalText(text []byte) error {
45 decoded := make([]byte, hex.DecodedLen(len(text)))
46 if _, err := hex.Decode(decoded, text); err != nil {
50 r := blockchain.NewReader(decoded)
51 if err := b.readFrom(r); err != nil {
55 if trailing := r.Len(); trailing > 0 {
56 return fmt.Errorf("trailing garbage (%d bytes)", trailing)
61 // MarshalTextForBlockHeader fulfills the json.Marshaler interface.
62 func (b *Block) MarshalTextForBlockHeader() ([]byte, error) {
64 defer bufpool.Put(buf)
66 ew := errors.NewWriter(buf)
67 if err := b.writeTo(ew, SerBlockHeader); err != nil {
70 if err := ew.Err(); err != nil {
74 enc := make([]byte, hex.EncodedLen(buf.Len()))
75 hex.Encode(enc, buf.Bytes())
79 // MarshalTextForTransactions fulfills the json.Marshaler interface.
80 func (b *Block) MarshalTextForTransactions() ([]byte, error) {
82 defer bufpool.Put(buf)
84 ew := errors.NewWriter(buf)
85 if err := b.writeTo(ew, SerBlockTransactions); err != nil {
88 if err := ew.Err(); err != nil {
92 enc := make([]byte, hex.EncodedLen(buf.Len()))
93 hex.Encode(enc, buf.Bytes())
97 func (b *Block) readFrom(r *blockchain.Reader) error {
98 serflag, err := b.BlockHeader.readFrom(r)
103 if serflag == SerBlockHeader {
107 n, err := blockchain.ReadVarint31(r)
109 return errors.Wrap(err, "reading number of transactions")
114 if err = data.readFrom(r); err != nil {
115 return errors.Wrapf(err, "reading transaction %d", len(b.Transactions))
118 b.Transactions = append(b.Transactions, NewTx(data))
123 // WriteTo will write block to input io.Writer
124 func (b *Block) WriteTo(w io.Writer) (int64, error) {
125 ew := errors.NewWriter(w)
126 if err := b.writeTo(ew, SerBlockFull); err != nil {
129 return ew.Written(), ew.Err()
132 func (b *Block) writeTo(w io.Writer, serflags uint8) error {
133 if serflags == SerBlockHeader || serflags == SerBlockFull {
134 if err := b.BlockHeader.writeTo(w, serflags); err != nil {
139 if serflags == SerBlockHeader {
143 if serflags != SerBlockFull {
144 w.Write([]byte{serflags})
147 if _, err := blockchain.WriteVarint31(w, uint64(len(b.Transactions))); err != nil {
151 for _, tx := range b.Transactions {
152 if _, err := tx.WriteTo(w); err != nil {