mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
core: Fix divergence in behavior between TransactionSignatureSerializer.hashForSignature() methods (#5765)
This commit is contained in:
parent
17f965fd45
commit
c5d57de618
@ -1,15 +1,16 @@
|
|||||||
package org.bitcoins.core.crypto
|
package org.bitcoins.core.crypto
|
||||||
|
|
||||||
import org.bitcoins.core.number.{Int32, UInt32}
|
import org.bitcoins.core.number.{Int32, UInt32}
|
||||||
|
import org.bitcoins.core.policy.Policy
|
||||||
import org.bitcoins.core.protocol.CompactSizeUInt
|
import org.bitcoins.core.protocol.CompactSizeUInt
|
||||||
import org.bitcoins.core.protocol.script._
|
import org.bitcoins.core.protocol.script.*
|
||||||
import org.bitcoins.core.protocol.transaction._
|
import org.bitcoins.core.protocol.transaction.*
|
||||||
import org.bitcoins.core.script.constant.ScriptToken
|
import org.bitcoins.core.script.constant.ScriptToken
|
||||||
import org.bitcoins.core.script.crypto._
|
import org.bitcoins.core.script.crypto.*
|
||||||
import org.bitcoins.core.serializers.transaction.RawTransactionOutputParser
|
import org.bitcoins.core.serializers.transaction.RawTransactionOutputParser
|
||||||
import org.bitcoins.core.util.{BitcoinScriptUtil, BytesUtil}
|
import org.bitcoins.core.util.{BitcoinScriptUtil, BytesUtil}
|
||||||
import org.bitcoins.core.wallet.utxo.{InputInfo, InputSigningInfo}
|
import org.bitcoins.core.wallet.utxo.{InputInfo, InputSigningInfo}
|
||||||
import org.bitcoins.crypto._
|
import org.bitcoins.crypto.*
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
||||||
/** Created by chris on 2/16/16. Wrapper that serializes like Transaction, but
|
/** Created by chris on 2/16/16. Wrapper that serializes like Transaction, but
|
||||||
@ -466,27 +467,13 @@ sealed abstract class TransactionSignatureSerializer {
|
|||||||
spendingTransaction: Transaction,
|
spendingTransaction: Transaction,
|
||||||
signingInfo: InputSigningInfo[InputInfo],
|
signingInfo: InputSigningInfo[InputInfo],
|
||||||
hashType: HashType,
|
hashType: HashType,
|
||||||
taprootOptions: TaprootSerializationOptions): DoubleSha256Digest = {
|
taprootOptions: TaprootSerializationOptions): HashDigest = {
|
||||||
val inputIndexOpt =
|
val txSigComponent = TxSigComponent(
|
||||||
TxUtil.inputIndexOpt(signingInfo.inputInfo, spendingTransaction)
|
inputInfo = signingInfo.inputInfo,
|
||||||
|
unsignedTx = spendingTransaction,
|
||||||
if (inputIndexOpt.isEmpty) {
|
outputMap = signingInfo.inputInfo.previousOutputMap,
|
||||||
errorHash
|
flags = Policy.standardFlags)
|
||||||
} else if (
|
hashForSignature(txSigComponent, hashType, taprootOptions)
|
||||||
(hashType.isInstanceOf[SIGHASH_SINGLE] || hashType
|
|
||||||
.isInstanceOf[SIGHASH_SINGLE_ANYONECANPAY]) &&
|
|
||||||
inputIndexOpt.get >= spendingTransaction.outputs.size &&
|
|
||||||
signingInfo.sigVersion != SigVersionWitnessV0
|
|
||||||
) {
|
|
||||||
errorHash
|
|
||||||
} else {
|
|
||||||
val serializedTxForSignature =
|
|
||||||
serializeForSignature(spendingTransaction,
|
|
||||||
signingInfo,
|
|
||||||
hashType,
|
|
||||||
taprootOptions)
|
|
||||||
CryptoUtil.doubleSHA256(serializedTxForSignature)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the input's sequence number to zero EXCEPT for the input at
|
/** Sets the input's sequence number to zero EXCEPT for the input at
|
||||||
|
@ -6,6 +6,7 @@ import org.bitcoins.core.protocol.CompactSizeUInt
|
|||||||
import org.bitcoins.core.protocol.script.*
|
import org.bitcoins.core.protocol.script.*
|
||||||
import org.bitcoins.core.protocol.transaction.*
|
import org.bitcoins.core.protocol.transaction.*
|
||||||
import org.bitcoins.core.script.constant.{OP_TRUE, ScriptConstant}
|
import org.bitcoins.core.script.constant.{OP_TRUE, ScriptConstant}
|
||||||
|
import org.bitcoins.core.script.util.PreviousOutputMap
|
||||||
import org.bitcoins.core.util.{BitcoinScriptUtil, BytesUtil}
|
import org.bitcoins.core.util.{BitcoinScriptUtil, BytesUtil}
|
||||||
import org.bitcoins.crypto.{
|
import org.bitcoins.crypto.{
|
||||||
ECDigitalSignature,
|
ECDigitalSignature,
|
||||||
@ -77,6 +78,8 @@ sealed trait InputInfo {
|
|||||||
: ECSignatureParams[this.type] = {
|
: ECSignatureParams[this.type] = {
|
||||||
signerMaterial.copy(inputInfo = this)
|
signerMaterial.copy(inputInfo = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def previousOutputMap: PreviousOutputMap
|
||||||
}
|
}
|
||||||
|
|
||||||
object InputInfo {
|
object InputInfo {
|
||||||
@ -347,6 +350,7 @@ object InputInfo {
|
|||||||
|
|
||||||
sealed trait RawInputInfo extends InputInfo {
|
sealed trait RawInputInfo extends InputInfo {
|
||||||
override def scriptPubKey: RawScriptPubKey
|
override def scriptPubKey: RawScriptPubKey
|
||||||
|
override def previousOutputMap: PreviousOutputMap = PreviousOutputMap.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
object RawInputInfo {
|
object RawInputInfo {
|
||||||
@ -422,6 +426,8 @@ case class EmptyInputInfo(outPoint: TransactionOutPoint, amount: CurrencyUnit)
|
|||||||
ConditionalPath.NoCondition
|
ConditionalPath.NoCondition
|
||||||
override def pubKeys: Vector[ECPublicKey] = Vector.empty
|
override def pubKeys: Vector[ECPublicKey] = Vector.empty
|
||||||
override def requiredSigs: Int = 0
|
override def requiredSigs: Int = 0
|
||||||
|
|
||||||
|
override def previousOutputMap: PreviousOutputMap = PreviousOutputMap.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
case class P2PKInputInfo(
|
case class P2PKInputInfo(
|
||||||
@ -550,6 +556,7 @@ case class LockTimeInputInfo(
|
|||||||
|
|
||||||
sealed trait SegwitV0NativeInputInfo extends InputInfo {
|
sealed trait SegwitV0NativeInputInfo extends InputInfo {
|
||||||
def scriptWitness: ScriptWitnessV0
|
def scriptWitness: ScriptWitnessV0
|
||||||
|
override def previousOutputMap: PreviousOutputMap = PreviousOutputMap.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
object SegwitV0NativeInputInfo {
|
object SegwitV0NativeInputInfo {
|
||||||
@ -623,6 +630,7 @@ case class UnassignedSegwitNativeInputInfo(
|
|||||||
pubKeys: Vector[ECPublicKey])
|
pubKeys: Vector[ECPublicKey])
|
||||||
extends InputInfo {
|
extends InputInfo {
|
||||||
override def requiredSigs: Int = pubKeys.length
|
override def requiredSigs: Int = pubKeys.length
|
||||||
|
override def previousOutputMap: PreviousOutputMap = PreviousOutputMap.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait P2SHInputInfo extends InputInfo {
|
sealed trait P2SHInputInfo extends InputInfo {
|
||||||
@ -637,6 +645,8 @@ sealed trait P2SHInputInfo extends InputInfo {
|
|||||||
override def pubKeys: Vector[ECPublicKey] = nestedInputInfo.pubKeys
|
override def pubKeys: Vector[ECPublicKey] = nestedInputInfo.pubKeys
|
||||||
|
|
||||||
override def requiredSigs: Int = nestedInputInfo.requiredSigs
|
override def requiredSigs: Int = nestedInputInfo.requiredSigs
|
||||||
|
|
||||||
|
override def previousOutputMap: PreviousOutputMap = PreviousOutputMap.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
case class P2SHNonSegwitInputInfo(
|
case class P2SHNonSegwitInputInfo(
|
||||||
|
Loading…
Reference in New Issue
Block a user