diff --git a/src/main/scala/org/bitcoins/protocol/transaction/TransactionConstants.scala b/src/main/scala/org/bitcoins/protocol/transaction/TransactionConstants.scala index 9092188ed7..0aec03634e 100644 --- a/src/main/scala/org/bitcoins/protocol/transaction/TransactionConstants.scala +++ b/src/main/scala/org/bitcoins/protocol/transaction/TransactionConstants.scala @@ -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 diff --git a/src/main/scala/org/bitcoins/script/locktime/LockTimeInterpreter.scala b/src/main/scala/org/bitcoins/script/locktime/LockTimeInterpreter.scala index b3cf67d197..4bc7792ca5 100644 --- a/src/main/scala/org/bitcoins/script/locktime/LockTimeInterpreter.scala +++ b/src/main/scala/org/bitcoins/script/locktime/LockTimeInterpreter.scala @@ -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 } diff --git a/src/test/scala/org/bitcoins/script/locktime/LockTimeInterpreterTest.scala b/src/test/scala/org/bitcoins/script/locktime/LockTimeInterpreterTest.scala index 799dd14bc0..d9b71ec6d1 100644 --- a/src/test/scala/org/bitcoins/script/locktime/LockTimeInterpreterTest.scala +++ b/src/test/scala/org/bitcoins/script/locktime/LockTimeInterpreterTest.scala @@ -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)