From ba97b5ee3422df331def82670680febd961704b5 Mon Sep 17 00:00:00 2001
From: Daniel Cousens <github@dcousens.com>
Date: Fri, 12 Dec 2014 14:48:31 +1100
Subject: [PATCH] TxBuilder: re-order to avoid mutation in case of failure

---
 src/transaction_builder.js  | 19 +++++++++++--------
 test/transaction_builder.js | 23 +++++++++++++++++++++++
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/transaction_builder.js b/src/transaction_builder.js
index 2f110fc..3581726 100644
--- a/src/transaction_builder.js
+++ b/src/transaction_builder.js
@@ -253,25 +253,28 @@ TransactionBuilder.prototype.sign = function(index, privKey, redeemScript, hashT
     hash = this.tx.hashForSignature(index, prevOutScript, hashType)
   }
 
-  this.prevOutScripts[index] = prevOutScript
-  this.prevOutTypes[index] = prevOutType
-
-  if (!(index in this.signatures)) {
-    this.signatures[index] = {
+  var input = this.signatures[index]
+  if (!input) {
+    input = {
       hashType: hashType,
       pubKeys: [],
       redeemScript: redeemScript,
       scriptType: scriptType,
       signatures: []
     }
+
+    this.signatures[index] = input
+
   } else {
     assert.equal(scriptType, 'multisig', scriptType + ' doesn\'t support multiple signatures')
+    assert.equal(input.hashType, hashType, 'Inconsistent hashType')
+    assert.deepEqual(input.redeemScript, redeemScript, 'Inconsistent redeemScript')
   }
 
-  var input = this.signatures[index]
-  assert.equal(input.hashType, hashType, 'Inconsistent hashType')
-  assert.deepEqual(input.redeemScript, redeemScript, 'Inconsistent redeemScript')
+  this.prevOutScripts[index] = prevOutScript
+  this.prevOutTypes[index] = prevOutType
 
+  // TODO: order signatures for multisig, enforce m < n
   var signature = privKey.sign(hash)
   input.pubKeys.push(privKey.pub)
   input.signatures.push(signature)
diff --git a/test/transaction_builder.js b/test/transaction_builder.js
index 8e2b528..cde634b 100644
--- a/test/transaction_builder.js
+++ b/test/transaction_builder.js
@@ -153,6 +153,29 @@ describe('TransactionBuilder', function() {
         }, /RedeemScript can\'t be P2SH/)
       })
 
+      it('throws if hashType is inconsistent', function() {
+        var redeemScript = scripts.multisigOutput(1, [privKey.pub])
+
+        txb.addInput(prevTxHash, 0)
+        txb.sign(0, privKey, redeemScript, 83)
+
+        assert.throws(function() {
+          txb.sign(0, privKey, redeemScript, 82)
+        }, /Inconsistent hashType/)
+      })
+
+      it('throws if redeemScript is inconsistent', function() {
+        var firstScript = scripts.multisigOutput(1, [privKey.pub])
+        var otherScript = scripts.multisigOutput(2, [privKey.pub, privKey.pub])
+
+        txb.addInput(prevTxHash, 0)
+        txb.sign(0, privKey, firstScript)
+
+        assert.throws(function() {
+          txb.sign(0, privKey, otherScript)
+        }, /Inconsistent redeemScript/)
+      })
+
       it('throws if redeemScript not supported', function() {
         txb.addInput(prevTxHash, 0)