diff --git a/wire/message.go b/wire/message.go index 84ffef9b..80e9fe3c 100644 --- a/wire/message.go +++ b/wire/message.go @@ -53,7 +53,7 @@ const ( CmdFeeFilter = "feefilter" ) -// WireEncoding represents the wire message encoding format to be used. +// MessageEncoding represents the wire message encoding format to be used. type MessageEncoding uint32 const ( diff --git a/wire/msgblock.go b/wire/msgblock.go index 73c264a5..4172949d 100644 --- a/wire/msgblock.go +++ b/wire/msgblock.go @@ -23,7 +23,8 @@ const defaultTransactionAlloc = 2048 const MaxBlocksPerMsg = 500 // MaxBlockPayload is the maximum bytes a block message can be in bytes. -const MaxBlockPayload = 1000000 // Not actually 1MB which would be 1024 * 1024 +// After Segregated Witness, the max block payload has been raised to 4MB. +const MaxBlockPayload = 4000000 // maxTxPerBlock is the maximum number of transactions that could // possibly fit into a block. @@ -114,7 +115,7 @@ func (msg *MsgBlock) Deserialize(r io.Reader) error { return msg.BtcDecode(r, 0, WitnessEncoding) } -// DeserializeWitness decodes a block from r into the receiver similar to +// DeserializeNoWitness decodes a block from r into the receiver similar to // Deserialize, however DeserializeWitness strips all (if any) witness data // from the transactions within the block before encoding them. func (msg *MsgBlock) DeserializeNoWitness(r io.Reader) error { @@ -213,8 +214,8 @@ func (msg *MsgBlock) Serialize(w io.Writer) error { return msg.BtcEncode(w, 0, WitnessEncoding) } -// SerializeWitness encodes a block to w using an identical format to Serialize, -// with all (if any) witness data stripped from all transactions. +// SerializeNoWitness encodes a block to w using an identical format to +// Serialize, with all (if any) witness data stripped from all transactions. // This method is provided in additon to the regular Serialize, in order to // allow one to selectively encode transaction witness data to non-upgraded // peers which are unaware of the new encoding. @@ -223,7 +224,7 @@ func (msg *MsgBlock) SerializeNoWitness(w io.Writer) error { } // SerializeSize returns the number of bytes it would take to serialize the -// the block. +// block, factoring in any witness data within transaction. func (msg *MsgBlock) SerializeSize() int { // Block header bytes + Serialized varint size for the number of // transactions. @@ -236,6 +237,20 @@ func (msg *MsgBlock) SerializeSize() int { return n } +// SerializeSizeStripped returns the number of bytes it would take to serialize +// the block, excluding any witness data (if any). +func (msg *MsgBlock) SerializeSizeStripped() int { + // Block header bytes + Serialized varint size for the number of + // transactions. + n := blockHeaderLen + VarIntSerializeSize(uint64(len(msg.Transactions))) + + for _, tx := range msg.Transactions { + n += tx.SerializeSizeStripped() + } + + return n +} + // Command returns the protocol command string for the message. This is part // of the Message interface implementation. func (msg *MsgBlock) Command() string { diff --git a/wire/msgtx.go b/wire/msgtx.go index 144f27aa..a22118e6 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -93,8 +93,31 @@ const ( // peers. Thus, the peak usage of the free list is 12,500 * 512 = // 6,400,000 bytes. freeListMaxItems = 12500 + + // maxWitnessItemsPerInput is the maximum number of witness items to + // be read for the witness data for a single TxIn. This number is + // derived using a possble lower bound for the encoding of a witness + // item: 1 byte for length + 1 byte for the witness item itself, or two + // bytes. This value is then divided by the currently allowed maximum + // "cost" for a transaction. + maxWitnessItemsPerInput = 500000 + + // maxWitnessItemSize is the maximum allowed size for an item within + // an input's witness data. This number is derived from the fact that + // for script validation, each pushed item onto the stack must be less + // than 10k bytes. + maxWitnessItemSize = 11000 ) +// witnessMarkerBytes are a pair of bytes specific to the witness encoding. If +// this sequence is encoutered, then it indicates a transaction has iwtness +// data. The first byte is an always 0x00 marker byte, which allows decoders to +// distinguish a serialized transaction with witnesses from a regular (legacy) +// one. The second byte is the Flag field, which at the moment is always 0x01, +// but may be extended in the future to accommodate auxiliary non-committed +// fields. +var witessMarkerBytes = []byte{0x00, 0x01} + // scriptFreeList defines a free list of byte slices (up to the maximum number // defined by the freeListMaxItems constant) that have a cap according to the // freeListMaxScriptSize constant. It is used to provide temporary buffers for @@ -187,6 +210,7 @@ func (o OutPoint) String() string { type TxIn struct { PreviousOutPoint OutPoint SignatureScript []byte + Witness TxWitness Sequence uint32 } @@ -203,14 +227,36 @@ func (t *TxIn) SerializeSize() int { // NewTxIn returns a new bitcoin transaction input with the provided // previous outpoint point and signature script with a default sequence of // MaxTxInSequenceNum. -func NewTxIn(prevOut *OutPoint, signatureScript []byte) *TxIn { +func NewTxIn(prevOut *OutPoint, signatureScript []byte, witness [][]byte) *TxIn { return &TxIn{ PreviousOutPoint: *prevOut, SignatureScript: signatureScript, + Witness: witness, Sequence: MaxTxInSequenceNum, } } +// TxWitness defines the witness for a TxIn. A witness is to be interpreted as +// a slice of byte slices, or a stack with one or many elements. +type TxWitness [][]byte + +// SerializeSize returns the number of bytes it would take to serialize the the +// transaction input's witness. +func (t TxWitness) SerializeSize() int { + // A varint to signal the number of elements the witness has. + n := VarIntSerializeSize(uint64(len(t))) + + // For each element in the witness, we'll need a varint to signal the + // size of the element, then finally the number of bytes the element + // itself comprises. + for _, witItem := range t { + n += VarIntSerializeSize(uint64(len(witItem))) + n += len(witItem) + } + + return n +} + // TxOut defines a bitcoin transaction output. type TxOut struct { Value int64 @@ -263,8 +309,8 @@ func (msg *MsgTx) TxHash() chainhash.Hash { // Ignore the error returns since the only way the encode could fail // is being out of memory or due to nil pointers, both of which would // cause a run-time panic. - buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSize())) - _ = msg.Serialize(buf) + buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSizeStripped())) + _ = msg.SerializeNoWitness(buf) return chainhash.DoubleHashH(buf.Bytes()) } @@ -297,13 +343,26 @@ func (msg *MsgTx) Copy() *MsgTx { copy(newScript, oldScript[:oldScriptLen]) } - // Create new txIn with the deep copied data and append it to - // new Tx. + // Create new txIn with the deep copied data. newTxIn := TxIn{ PreviousOutPoint: newOutPoint, SignatureScript: newScript, Sequence: oldTxIn.Sequence, } + + // If the transaction is witnessy, then also copy the + // witnesses. + if len(oldTxIn.Witness) != 0 { + // Deep copy the old witness data. + newTxIn.Witness = make([][]byte, len(oldTxIn.Witness)) + for i, oldItem := range oldTxIn.Witness { + newItem := make([]byte, len(oldItem)) + copy(newItem, oldItem) + newTxIn.Witness[i] = newItem + } + } + + // Finally, append this fully copied txin. newTx.TxIn = append(newTx.TxIn, &newTxIn) } @@ -346,6 +405,30 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error return err } + // A count of zero (meaning no TxIn's to the uninitiated) indicates + // this is a transaction with witness data. + var flag [1]byte + if count == 0 && enc == WitnessEncoding { + // Next, we need to read the flag, which is a single byte. + if _, err = io.ReadFull(r, flag[:]); err != nil { + return err + } + + // At the moment, the flag MUST be 0x01. In the future other + // flag types may be supported. + if flag[0] != 0x01 { + str := fmt.Sprintf("witness tx but flag byte is %x", flag) + return messageError("MsgTx.BtcDecode", str) + } + + // With the Segregated Witness specific fields decoded, we can + // now read in the actual txin count. + count, err = ReadVarInt(r, pver) + if err != nil { + return err + } + } + // Prevent more input transactions than could possibly fit into a // message. It would be possible to cause memory exhaustion and panics // without a sane upper bound on this count. @@ -363,10 +446,19 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error // returns them. returnScriptBuffers := func() { for _, txIn := range msg.TxIn { - if txIn == nil || txIn.SignatureScript == nil { + if txIn == nil { continue } - scriptPool.Return(txIn.SignatureScript) + + if txIn.SignatureScript != nil { + scriptPool.Return(txIn.SignatureScript) + } + + for _, witnessElem := range txIn.Witness { + if witnessElem != nil { + scriptPool.Return(witnessElem) + } + } } for _, txOut := range msg.TxOut { if txOut == nil || txOut.PkScript == nil { @@ -426,6 +518,45 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error totalScriptSize += uint64(len(to.PkScript)) } + // If the transaction's flag byte isn't 0x00 at this point, then one or + // more of its inputs has accompanying witness data. + if flag[0] != 0 && enc == WitnessEncoding { + for _, txin := range msg.TxIn { + // For each input, the witness is encoded as a stack + // with one or more items. Therefore, we first read a + // varint which encodes the number of stack items. + witCount, err := ReadVarInt(r, pver) + if err != nil { + returnScriptBuffers() + return err + } + + // Prevent a possible memory exhaustion attack by + // limiting the witCount value to a sane upper bound. + if witCount > maxWitnessItemsPerInput { + returnScriptBuffers() + str := fmt.Sprintf("too many witness items to fit "+ + "into max message size [count %d, max %d]", + witCount, maxWitnessItemsPerInput) + return messageError("MsgTx.BtcDecode", str) + } + + // Then for witCount number of stack items, each item + // has a varint length prefix, followed by the witness + // item itself. + txin.Witness = make([][]byte, witCount) + for j := uint64(0); j < witCount; j++ { + txin.Witness[j], err = readScript(r, pver, + maxWitnessItemSize, "script witness item") + if err != nil { + returnScriptBuffers() + return err + } + totalScriptSize += uint64(len(txin.Witness[j])) + } + } + } + msg.LockTime, err = binarySerializer.Uint32(r, littleEndian) if err != nil { returnScriptBuffers() @@ -463,6 +594,25 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error // Return the temporary script buffer to the pool. scriptPool.Return(signatureScript) + + for j := 0; j < len(msg.TxIn[i].Witness); j++ { + // Copy each item within the witness stack for this + // input into the contiguous buffer at the appropriate + // offset. + witnessElem := msg.TxIn[i].Witness[j] + copy(scripts[offset:], witnessElem) + + // Reset the witness item within the stack to the slice + // of the contiguous buffer where the witness lives. + witnessElemSize := uint64(len(witnessElem)) + end := offset + witnessElemSize + msg.TxIn[i].Witness[j] = scripts[offset:end:end] + offset += witnessElemSize + + // Return the temporary buffer used for the witness stack + // item to the pool. + scriptPool.Return(witnessElem) + } } for i := 0; i < len(msg.TxOut); i++ { // Copy the public key script into the contiguous buffer at the @@ -519,6 +669,24 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error return err } + // If the encoding version is set to WitnessEncoding, and the Flags + // field for the MsgTx aren't 0x00, then this indicates the transaction + // is to be encoded using the new witness inclusionary structure + // defined in BIP0144. + doWitness := enc == WitnessEncoding && msg.HasWitness() + if doWitness { + // After the txn's Version field, we include two additional + // bytes specific to the witness encoding. The first byte is an + // always 0x00 marker byte, which allows decoders to + // distinguish a serialized transaction with witnesses from a + // regular (legacy) one. The second byte is the Flag field, + // which at the moment is always 0x01, but may be extended in + // the future to accommodate auxiliary non-committed fields. + if _, err := w.Write(witessMarkerBytes); err != nil { + return err + } + } + count := uint64(len(msg.TxIn)) err = WriteVarInt(w, pver, count) if err != nil { @@ -545,9 +713,33 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error } } + // If this transaction is a witness transaction, and the witness + // encoded is desired, then encode the witness for each of the inputs + // within the transaction. + if doWitness { + for _, ti := range msg.TxIn { + err = writeTxWitness(w, pver, msg.Version, ti.Witness) + if err != nil { + return err + } + } + } + return binarySerializer.PutUint32(w, littleEndian, msg.LockTime) } +// HasWitness returns false if none of the inputs within the transaction +// contain witness data, true false otherwise. +func (msg *MsgTx) HasWitness() bool { + for _, txIn := range msg.TxIn { + if len(txIn.Witness) != 0 { + return true + } + } + + return false +} + // Serialize encodes the transaction to w using a format that suitable for // long-term storage such as a database while respecting the Version field in // the transaction. This function differs from BtcEncode in that BtcEncode @@ -570,16 +762,16 @@ func (msg *MsgTx) Serialize(w io.Writer) error { return msg.BtcEncode(w, 0, WitnessEncoding) } -// SerializeWitness encodes the transaction to w in an identical manner to +// SerializeNoWitness encodes the transaction to w in an identical manner to // Serialize, however even if the source transaction has inputs with witness // data, the old serialization format will still be used. func (msg *MsgTx) SerializeNoWitness(w io.Writer) error { return msg.BtcEncode(w, 0, BaseEncoding) } -// SerializeSize returns the number of bytes it would take to serialize the -// the transaction. -func (msg *MsgTx) SerializeSize() int { +// baseSize returns the serialized size of the transaction without accounting +// for any witness data. +func (msg *MsgTx) baseSize() int { // Version 4 bytes + LockTime 4 bytes + Serialized varint size for the // number of transaction inputs and outputs. n := 8 + VarIntSerializeSize(uint64(len(msg.TxIn))) + @@ -596,6 +788,31 @@ func (msg *MsgTx) SerializeSize() int { return n } +// SerializeSize returns the number of bytes it would take to serialize the +// the transaction. +func (msg *MsgTx) SerializeSize() int { + n := msg.baseSize() + + if msg.HasWitness() { + // The marker, and flag fields take up two additional bytes. + n += 2 + + // Additionally, factor in the serialized size of each of the + // witnesses for each txin. + for _, txin := range msg.TxIn { + n += txin.Witness.SerializeSize() + } + } + + return n +} + +// SerializeSizeStripped returns the number of bytes it would take to serialize +// the transaction, excluding any included witness data. +func (msg *MsgTx) SerializeSizeStripped() int { + return msg.baseSize() +} + // Command returns the protocol command string for the message. This is part // of the Message interface implementation. func (msg *MsgTx) Command() string { @@ -626,6 +843,13 @@ func (msg *MsgTx) PkScriptLocs() []int { // input. n := 4 + VarIntSerializeSize(uint64(len(msg.TxIn))) + VarIntSerializeSize(uint64(numTxOut)) + + // If this transaction has a witness input, the an additional two bytes + // for the marker, and flag byte need to be taken into account. + if len(msg.TxIn) > 0 && msg.TxIn[0].Witness != nil { + n += 2 + } + for _, txIn := range msg.TxIn { n += txIn.SerializeSize() } @@ -767,3 +991,19 @@ func writeTxOut(w io.Writer, pver uint32, version int32, to *TxOut) error { return WriteVarBytes(w, pver, to.PkScript) } + +// writeTxWitness encodes the bitcoin protocol encoding for a transaction +// input's witness into to w. +func writeTxWitness(w io.Writer, pver uint32, version int32, wit [][]byte) error { + err := WriteVarInt(w, pver, uint64(len(wit))) + if err != nil { + return err + } + for _, item := range wit { + err = WriteVarBytes(w, pver, item) + if err != nil { + return err + } + } + return nil +} diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index ae669008..dd809f81 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -35,8 +35,7 @@ func TestTx(t *testing.T) { } // Ensure max payload is expected value for latest protocol version. - // Num addresses (varInt) + max allowed addresses. - wantPayload := uint32(1000 * 1000) + wantPayload := uint32(1000 * 4000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ @@ -65,7 +64,11 @@ func TestTx(t *testing.T) { // Ensure we get the same transaction input back out. sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62} - txIn := NewTxIn(prevOut, sigScript) + witnessData := [][]byte{ + {0x04, 0x31}, + {0x01, 0x43}, + } + txIn := NewTxIn(prevOut, sigScript, witnessData) if !reflect.DeepEqual(&txIn.PreviousOutPoint, prevOut) { t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v", spew.Sprint(&txIn.PreviousOutPoint), @@ -76,6 +79,11 @@ func TestTx(t *testing.T) { spew.Sdump(txIn.SignatureScript), spew.Sdump(sigScript)) } + if !reflect.DeepEqual(txIn.Witness, TxWitness(witnessData)) { + t.Errorf("NewTxIn: wrong witness data - got %v, want %v", + spew.Sdump(txIn.Witness), + spew.Sdump(witnessData)) + } // Ensure we get the same transaction output back out. txValue := int64(5000000000) @@ -203,7 +211,7 @@ func TestWTxSha(t *testing.T) { Index: 19, }, Witness: [][]byte{ - []byte{ // 70-byte signature + { // 70-byte signature 0x30, 0x43, 0x02, 0x1f, 0x4d, 0x23, 0x81, 0xdc, 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, @@ -214,7 +222,7 @@ func TestWTxSha(t *testing.T) { 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, 0x56, 0x9a, 0x18, 0x19, 0x70, 0x01, }, - []byte{ // 33-byte serialize pub key + { // 33-byte serialize pub key 0x03, 0x07, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, 0x63, 0x46, 0xdf, 0x69, 0x77, 0x00, 0x0c, 0x89, 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, @@ -493,6 +501,14 @@ func TestTxSerialize(t *testing.T) { multiTxPkScriptLocs, false, }, + // Multiple outputs witness transaction. + { + multiWitnessTx, + multiWitnessTx, + multiWitnessTxEncoded, + multiWitnessTxPkScriptLocs, + true, + }, } t.Logf("Running %d tests", len(tests)) @@ -513,7 +529,11 @@ func TestTxSerialize(t *testing.T) { // Deserialize the transaction. var tx MsgTx rbuf := bytes.NewReader(test.buf) - err = tx.Deserialize(rbuf) + if test.witness { + err = tx.Deserialize(rbuf) + } else { + err = tx.DeserializeNoWitness(rbuf) + } if err != nil { t.Errorf("Deserialize #%d error %v", i, err) continue @@ -701,9 +721,9 @@ func TestTxOverflowErrors(t *testing.T) { } } -// TestTxSerializeSize performs tests to ensure the serialize size for various -// transactions is accurate. -func TestTxSerializeSize(t *testing.T) { +// TestTxSerializeSizeStripped performs tests to ensure the serialize size for +// various transactions is accurate. +func TestTxSerializeSizeStripped(t *testing.T) { // Empty tx message. noTx := NewMsgTx(1) noTx.Version = 1 @@ -717,6 +737,34 @@ func TestTxSerializeSize(t *testing.T) { // Transcaction with an input and an output. {multiTx, 210}, + + // Transaction with an input which includes witness data, and + // one output. Note that this uses SerializeSizeStripped which + // excludes the additional bytes due to witness data encoding. + {multiWitnessTx, 82}, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + serializedSize := test.in.SerializeSizeStripped() + if serializedSize != test.size { + t.Errorf("MsgTx.SerializeSizeStripped: #%d got: %d, want: %d", i, + serializedSize, test.size) + continue + } + } +} + +// TestTxWitnessSize performs tests to ensure that the serialized size for +// various types of transactions that include witness data is accurate. +func TestTxWitnessSize(t *testing.T) { + tests := []struct { + in *MsgTx // Tx to encode + size int // Expected serialized size w/ witnesses + }{ + // Transaction with an input which includes witness data, and + // one output. + {multiWitnessTx, 190}, } t.Logf("Running %d tests", len(tests)) @@ -828,3 +876,146 @@ var multiTxEncoded = []byte{ // multiTxPkScriptLocs is the location information for the public key scripts // located in multiTx. var multiTxPkScriptLocs = []int{63, 139} + +// multiWitnessTx is a MsgTx with an input with witness data, and an +// output used in various tests. +var multiWitnessTx = &MsgTx{ + Version: 1, + TxIn: []*TxIn{ + { + PreviousOutPoint: OutPoint{ + Hash: chainhash.Hash{ + 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, + 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, + 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, + 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, + }, + Index: 19, + }, + SignatureScript: []byte{}, + Witness: [][]byte{ + { // 70-byte signature + 0x30, 0x43, 0x02, 0x1f, 0x4d, 0x23, 0x81, 0xdc, + 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, + 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, + 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, + 0x58, 0xda, 0x19, 0x02, 0x20, 0x60, 0x8b, 0x5c, + 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, + 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, + 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, + 0x56, 0x9a, 0x18, 0x19, 0x70, 0x01, + }, + { // 33-byte serialize pub key + 0x03, 0x07, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, + 0x63, 0x46, 0xdf, 0x69, 0x77, 0x00, 0x0c, 0x89, + 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, + 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x06, 0x6a, + 0x8f, + }, + }, + Sequence: 0xffffffff, + }, + }, + TxOut: []*TxOut{ + { + Value: 395019, + PkScript: []byte{ // p2wkh output + 0x00, // Version 0 witness program + 0x14, // OP_DATA_20 + 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, + 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, + 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash + }, + }, + }, +} + +// multiWitnessTxEncoded is the wire encoded bytes for multiWitnessTx including inputs +// with witness data using protocol version 70012 and is used in the various +// tests. +var multiWitnessTxEncoded = []byte{ + 0x1, 0x0, 0x0, 0x0, // Version + 0x0, // Marker byte indicating 0 inputs, or a segwit encoded tx + 0x1, // Flag byte + 0x1, // Varint for number of inputs + 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, + 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, + 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, + 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, // Previous output hash + 0x13, 0x0, 0x0, 0x0, // Little endian previous output index + 0x0, // No sig script (this is a witness input) + 0xff, 0xff, 0xff, 0xff, // Sequence + 0x1, // Varint for number of outputs + 0xb, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, // Output amount + 0x16, // Varint for length of pk script + 0x0, // Version 0 witness program + 0x14, // OP_DATA_20 + 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, + 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, + 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash + 0x2, // Two items on the witness stack + 0x46, // 70 byte stack item + 0x30, 0x43, 0x2, 0x1f, 0x4d, 0x23, 0x81, 0xdc, + 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, + 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, + 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, + 0x58, 0xda, 0x19, 0x2, 0x20, 0x60, 0x8b, 0x5c, + 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, + 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, + 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, + 0x56, 0x9a, 0x18, 0x19, 0x70, 0x1, + 0x21, // 33 byte stack item + 0x3, 0x7, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, + 0x63, 0x46, 0xdf, 0x69, 0x77, 0x0, 0xc, 0x89, + 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, + 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x6, 0x6a, + 0x8f, + 0x0, 0x0, 0x0, 0x0, // Lock time +} + +// multiWitnessTxEncodedNonZeroFlag is an incorrect wire encoded bytes for +// multiWitnessTx including inputs with witness data. Instead of the flag byte +// being set to 0x01, the flag is 0x00, which should trigger a decoding error. +var multiWitnessTxEncodedNonZeroFlag = []byte{ + 0x1, 0x0, 0x0, 0x0, // Version + 0x0, // Marker byte indicating 0 inputs, or a segwit encoded tx + 0x0, // Incorrect flag byte (should be 0x01) + 0x1, // Varint for number of inputs + 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, + 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, + 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, + 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, // Previous output hash + 0x13, 0x0, 0x0, 0x0, // Little endian previous output index + 0x0, // No sig script (this is a witness input) + 0xff, 0xff, 0xff, 0xff, // Sequence + 0x1, // Varint for number of outputs + 0xb, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, // Output amount + 0x16, // Varint for length of pk script + 0x0, // Version 0 witness program + 0x14, // OP_DATA_20 + 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, + 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, + 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash + 0x2, // Two items on the witness stack + 0x46, // 70 byte stack item + 0x30, 0x43, 0x2, 0x1f, 0x4d, 0x23, 0x81, 0xdc, + 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, + 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, + 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, + 0x58, 0xda, 0x19, 0x2, 0x20, 0x60, 0x8b, 0x5c, + 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, + 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, + 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, + 0x56, 0x9a, 0x18, 0x19, 0x70, 0x1, + 0x21, // 33 byte stack item + 0x3, 0x7, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, + 0x63, 0x46, 0xdf, 0x69, 0x77, 0x0, 0xc, 0x89, + 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, + 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x6, 0x6a, + 0x8f, + 0x0, 0x0, 0x0, 0x0, // Lock time +} + +// multiTxPkScriptLocs is the location information for the public key scripts +// located in multiWitnessTx. +var multiWitnessTxPkScriptLocs = []int{58}