Refactoring WitnessTransactionSignatureComponentV0 to remove explicit paramter of 'ScriptWitness' -- this can be derived from the inputIndex

This commit is contained in:
Chris Stewart 2016-12-07 11:17:44 -06:00
parent ac2c583905
commit 86d8a92657
4 changed files with 38 additions and 32 deletions

View File

@ -3,7 +3,7 @@ package org.bitcoins.core.crypto
import org.bitcoins.core.currency.CurrencyUnit import org.bitcoins.core.currency.CurrencyUnit
import org.bitcoins.core.number.UInt32 import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.script._ import org.bitcoins.core.protocol.script._
import org.bitcoins.core.protocol.transaction.{Transaction, WitnessTransaction} import org.bitcoins.core.protocol.transaction.{Transaction, TransactionOutput, WitnessTransaction}
import org.bitcoins.core.script.flag.ScriptFlag import org.bitcoins.core.script.flag.ScriptFlag
/** /**
@ -46,7 +46,7 @@ sealed trait WitnessV0TransactionSignatureComponent extends TransactionSignature
override def transaction: WitnessTransaction override def transaction: WitnessTransaction
def witness: ScriptWitness def witness: ScriptWitness = transaction.witness.witnesses(inputIndex.toInt).witness
/** The amount of [[CurrencyUnit]] this input is spending */ /** The amount of [[CurrencyUnit]] this input is spending */
def amount: CurrencyUnit def amount: CurrencyUnit
@ -63,14 +63,10 @@ object TransactionSignatureComponent {
private case class BaseTransactionSignatureComponentImpl(transaction : Transaction, inputIndex : UInt32, private case class BaseTransactionSignatureComponentImpl(transaction : Transaction, inputIndex : UInt32,
scriptPubKey : ScriptPubKey, flags : Seq[ScriptFlag]) extends BaseTransactionSignatureComponent scriptPubKey : ScriptPubKey, flags : Seq[ScriptFlag]) extends BaseTransactionSignatureComponent
private case class WitnessV0TransactionSignatureComponentImpl(transaction : WitnessTransaction, inputIndex : UInt32,
scriptPubKey : ScriptPubKey, flags : Seq[ScriptFlag],
witness: ScriptWitness, amount: CurrencyUnit) extends WitnessV0TransactionSignatureComponent
def apply(transaction : WitnessTransaction, inputIndex : UInt32, scriptPubKey : ScriptPubKey, def apply(transaction : WitnessTransaction, inputIndex : UInt32, scriptPubKey : ScriptPubKey,
flags : Seq[ScriptFlag], witness : ScriptWitness, flags : Seq[ScriptFlag], amount: CurrencyUnit) : WitnessV0TransactionSignatureComponent = {
amount: CurrencyUnit) : WitnessV0TransactionSignatureComponent = { WitnessV0TransactionSignatureComponent(transaction,inputIndex,scriptPubKey,flags,amount)
WitnessV0TransactionSignatureComponentImpl(transaction,inputIndex, scriptPubKey, flags, witness, amount)
} }
def apply(transaction : Transaction, inputIndex : UInt32, def apply(transaction : Transaction, inputIndex : UInt32,
@ -78,19 +74,32 @@ object TransactionSignatureComponent {
BaseTransactionSignatureComponentImpl(transaction,inputIndex,scriptPubKey,flags) BaseTransactionSignatureComponentImpl(transaction,inputIndex,scriptPubKey,flags)
} }
/** /** This factory method is used for changing the scriptPubKey inside of a txSignatureComponent */
* This factory method is used for changing the scriptPubKey inside of a txSignatureComponent
*
* @param oldTxSignatureComponent
* @param scriptPubKey
* @return
*/
def apply(oldTxSignatureComponent : TransactionSignatureComponent, scriptPubKey : ScriptPubKey) : TransactionSignatureComponent = oldTxSignatureComponent match { def apply(oldTxSignatureComponent : TransactionSignatureComponent, scriptPubKey : ScriptPubKey) : TransactionSignatureComponent = oldTxSignatureComponent match {
case base: BaseTransactionSignatureComponent => case base: BaseTransactionSignatureComponent =>
TransactionSignatureComponent(base.transaction, TransactionSignatureComponent(base.transaction,
base.inputIndex,scriptPubKey, base.flags) base.inputIndex,scriptPubKey, base.flags)
case w: WitnessV0TransactionSignatureComponent => case w: WitnessV0TransactionSignatureComponent =>
TransactionSignatureComponent(w.transaction,w.inputIndex,w.scriptPubKey,w.flags,w.witness,w.amount) TransactionSignatureComponent(w.transaction,w.inputIndex,scriptPubKey,w.flags,w.amount)
} }
}
object WitnessV0TransactionSignatureComponent {
private case class WitnessV0TransactionSignatureComponentImpl(transaction : WitnessTransaction, inputIndex : UInt32,
scriptPubKey : ScriptPubKey, flags : Seq[ScriptFlag],
amount: CurrencyUnit) extends WitnessV0TransactionSignatureComponent
def apply(transaction : WitnessTransaction, inputIndex : UInt32, scriptPubKey : ScriptPubKey,
flags : Seq[ScriptFlag], amount: CurrencyUnit) : WitnessV0TransactionSignatureComponent = {
WitnessV0TransactionSignatureComponentImpl(transaction,inputIndex, scriptPubKey, flags, amount)
}
/** Note: The output passed here is the output we are spending,
* we use the [[CurrencyUnit]] and [[ScriptPubKey]] in that output for signing */
def apply(transaction : WitnessTransaction, inputIndex : UInt32, output : TransactionOutput,
flags : Seq[ScriptFlag]): WitnessV0TransactionSignatureComponent = {
WitnessV0TransactionSignatureComponent(transaction,inputIndex,output.scriptPubKey,flags,output.value)
}
} }

