MCPcopy Index your code
hub / github.com/btcsuite/btcd / opcodeCheckSequenceVerify

Function opcodeCheckSequenceVerify

txscript/opcode.go:1125–1195  ·  view source on GitHub ↗

opcodeCheckSequenceVerify compares the top item on the data stack to the LockTime field of the transaction containing the script signature validating if the transaction outputs are spendable yet. If flag ScriptVerifyCheckSequenceVerify is not set, the code continues as if OP_NOP3 were executed.

(op *opcode, data []byte, vm *Engine)

Source from the content-addressed store, hash-verified

1123// ScriptVerifyCheckSequenceVerify is not set, the code continues as if OP_NOP3
1124// were executed.
1125func opcodeCheckSequenceVerify(op *opcode, data []byte, vm *Engine) error {
1126 // If the ScriptVerifyCheckSequenceVerify script flag is not set, treat
1127 // opcode as OP_NOP3 instead.
1128 if !vm.hasFlag(ScriptVerifyCheckSequenceVerify) {
1129 if vm.hasFlag(ScriptDiscourageUpgradableNops) {
1130 return scriptError(ErrDiscourageUpgradableNOPs,
1131 "OP_NOP3 reserved for soft-fork upgrades")
1132 }
1133 return nil
1134 }
1135
1136 // The current transaction sequence is a uint32 resulting in a maximum
1137 // sequence of 2^32-1. However, scriptNums are signed and therefore a
1138 // standard 4-byte scriptNum would only support up to a maximum of
1139 // 2^31-1. Thus, a 5-byte scriptNum is used here since it will support
1140 // up to 2^39-1 which allows sequences beyond the current sequence
1141 // limit.
1142 //
1143 // PeekByteArray is used here instead of PeekInt because we do not want
1144 // to be limited to a 4-byte integer for reasons specified above.
1145 so, err := vm.dstack.PeekByteArray(0)
1146 if err != nil {
1147 return err
1148 }
1149 stackSequence, err := MakeScriptNum(so, vm.dstack.verifyMinimalData, 5)
1150 if err != nil {
1151 return err
1152 }
1153
1154 // In the rare event that the argument needs to be < 0 due to some
1155 // arithmetic being done first, you can always use
1156 // 0 OP_MAX OP_CHECKSEQUENCEVERIFY.
1157 if stackSequence < 0 {
1158 str := fmt.Sprintf("negative sequence: %d", stackSequence)
1159 return scriptError(ErrNegativeLockTime, str)
1160 }
1161
1162 sequence := int64(stackSequence)
1163
1164 // To provide for future soft-fork extensibility, if the
1165 // operand has the disabled lock-time flag set,
1166 // CHECKSEQUENCEVERIFY behaves as a NOP.
1167 if sequence&int64(wire.SequenceLockTimeDisabled) != 0 {
1168 return nil
1169 }
1170
1171 // Transaction version numbers not high enough to trigger CSV rules must
1172 // fail.
1173 if uint32(vm.tx.Version) < 2 {
1174 str := fmt.Sprintf("invalid transaction version: %d",
1175 vm.tx.Version)
1176 return scriptError(ErrUnsatisfiedLockTime, str)
1177 }
1178
1179 // Sequence numbers with their most significant bit set are not
1180 // consensus constrained. Testing that the transaction's sequence
1181 // number does not have this bit set prevents using this property
1182 // to get around a CHECKSEQUENCEVERIFY check.

Callers

nothing calls this directly

Calls 5

scriptErrorFunction · 0.85
MakeScriptNumFunction · 0.85
verifyLockTimeFunction · 0.85
hasFlagMethod · 0.80
PeekByteArrayMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…