2022 06 30 OP_CODESEPARATOR impl compatible with taproot (#4439)

* Implement OP_CODESEPARATOR index checking

* Remove taproot serialization options

* Refactor name

Co-authored-by: benthecarman <benthecarman@live.com>
This commit is contained in:
Chris Stewart 2022-06-30 13:59:14 -05:00 committed by GitHub
parent 678612161b
commit 38d8f8cdf0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 0 deletions

View file

@ -73,6 +73,7 @@ class ScriptProgramFactoryTest extends BitcoinSUnitTest {
altStack = Nil,
flags = Nil,
lastCodeSeparator = None,
codeSeparatorTapscriptIdx = None,
conditionalCounter = ConditionalCounter.empty
)
inProgress.stack must be(stack)

View file

@ -75,6 +75,7 @@ case class PreExecutionScriptProgram(
altStack = altStack,
flags = flags,
lastCodeSeparator = None,
codeSeparatorTapscriptIdx = None,
conditionalCounter = ConditionalCounter.empty
)
}
@ -221,6 +222,7 @@ case class ExecutionInProgressScriptProgram(
altStack: List[ScriptToken],
flags: Seq[ScriptFlag],
lastCodeSeparator: Option[Int],
codeSeparatorTapscriptIdx: Option[Int],
conditionalCounter: ConditionalCounter)
extends StartedScriptProgram {
@ -239,6 +241,7 @@ case class ExecutionInProgressScriptProgram(
altStack,
flags,
lastCodeSeparator,
codeSeparatorTapscriptIdx,
errorOpt
)
}
@ -335,6 +338,11 @@ case class ExecutionInProgressScriptProgram(
newLastCodeSeparator: Int): ExecutionInProgressScriptProgram = {
this.copy(lastCodeSeparator = Some(newLastCodeSeparator))
}
def updateTapscriptCodeSeparatorIdx(
newIdx: Int): ExecutionInProgressScriptProgram = {
this.copy(codeSeparatorTapscriptIdx = Some(newIdx))
}
}
/** Type for a [[org.bitcoins.core.script.ScriptProgram ScriptProgram]] that has been
@ -352,6 +360,7 @@ case class ExecutedScriptProgram(
altStack: List[ScriptToken],
flags: Seq[ScriptFlag],
lastCodeSeparator: Option[Int],
codeSeparatorTapscriptIdx: Option[Int],
error: Option[ScriptError])
extends StartedScriptProgram {

View file

@ -124,12 +124,21 @@ sealed abstract class CryptoInterpreter {
require(program.script.headOption.contains(OP_CODESEPARATOR),
"Script top must be OP_CODESEPARATOR")
// Filter out the constants for Tapscript OP_CODESEPARATORs
// because we only count op codes
val constants =
program.originalScript.dropRight(program.script.size).count {
case _: ScriptOperation => false
case _: ScriptConstant => true
}
val indexOfOpCodeSeparator =
program.originalScript.size - program.script.size
program
.updateScript(program.script.tail)
.updateLastCodeSeparator(indexOfOpCodeSeparator)
.updateTapscriptCodeSeparatorIdx(indexOfOpCodeSeparator - constants)
}
/** Compares the first signature against each public key until it finds an ECDSA match.

View file

@ -469,6 +469,7 @@ sealed abstract class ScriptInterpreter {
altStack = Nil,
flags = wTxSigComponent.flags,
lastCodeSeparator = None,
codeSeparatorTapscriptIdx = None,
error = Some(err)
)
Success(program)
@ -1203,6 +1204,7 @@ sealed abstract class ScriptInterpreter {
altStack = Nil,
flags = flags,
lastCodeSeparator = None,
codeSeparatorTapscriptIdx = None,
error = Some(ScriptErrorDiscourageUpgradeableWitnessProgram)
)
Success(executed)