View File

@ -235,15 +235,14 @@ object ScriptProgram {
* @param scriptPubKey the scriptPubKey for which the input is spending * @param scriptPubKey the scriptPubKey for which the input is spending
* @param inputIndex the input's index inside of transaction which we are spending * @param inputIndex the input's index inside of transaction which we are spending
* @param flags the flags which we are enforcing inside of the script interpreter * @param flags the flags which we are enforcing inside of the script interpreter
* @param witness the witness used to evaluate the input
* @param amount the amount of [[CurrencyUnit]] we are spending in this input * @param amount the amount of [[CurrencyUnit]] we are spending in this input
* @return the script program representing all of this information * @return the script program representing all of this information
*/ */
def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32,
flags : Seq[ScriptFlag], witness: ScriptWitness, flags : Seq[ScriptFlag],
amount: CurrencyUnit) : PreExecutionScriptProgram = { amount: CurrencyUnit) : PreExecutionScriptProgram = {
val script = transaction.inputs(inputIndex.toInt).scriptSignature.asm val script = transaction.inputs(inputIndex.toInt).scriptSignature.asm
ScriptProgram(transaction,scriptPubKey,inputIndex,script.toList,flags, witness, amount) ScriptProgram(transaction,scriptPubKey,inputIndex,script.toList,flags, amount)
} }
def apply(transaction: Transaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, def apply(transaction: Transaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32,
@ -253,16 +252,15 @@ object ScriptProgram {
} }
def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, script : Seq[ScriptToken], def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, script : Seq[ScriptToken],
flags : Seq[ScriptFlag], witness: ScriptWitness, amount: CurrencyUnit) : PreExecutionScriptProgram = { flags : Seq[ScriptFlag], amount: CurrencyUnit) : PreExecutionScriptProgram = {
val txSignatureComponent = TransactionSignatureComponent(transaction,inputIndex,scriptPubKey,flags, val txSignatureComponent = TransactionSignatureComponent(transaction,inputIndex,scriptPubKey,flags, amount)
witness, amount)
PreExecutionScriptProgramImpl(txSignatureComponent,Nil,script.toList,script.toList,Nil,flags) PreExecutionScriptProgramImpl(txSignatureComponent,Nil,script.toList,script.toList,Nil,flags)
} }
def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, stack : Seq[ScriptToken], def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, stack : Seq[ScriptToken],
script : Seq[ScriptToken], flags : Seq[ScriptFlag], witness: ScriptWitness, script : Seq[ScriptToken], flags : Seq[ScriptFlag], witness: ScriptWitness,
amount: CurrencyUnit) : ScriptProgram = { amount: CurrencyUnit) : ScriptProgram = {
val program = ScriptProgram(transaction,scriptPubKey,inputIndex,flags,witness, amount) val program = ScriptProgram(transaction,scriptPubKey,inputIndex,flags, amount)
ScriptProgram(program,stack,script) ScriptProgram(program,stack,script)
} }
@ -283,7 +281,7 @@ object ScriptProgram {
ExecutionInProgressScriptProgramImpl(b,stack.toList, ExecutionInProgressScriptProgramImpl(b,stack.toList,
script.toList,originalScript.toList,Nil,b.flags,None) script.toList,originalScript.toList,Nil,b.flags,None)
case w: WitnessV0TransactionSignatureComponent => case w: WitnessV0TransactionSignatureComponent =>
ScriptProgram(w,stack,script,originalScript,Nil,w.flags,w.witness,w.amount) ScriptProgram(w,stack,script,originalScript,Nil,w.flags,w.amount)
} }
@ -293,25 +291,24 @@ object ScriptProgram {
b.inputIndex, b.flags) b.inputIndex, b.flags)
case w : WitnessV0TransactionSignatureComponent => case w : WitnessV0TransactionSignatureComponent =>
ScriptProgram(w.transaction, w.scriptPubKey, ScriptProgram(w.transaction, w.scriptPubKey,
w.inputIndex, w.flags, w.witness, w.amount) w.inputIndex, w.flags, w.amount)
} }
/** Creates a fresh [[PreExecutionScriptProgram]] */ /** Creates a fresh [[PreExecutionScriptProgram]] */
def apply(transaction: WitnessTransaction, scriptPubKey: ScriptPubKey, inputIndex: UInt32, stack: Seq[ScriptToken], def apply(transaction: WitnessTransaction, scriptPubKey: ScriptPubKey, inputIndex: UInt32, stack: Seq[ScriptToken],
script: Seq[ScriptToken], originalScript: Seq[ScriptToken], altStack: Seq[ScriptToken], script: Seq[ScriptToken], originalScript: Seq[ScriptToken], altStack: Seq[ScriptToken],
flags: Seq[ScriptFlag], witness: ScriptWitness, sigVersion: SignatureVersion, flags: Seq[ScriptFlag], sigVersion: SignatureVersion,
amount: CurrencyUnit): PreExecutionScriptProgram = { amount: CurrencyUnit): PreExecutionScriptProgram = {
val t = TransactionSignatureComponent(transaction,inputIndex, val t = TransactionSignatureComponent(transaction,inputIndex,
scriptPubKey,flags, witness, amount) scriptPubKey,flags, amount)
PreExecutionScriptProgramImpl(t,stack.toList,script.toList,originalScript.toList,altStack.toList,flags) PreExecutionScriptProgramImpl(t,stack.toList,script.toList,originalScript.toList,altStack.toList,flags)
} }
/** Creates a fresh instance of [[PreExecutionScriptProgram]] */ /** Creates a fresh instance of [[PreExecutionScriptProgram]] */
def apply(txSigComponent: WitnessV0TransactionSignatureComponent, stack: Seq[ScriptToken], script: Seq[ScriptToken], def apply(txSigComponent: WitnessV0TransactionSignatureComponent, stack: Seq[ScriptToken], script: Seq[ScriptToken],
originalScript: Seq[ScriptToken], altStack: Seq[ScriptToken], flags: Seq[ScriptFlag], originalScript: Seq[ScriptToken], altStack: Seq[ScriptToken], flags: Seq[ScriptFlag], amount: CurrencyUnit): PreExecutionScriptProgram = {
witness: ScriptWitness, amount: CurrencyUnit): PreExecutionScriptProgram = {
ScriptProgram(txSigComponent.transaction, txSigComponent.scriptPubKey, txSigComponent.inputIndex, stack, ScriptProgram(txSigComponent.transaction, txSigComponent.scriptPubKey, txSigComponent.inputIndex, stack,
script,originalScript, altStack,flags, witness, txSigComponent.sigVersion, amount) script,originalScript, altStack,flags, txSigComponent.sigVersion, amount)
} }

