reduce nullFailCheck, change serializeForSig doc from BIP141->BIP143, add scalaDoc braces to links throughout code

This commit is contained in:
Tom McCabe 2017-01-05 13:37:33 -06:00
parent 983d2ed946
commit 6baf414c0a
6 changed files with 19 additions and 23 deletions

View file

@ -136,9 +136,9 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
private def nullFailCheck(sigs: Seq[ECDigitalSignature], result: TransactionSignatureCheckerResult,flags: Seq[ScriptFlag]): TransactionSignatureCheckerResult = {
logger.info("Result before nullfail check:" + result)
val nullFailEnabled = ScriptFlagUtil.requireScriptVerifyNullFail(flags)
if (nullFailEnabled && !result.isValid) {
if (nullFailEnabled && !result.isValid && sigs.exists(_.bytes.nonEmpty)) {
//we need to check that all signatures were empty byte vectors, else this fails because of BIP146 and nullfail
if (sigs.exists(_.bytes.nonEmpty)) SignatureValidationErrorNullFail else result
SignatureValidationErrorNullFail
} else result
}
}

View file

@ -15,9 +15,9 @@ import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil, BitcoinScriptUtil,
* Created by chris on 2/16/16.
* Wrapper that serializes like Transaction, but with the modifications
* required for the signature hash done
* https://github.com/bitcoin/bitcoin/blob/93c85d458ac3e2c496c1a053e1f5925f55e29100/src/script/interpreter.cpp#L1016-L1105
* [[https://github.com/bitcoin/bitcoin/blob/93c85d458ac3e2c496c1a053e1f5925f55e29100/src/script/interpreter.cpp#L1016-L1105]]
* bitcoinj version of this
* https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/Transaction.java#L924-L1008
* [[https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/Transaction.java#L924-L1008]]
*/
trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with BitcoinSLogger {
@ -130,7 +130,7 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
/**
* Serializes then hashes a transaction for signing
* this is an implementation of it's bitcoinj equivalent found here
* https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/Transaction.java#L924
* [[https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/Transaction.java#L924]]
* @param spendingTransaction the transaction we are hashing
* @param inputIndex the inputIndex we are hashing for signing
* @param script the script which we are spending
@ -140,7 +140,7 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
def hashForSignature(spendingTransaction : Transaction, inputIndex : UInt32, script : Seq[ScriptToken],
hashType : HashType) : DoubleSha256Digest = {
//these first two checks are in accordance with behavior in bitcoin core
//https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1112-L1123
//[[https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1112-L1123]]
if (inputIndex >= UInt32(spendingTransaction.inputs.size)) {
logger.warn("Our inputIndex is out of the range of the inputs in the spending transaction")
errorHash
@ -155,8 +155,8 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
}
}
/** Implements the new serialization algorithm defined in BIP141
* [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki]]
/** Implements the new serialization algorithm defined in BIP143
* [[https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki]]
* [[https://github.com/bitcoin/bitcoin/blob/f8528134fc188abc5c7175a19680206964a8fade/src/script/interpreter.cpp#L1113]]
*/
def serializeForSignature(spendingTx: Transaction, inputIndex: UInt32, script: Seq[ScriptToken], hashType: HashType,
@ -241,7 +241,7 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
/** Executes the [[SIGHASH_NONE]] procedure on a spending transaction for the input specified by inputIndex. */
private def sigHashNone(spendingTransaction : Transaction, inputIndex : UInt32) : Transaction = {
//following this implementation from bitcoinj
//https://github.com/bitcoinj/bitcoinj/blob/09a2ca64d2134b0dcbb27b1a6eb17dda6087f448/core/src/main/java/org/bitcoinj/core/Transaction.java#L957
//[[https://github.com/bitcoinj/bitcoinj/blob/09a2ca64d2134b0dcbb27b1a6eb17dda6087f448/core/src/main/java/org/bitcoinj/core/Transaction.java#L957]]
//means that no outputs are signed at all
val txWithNoOutputs = Transaction.emptyOutputs(spendingTransaction)
//set the sequence number of all inputs to 0 EXCEPT the input at inputIndex
@ -254,7 +254,7 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
/** Executes the [[SIGHASH_SINGLE]] procedure on a spending transaction for the input specified by inputIndex */
private def sigHashSingle(spendingTransaction : Transaction, inputIndex : UInt32) : Transaction = {
//following this implementation from bitcoinj
//https://github.com/bitcoinj/bitcoinj/blob/09a2ca64d2134b0dcbb27b1a6eb17dda6087f448/core/src/main/java/org/bitcoinj/core/Transaction.java#L964
//[[https://github.com/bitcoinj/bitcoinj/blob/09a2ca64d2134b0dcbb27b1a6eb17dda6087f448/core/src/main/java/org/bitcoinj/core/Transaction.java#L964]]
// In SIGHASH_SINGLE the outputs after the matching input index are deleted, and the outputs before
// that position are "nulled out". Unintuitively, the value in a "null" transaction is set to -1.
val updatedOutputsOpt : Seq[Option[TransactionOutput]] = for {

View file

@ -77,7 +77,7 @@ trait LockTimeInterpreter extends BitcoinSLogger {
* the top stack item is greater than the transaction sequence (when masked according to the BIP68);
* Otherwise, script execution will continue as if a NOP had been executed.
* See BIP112 for more information
* https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki
* [[https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki]]
*/
@tailrec
final def opCheckSequenceVerify(program : ScriptProgram) : ScriptProgram = {
@ -118,8 +118,8 @@ trait LockTimeInterpreter extends BitcoinSLogger {
/**
* Mimics this function inside of bitcoin core
* https://github.com/bitcoin/bitcoin/blob/e26b62093ae21e89ed7d36a24a6b863f38ec631d/src/script/interpreter.cpp#L1196
* https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki#specification
* [[https://github.com/bitcoin/bitcoin/blob/e26b62093ae21e89ed7d36a24a6b863f38ec631d/src/script/interpreter.cpp#L1196]]
* [[https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki#specification]]
* @param program the program whose transaction input's sequence is being compared
* @param nSequence the script number on the stack top to compare to the input's sequence number
* @return if the given script number is valid or not
@ -185,7 +185,7 @@ trait LockTimeInterpreter extends BitcoinSLogger {
}
/** Mimics this function inside of bitcoin core for checking the locktime of a transaction
* https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1160. */
* [[https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1160]]. */
private def checkLockTime(program : ScriptProgram, locktime : ScriptNumber) : Boolean = {
// There are two kinds of nLockTime: lock-by-blockheight
// and lock-by-blocktime, distinguished by whether

View file

@ -52,7 +52,7 @@ trait ScriptParser extends Factory[List[ScriptToken]] with BitcoinSLogger {
logger.debug("Accum: " + accum)*/
operations match {
//for parsing strings like 'Az', need to remove single quotes
//example: https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_valid.json#L24
//example: [[https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_valid.json#L24]]
case h :: t if (h.size > 0 && h.head == ''' && h.last == ''') =>
logger.debug("Found a string constant")
val strippedQuotes = h.replace("'","")
@ -123,7 +123,7 @@ trait ScriptParser extends Factory[List[ScriptToken]] with BitcoinSLogger {
//this handles weird cases for parsing with various formats in bitcoin core.
//take a look at https://github.com/bitcoin/bitcoin/blob/605c17844ea32b6d237db6d83871164dc7d59dab/src/core_read.cpp#L53-L88
//for the offical parsing algorithm, for examples of weird formats look inside of
//https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_valid.json
//[[https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_valid.json]]
val parsedBytesFromString = loop(str.split(" ").toList, List()).reverse
logger.info("Parsed bytes from the given string: " + BitcoinSUtil.encodeHex(parsedBytesFromString))
parse(parsedBytesFromString)
@ -172,7 +172,7 @@ trait ScriptParser extends Factory[List[ScriptToken]] with BitcoinSLogger {
/**
* Parses the bytes in string format, an example input would look like this
* "0x09 0x00000000 0x00000000 0x10"
* see https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_valid.json#L21-L25
* see [[https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_valid.json#L21-L25]]
* for examples of this */
def parseBytesFromString(s: String) : List[ScriptConstant] = {
//logger.debug("Parsing bytes from string " + s)

View file

@ -45,7 +45,6 @@ trait RawTransactionOutputParser extends RawBitcoinSerializer[Seq[TransactionOut
numOutputs.hex + serializedOutputs.mkString
}
/** Writes a single transaction output */
def write(output : TransactionOutput) : String = {
val satoshis = CurrencyUnits.toSatoshis(output.value)
@ -72,10 +71,7 @@ trait RawTransactionOutputParser extends RawBitcoinSerializer[Seq[TransactionOut
}
/**
* Parses the amount of satoshis a hex string represetns
* @param hex the hex string that is being parsed to satoshis
* @return the value of the hex string in satoshis
*/
* Parses the amount of [[Satoshis]] a hex string represents. */
private def parseSatoshis(hex : String) : Satoshis = RawSatoshisSerializer.read(hex)
}

View file

@ -49,7 +49,7 @@ trait NumberUtil extends BitcoinSLogger {
//BigInt interprets the number as an unsigned number then applies the given
//sign in front of that number, therefore if we have a negative number we need to invert it
//since twos complement is an inverted number representation for negative numbers
//see https://en.wikipedia.org/wiki/Two%27s_complement
//see [[https://en.wikipedia.org/wiki/Two%27s_complement]]
if (bytes.isEmpty) BigInt(0)
//check if sign bit is set
else if ((0x80.toByte & bytes.head) !=0) {