From b3ce2ad2ad2ae26e406354cc10dfa533def1d282 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Apr 2018 07:09:07 -0500 Subject: [PATCH] wire: Remove TxSerializeWitnessSigning. This removes the TxSerializeWitnessSigning serialization type since it is no longer required due to implementing it directly in the signature hash calculation function. It also removes all related tests. Although this is technically a change to the wire protocol, the protocol version is not being bumped because nothing ever sends messages using this serialization type as it only applied for calculating signature hashes and really should not have ever been in the wire package to begin with. --- wire/msgtx.go | 117 --------------------------------------------- wire/msgtx_test.go | 114 ------------------------------------------- 2 files changed, 231 deletions(-) diff --git a/wire/msgtx.go b/wire/msgtx.go index 797f9a6a20..8d477d4fa0 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -148,10 +148,6 @@ const ( // TxSerializeOnlyWitness indicates a transaction be serialized with // only the witness data. TxSerializeOnlyWitness - - // TxSerializeWitnessSigning indicates a transaction be serialized with - // only the witness scripts. - TxSerializeWitnessSigning ) // scriptFreeList defines a free list of byte slices (up to the maximum number @@ -306,15 +302,6 @@ func (t *TxIn) SerializeSizeWitness() int { len(t.SignatureScript) } -// SerializeSizeWitnessSigning returns the number of bytes it would take to -// serialize the transaction input for a witness used in signing. -func (t *TxIn) SerializeSizeWitnessSigning() int { - // Serialized varint size for the length of SignatureScript + - // SignatureScript bytes. - return VarIntSerializeSize(uint64(len(t.SignatureScript))) + - len(t.SignatureScript) -} - // NewTxIn returns a new Decred transaction input with the provided // previous outpoint point and signature script with a default sequence of // MaxTxInSequenceNum. @@ -443,13 +430,6 @@ func (msg *MsgTx) TxHashWitness() chainhash.Hash { return chainhash.HashH(msg.mustSerialize(TxSerializeOnlyWitness)) } -// TxHashWitnessSigning generates the hash for the transaction witness with the -// malleable portions (AmountIn, BlockHeight, BlockIndex) removed. These are -// verified and set by the miner instead. -func (msg *MsgTx) TxHashWitnessSigning() chainhash.Hash { - return chainhash.HashH(msg.mustSerialize(TxSerializeWitnessSigning)) -} - // TxHashFull generates the hash for the transaction prefix || witness. It first // obtains the hashes for both the transaction prefix and witness, then // concatenates them and hashes the result. @@ -606,8 +586,6 @@ func writeTxScriptsToMsgTx(msg *MsgTx, totalScriptSize uint64, serType TxSeriali writeTxOuts() case TxSerializeOnlyWitness: fallthrough - case TxSerializeWitnessSigning: - writeTxIns() case TxSerializeFull: writeTxIns() writeTxOuts() @@ -775,44 +753,6 @@ func (msg *MsgTx) decodeWitness(r io.Reader, pver uint32, isFull bool) (uint64, return totalScriptSize, nil } -// decodeWitnessSigning decodes a witness for signing. -func (msg *MsgTx) decodeWitnessSigning(r io.Reader, pver uint32) (uint64, error) { - // Witness only for signing; generate the TxIn list and fill out only the - // sigScripts. - count, err := ReadVarInt(r, pver) - if err != nil { - return 0, 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. - if count > uint64(maxTxInPerMessage) { - str := fmt.Sprintf("too many input transactions to fit into "+ - "max message size [count %d, max %d]", count, - maxTxInPerMessage) - return 0, messageError("MsgTx.decodeWitness", str) - } - - var totalScriptSize uint64 - txIns := make([]TxIn, count) - msg.TxIn = make([]*TxIn, count) - for i := uint64(0); i < count; i++ { - // The pointer is set now in case a script buffer is borrowed - // and needs to be returned to the pool on error. - ti := &txIns[i] - msg.TxIn[i] = ti - err = readTxInWitnessSigning(r, pver, msg.Version, ti) - if err != nil { - return 0, err - } - totalScriptSize += uint64(len(ti.SignatureScript)) - } - msg.TxOut = make([]*TxOut, 0) - - return totalScriptSize, nil -} - // BtcDecode decodes r using the Decred protocol encoding into the receiver. // This is part of the Message interface implementation. // See Deserialize for decoding transactions stored to disk, such as in a @@ -871,14 +811,6 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error { } writeTxScriptsToMsgTx(msg, totalScriptSize, txSerType) - case TxSerializeWitnessSigning: - totalScriptSize, err := msg.decodeWitnessSigning(r, pver) - if err != nil { - returnScriptBuffers() - return err - } - writeTxScriptsToMsgTx(msg, totalScriptSize, txSerType) - case TxSerializeFull: totalScriptSizeIns, err := msg.decodePrefix(r, pver) if err != nil { @@ -977,24 +909,6 @@ func (msg *MsgTx) encodeWitness(w io.Writer, pver uint32) error { return nil } -// encodeWitnessSigning encodes a transaction witness into a writer for signing. -func (msg *MsgTx) encodeWitnessSigning(w io.Writer, pver uint32) error { - count := uint64(len(msg.TxIn)) - err := WriteVarInt(w, pver, count) - if err != nil { - return err - } - - for _, ti := range msg.TxIn { - err = writeTxInWitnessSigning(w, pver, msg.Version, ti) - if err != nil { - return err - } - } - - return nil -} - // BtcEncode encodes the receiver to w using the Decred protocol encoding. // This is part of the Message interface implementation. // See Serialize for encoding transactions to be stored to disk, such as in a @@ -1022,12 +936,6 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32) error { return err } - case TxSerializeWitnessSigning: - err := msg.encodeWitnessSigning(w, pver) - if err != nil { - return err - } - case TxSerializeFull: err := msg.encodePrefix(w, pver) if err != nil { @@ -1111,15 +1019,6 @@ func (msg *MsgTx) SerializeSize() int { n += txIn.SerializeSizeWitness() } - case TxSerializeWitnessSigning: - // Version 4 bytes + Serialized varint size for the - // number of transaction signatures. - n = 4 + VarIntSerializeSize(uint64(len(msg.TxIn))) - - for _, txIn := range msg.TxIn { - n += txIn.SerializeSizeWitnessSigning() - } - case TxSerializeFull: // Version 4 bytes + LockTime 4 bytes + Expiry 4 bytes + Serialized // varint size for the number of transaction inputs (x2) and @@ -1298,15 +1197,6 @@ func readTxInWitness(r io.Reader, pver uint32, version uint16, ti *TxIn) error { return err } -// readTxInWitnessSigning reads a TxIn witness for signing. -func readTxInWitnessSigning(r io.Reader, pver uint32, version uint16, ti *TxIn) error { - // Signature script. - var err error - ti.SignatureScript, err = readScript(r, pver, MaxMessagePayload, - "transaction input signature script") - return err -} - // writeTxInPrefixs encodes ti to the Decred protocol encoding for a transaction // input (TxIn) prefix to w. func writeTxInPrefix(w io.Writer, pver uint32, version uint16, ti *TxIn) error { @@ -1343,13 +1233,6 @@ func writeTxInWitness(w io.Writer, pver uint32, version uint16, ti *TxIn) error return WriteVarBytes(w, pver, ti.SignatureScript) } -// writeTxInWitnessSigning encodes ti to the Decred protocol encoding for a -// transaction input (TxIn) witness to w for signing. -func writeTxInWitnessSigning(w io.Writer, pver uint32, version uint16, ti *TxIn) error { - // Only write the signature script. - return WriteVarBytes(w, pver, ti.SignatureScript) -} - // readTxOut reads the next sequence of bytes from r as a transaction output // (TxOut). func readTxOut(r io.Reader, pver uint32, version uint16, to *TxOut) error { diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index 1fb06b5c95..194fc5dab8 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -616,97 +616,6 @@ func TestTxSerializeWitness(t *testing.T) { } } -// TestTxSerializeWitnessSigning tests MsgTx serialize and deserialize. -func TestTxSerializeWitnessSigning(t *testing.T) { - noTx := NewMsgTx() - noTx.SerType = TxSerializeWitnessSigning - noTx.Version = 1 - noTxEncoded := []byte{ - 0x01, 0x00, 0x03, 0x00, // Version - 0x00, // Varint for number of input signatures - } - - tests := []struct { - in *MsgTx // Message to encode - out *MsgTx // Expected decoded message - buf []byte // Serialized data - pkScriptLocs []int // Expected output script locations - }{ - // No transactions. - { - noTx, - noTx, - noTxEncoded, - nil, - }, - - // Multiple transactions. - { - multiTxWitnessSigning, - multiTxWitnessSigning, - multiTxWitnessSigningEncoded, - nil, - }, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - // Serialize the transaction. - buf := bytes.NewBuffer(make([]byte, 0, test.in.SerializeSize())) - err := test.in.Serialize(buf) - if err != nil { - t.Errorf("Serialize #%d error %v", i, err) - continue - } - if !bytes.Equal(buf.Bytes(), test.buf) { - t.Errorf("Serialize #%d\n got: %s want: %s", i, - spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) - continue - } - - // Test SerializeSize. - sz := test.in.SerializeSize() - actualSz := len(buf.Bytes()) - if sz != actualSz { - t.Errorf("Wrong serialize size #%d\n got: %d want: %d", i, - sz, actualSz) - } - - // Deserialize the transaction. - var tx MsgTx - rbuf := bytes.NewReader(test.buf) - err = tx.Deserialize(rbuf) - if err != nil { - t.Errorf("Deserialize #%d error %v", i, err) - continue - } - if !reflect.DeepEqual(&tx, test.out) { - t.Errorf("Deserialize #%d\n got: %s want: %s", i, - spew.Sdump(&tx), spew.Sdump(test.out)) - continue - } - - // Ensure the public key script locations are accurate. - pkScriptLocs := test.in.PkScriptLocs() - if !reflect.DeepEqual(pkScriptLocs, test.pkScriptLocs) { - t.Errorf("PkScriptLocs #%d\n got: %s want: %s", i, - spew.Sdump(pkScriptLocs), - spew.Sdump(test.pkScriptLocs)) - continue - } - for j, loc := range pkScriptLocs { - wantPkScript := test.in.TxOut[j].PkScript - gotPkScript := test.buf[loc : loc+len(wantPkScript)] - if !bytes.Equal(gotPkScript, wantPkScript) { - t.Errorf("PkScriptLocs #%d:%d\n unexpected "+ - "script got: %s want: %s", i, j, - spew.Sdump(gotPkScript), - spew.Sdump(wantPkScript)) - } - } - } -} - // TestTxSerializeErrors performs negative tests against wire encode and decode // of MsgTx to confirm error paths work correctly. func TestTxSerializeErrors(t *testing.T) { @@ -1066,20 +975,6 @@ var multiTxWitness = &MsgTx{ TxOut: []*TxOut{}, } -// multiTxWitnessSigning is a MsgTx witness with only input witness sigscripts. -var multiTxWitnessSigning = &MsgTx{ - SerType: TxSerializeWitnessSigning, - Version: 1, - TxIn: []*TxIn{ - { - SignatureScript: []byte{ - 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, - }, - }, - }, - TxOut: []*TxOut{}, -} - // multiTxEncoded is the wire encoded bytes for multiTx using protocol version // 0 and is used in the various tests. var multiTxEncoded = []byte{ @@ -1188,15 +1083,6 @@ var multiTxWitnessEncoded = []byte{ 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, // Signature script } -// multiTxWitnessSigningEncoded is the wire encoded bytes for multiTx using protocol version -// 1 and is used in the various tests. -var multiTxWitnessSigningEncoded = []byte{ - 0x01, 0x00, 0x03, 0x00, // Version - 0x01, // Varint for number of input signature - 0x07, // Varint for length of signature script - 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, // Signature script -} - // multiTxPkScriptLocs is the location information for the public key scripts // located in multiTx. var multiTxPkScriptLocs = []int{58, 136}