View File

@ -205,7 +205,7 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
case Left((stack,scriptPubKey)) => case Left((stack,scriptPubKey)) =>
val w = witnessTxSigComponent val w = witnessTxSigComponent
val newProgram = ScriptProgram(w.transaction,scriptPubKey,w.inputIndex,stack,scriptPubKey.asm, scriptPubKey.asm,Nil, val newProgram = ScriptProgram(w.transaction,scriptPubKey,w.inputIndex,stack,scriptPubKey.asm, scriptPubKey.asm,Nil,
w.flags,w.witness,w.sigVersion,w.amount) w.flags,w.sigVersion,w.amount)
val evaluated = loop(newProgram,0) val evaluated = loop(newProgram,0)
logger.info("Stack after evaluating witness: " + evaluated.stack) logger.info("Stack after evaluating witness: " + evaluated.stack)
if (evaluated.error.isDefined) evaluated if (evaluated.error.isDefined) evaluated

View File

@ -55,7 +55,7 @@ class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterp
logger.info("Witness after parsing: " + witness) logger.info("Witness after parsing: " + witness)
val program = witness match { val program = witness match {
case Some((w, amount)) => ScriptProgram(tx.asInstanceOf[WitnessTransaction], scriptPubKey, case Some((w, amount)) => ScriptProgram(tx.asInstanceOf[WitnessTransaction], scriptPubKey,
inputIndex, flags, w, amount) inputIndex, flags, amount)
case None => ScriptProgram(tx, scriptPubKey, inputIndex, flags) case None => ScriptProgram(tx, scriptPubKey, inputIndex, flags)
} }
withClue(testCase.raw) { withClue(testCase.raw) {