diff --git a/core-test/src/test/scala/org/bitcoins/core/protocol/script/TaprootWitnessTest.scala b/core-test/src/test/scala/org/bitcoins/core/protocol/script/TaprootWitnessTest.scala index 21d9ac6cad..840e9e6107 100644 --- a/core-test/src/test/scala/org/bitcoins/core/protocol/script/TaprootWitnessTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/protocol/script/TaprootWitnessTest.scala @@ -24,7 +24,7 @@ class TaprootWitnessTest extends BitcoinSUnitTest { "3052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2" + "e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c" - val controlBlock = ControlBlock.fromHex(controlBlockHex) + val controlBlock = TapscriptControlBlock.fromHex(controlBlockHex) val merkleRootHex = "c5c62d7fc595ba5fbe61602eb1a29e2e4763408fe1e2b161beb7cb3c71ebcad9" @@ -138,4 +138,12 @@ class TaprootWitnessTest extends BitcoinSUnitTest { val stack = stackHex.map(ByteVector.fromValidHex(_)) assert(!TaprootKeyPath.isValid(stack)) } + + it must "have a correct constructor" in { + val x = TapscriptControlBlock.apply(controlBlock.bytes.head, + controlBlock.p, + leafHashes = controlBlock.hashes) + assert(x.bytes.toHex == controlBlock.bytes.toHex) + assert(x == controlBlock) + } } diff --git a/core/src/main/scala/org/bitcoins/core/protocol/script/ControlBlock.scala b/core/src/main/scala/org/bitcoins/core/protocol/script/ControlBlock.scala index d089b6a038..d3a2cea9fb 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/script/ControlBlock.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/script/ControlBlock.scala @@ -37,7 +37,7 @@ sealed abstract class ControlBlock extends NetworkElement { case class TapscriptControlBlock(bytes: ByteVector) extends ControlBlock { require(TapscriptControlBlock.isValid(bytes), - s"Invalid leaf version for tapscript control block, got=$bytes") + s"Invalid tapscript control block, got=$bytes") } /** A control block that does not have a leaf version defined as per BIP342 This @@ -86,11 +86,21 @@ object TapscriptControlBlock extends Factory[TapscriptControlBlock] { new TapscriptControlBlock(bytes) } - def apply( + def fromLeaves( + leafVersion: Byte, internalKey: XOnlyPubKey, - leafHashes: Vector[TapLeaf]): ControlBlock = { - val bytes = internalKey.bytes ++ ByteVector.concat(leafHashes.map(_.bytes)) - ControlBlock(bytes) + leafs: Vector[TapLeaf]): TapscriptControlBlock = { + TapscriptControlBlock(leafVersion, internalKey, leafs.map(_.sha256)) + } + + def apply( + leafVersion: Byte, + internalKey: XOnlyPubKey, + leafHashes: Vector[Sha256Digest]): TapscriptControlBlock = { + val bytes = + (leafVersion +: internalKey.bytes) ++ ByteVector + .concat(leafHashes.map(_.bytes)) + TapscriptControlBlock(bytes) } }