github.com/bchainhub/blockbook@v0.3.2/bchain/coins/utils/parserutils.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/martinboehm/btcd/wire" 8 ) 9 10 // minTxPayload is the minimum payload size for a transaction. Note 11 // that any realistically usable transaction must have at least one 12 // input or output, but that is a rule enforced at a higher layer, so 13 // it is intentionally not included here. 14 // Version 4 bytes + Varint number of transaction inputs 1 byte + Varint 15 // number of transaction outputs 1 byte + LockTime 4 bytes + min input 16 // payload + min output payload. 17 const minTxPayload = 10 18 19 // maxTxPerBlock is the maximum number of transactions that could 20 // possibly fit into a block. 21 const maxTxPerBlock = (wire.MaxBlockPayload / minTxPayload) + 1 22 23 // DecodeTransactions decodes transactions from input stream using wire 24 func DecodeTransactions(r io.Reader, pver uint32, enc wire.MessageEncoding, blk *wire.MsgBlock) error { 25 txCount, err := wire.ReadVarInt(r, pver) 26 if err != nil { 27 return err 28 } 29 30 // Prevent more transactions than could possibly fit into a block. 31 // It would be possible to cause memory exhaustion and panics without 32 // a sane upper bound on this count. 33 if txCount > maxTxPerBlock { 34 str := fmt.Sprintf("too many transactions to fit into a block "+ 35 "[count %d, max %d]", txCount, maxTxPerBlock) 36 return &wire.MessageError{Func: "utils.decodeTransactions", Description: str} 37 } 38 39 blk.Transactions = make([]*wire.MsgTx, 0, txCount) 40 for i := uint64(0); i < txCount; i++ { 41 tx := wire.MsgTx{} 42 err := tx.BtcDecode(r, pver, enc) 43 if err != nil { 44 return err 45 } 46 blk.Transactions = append(blk.Transactions, &tx) 47 } 48 49 return nil 50 } 51 52 // VersionAuxpow marks that block contains Auxpow 53 const VersionAuxpow = (1 << 8) 54 55 // SkipAuxpow skips Auxpow data in block 56 func SkipAuxpow(r io.ReadSeeker) error { 57 // skip Auxpow part of the block 58 // https://github.com/dogecoin/dogecoin/blob/master/src/auxpow.h#L130 59 // CMerkleTx CTransaction 60 tx := wire.MsgTx{} 61 err := tx.BtcDecode(r, 0, wire.WitnessEncoding) 62 if err != nil { 63 return err 64 } 65 // CMerkleTx uint256 hashBlock 66 _, err = r.Seek(32, io.SeekCurrent) 67 if err != nil { 68 return err 69 } 70 // CMerkleTx std::vector<uint256> vMerkleBranch 71 size, err := wire.ReadVarInt(r, 0) 72 if err != nil { 73 return err 74 } 75 _, err = r.Seek(int64(size)*32, io.SeekCurrent) 76 if err != nil { 77 return err 78 } 79 // CMerkleTx int nIndex 80 _, err = r.Seek(4, io.SeekCurrent) 81 if err != nil { 82 return err 83 } 84 // CAuxPow std::vector<uint256> vChainMerkleBranch; 85 size, err = wire.ReadVarInt(r, 0) 86 if err != nil { 87 return err 88 } 89 _, err = r.Seek(int64(size)*32, io.SeekCurrent) 90 if err != nil { 91 return err 92 } 93 // CAuxPow int nChainIndex; 94 _, err = r.Seek(4, io.SeekCurrent) 95 if err != nil { 96 return err 97 } 98 // CAuxPow CPureBlockHeader parentBlock; 99 ph := wire.BlockHeader{} 100 err = ph.Deserialize(r) 101 if err != nil { 102 return err 103 } 104 return nil 105 }