Refactoring sequence masks into TransactionConstants

This commit is contained in:
Chris Stewart 2016-05-03 19:46:49 -05:00
commit a82ed54d24
3 changed files with 50 additions and 43 deletions

View file

@ -1,11 +1,39 @@
package org.bitcoins.protocol.transaction
/**
* Created by chris on 2/12/16.
*/
object TransactionConstants {
import org.bitcoins.script.constant.ScriptNumber
val version = 1
val lockTime = 0
val sequence = 4294967295L
/**
* Created by chris on 2/12/16.
*/
trait TransactionConstants {
lazy val version = 1
lazy val lockTime = 0
lazy val sequence = 4294967295L
/**
* If bit (1 << 31) of the sequence number is set,
* then no consensus meaning is applied to the sequence number and can be included
* in any block under all currently possible circumstances.
*
* @return the mask that ben used with a bitwise and to indicate if the sequence number has any meaning
*/
def locktimeDisabledFlag = 1L << 31
/**
* If a transaction's input's sequence number encodes a relative lock-time, this mask is
* applied to extract that lock-time from the sequence field.
*/
def sequenceLockTimeMask = 0x0000ffff
/**
* If the transaction input sequence number encodes a relative lock-time and this flag
* is set, the relative lock-time has units of 512 seconds,
* otherwise it specifies blocks with a granularity of 1.
*/
def sequenceLockTimeTypeFlag = (1L << 22)
}
object TransactionConstants extends TransactionConstants

View file

@ -101,40 +101,12 @@ trait LockTimeInterpreter extends BitcoinSLogger {
opCheckSequenceVerify(ScriptProgram(program, ScriptNumber(s.hex) :: program.stack.tail, ScriptProgram.Stack))
case token : ScriptToken =>
throw new RuntimeException("Stack top must be either a ScriptConstant or a ScriptNumber, we got: " + token)
}
}
}
/**
* If bit (1 << 31) of the sequence number is set,
* then no consensus meaning is applied to the sequence number and can be included
* in any block under all currently possible circumstances.
* @return the mask that ben used with a bitwise and to indicate if the sequence number has any meaning
*/
def locktimeDisabledFlag = 1L << 31
/**
* The script number on the stack has the disable flag (1 << 31) unset
* @param s
* @return
*/
def isLockTimeBitOff(s : ScriptNumber) : Boolean = (s.num & locktimeDisabledFlag) == 0
/**
* If a transaction's input's sequence number encodes a relative lock-time, this mask is
* applied to extract that lock-time from the sequence field.
*/
def sequenceLockTimeMask = 0x0000ffff
/**
* If the transaction input sequence number encodes a relative lock-time and this flag
* is set, the relative lock-time has units of 512 seconds,
* otherwise it specifies blocks with a granularity of 1.
*/
def sequenceLockTimeTypeFlag = (1L << 22)
/**
* Mimics this function inside of bitcoin core
* https://github.com/bitcoin/bitcoin/blob/e26b62093ae21e89ed7d36a24a6b863f38ec631d/src/script/interpreter.cpp#L1196
@ -148,7 +120,7 @@ trait LockTimeInterpreter extends BitcoinSLogger {
if (program.txSignatureComponent.transaction.version < 2) return false
val nLockTimeMask : Long = sequenceLockTimeTypeFlag | sequenceLockTimeMask
val nLockTimeMask : Long = TransactionConstants.sequenceLockTimeTypeFlag | TransactionConstants.sequenceLockTimeMask
val txToSequenceMasked : ScriptNumber = txToSequence & ScriptNumber(nLockTimeMask)
val nSequenceMasked : ScriptNumber = nSequence & ScriptNumber(nLockTimeMask)
@ -161,10 +133,10 @@ trait LockTimeInterpreter extends BitcoinSLogger {
// unless the type of nSequenceMasked being tested is the same as
// the nSequenceMasked in the transaction.
if (!(
(txToSequenceMasked < ScriptNumber(sequenceLockTimeTypeFlag) &&
nSequenceMasked < ScriptNumber(sequenceLockTimeTypeFlag)) ||
(txToSequenceMasked >= ScriptNumber(sequenceLockTimeTypeFlag) &&
nSequenceMasked >= ScriptNumber(sequenceLockTimeTypeFlag))
(txToSequenceMasked < ScriptNumber(TransactionConstants.sequenceLockTimeTypeFlag) &&
nSequenceMasked < ScriptNumber(TransactionConstants.sequenceLockTimeTypeFlag)) ||
(txToSequenceMasked >= ScriptNumber(TransactionConstants.sequenceLockTimeTypeFlag) &&
nSequenceMasked >= ScriptNumber(TransactionConstants.sequenceLockTimeTypeFlag))
)) return false
// Now that we know we're comparing apples-to-apples, the
@ -173,4 +145,11 @@ trait LockTimeInterpreter extends BitcoinSLogger {
true
}
/**
* The script number on the stack has the disable flag (1 << 31) unset
* @param s
* @return
*/
def isLockTimeBitOff(s : ScriptNumber) : Boolean = (s.num & TransactionConstants.locktimeDisabledFlag) == 0
}

View file

@ -2,7 +2,7 @@ package org.bitcoins.script.locktime
import org.bitcoins.policy.Policy
import org.bitcoins.protocol.transaction.{Transaction, TransactionInput, UpdateTransactionInputs}
import org.bitcoins.protocol.transaction.{Transaction, TransactionConstants, TransactionInput, UpdateTransactionInputs}
import org.bitcoins.script.result._
import org.bitcoins.script.{ExecutedScriptProgram, ExecutionInProgressScriptProgram, PreExecutionScriptProgram, ScriptProgram}
import org.bitcoins.script.constant.{OP_0, ScriptNumber}
@ -127,7 +127,7 @@ class LockTimeInterpreterTest extends FlatSpec with MustMatchers with LockTimeIn
}
it must "treat OP_CHECKSEQUENCEVERIFY as a NOP if the locktime disabled flag is set in the sequence number" in {
val stack = List(ScriptNumber(locktimeDisabledFlag))
val stack = List(ScriptNumber(TransactionConstants.locktimeDisabledFlag))
val script = List(OP_CHECKSEQUENCEVERIFY)
val program = ScriptProgram(TestUtil.testProgramExecutionInProgress,stack,script)
val newProgram = opCheckSequenceVerify(program)