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)
| 1123 | // ScriptVerifyCheckSequenceVerify is not set, the code continues as if OP_NOP3 |
| 1124 | // were executed. |
| 1125 | func 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. |
nothing calls this directly
no test coverage detected
searching dependent graphs…