CheckSequenceVerify   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Test Coverage

Coverage 57.14%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 23
c 1
b 0
f 1
dl 0
loc 87
ccs 16
cts 28
cp 0.5714
rs 10
wmc 13

6 Methods

Rating   Name   Duplication   Size   Complexity  
A isDisabled() 0 3 1
A isRelativeToBlock() 0 7 2
A getRelativeLockTime() 0 3 1
A __construct() 0 11 3
A fromDecodedScript() 0 21 5
A fromScript() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Bitcoin\Transaction\Factory\ScriptInfo;
6
7
use BitWasp\Bitcoin\Locktime;
8
use BitWasp\Bitcoin\Script\Interpreter\Number;
9
use BitWasp\Bitcoin\Script\Opcodes;
10
use BitWasp\Bitcoin\Script\Parser\Operation;
11
use BitWasp\Bitcoin\Script\ScriptInterface;
12
use BitWasp\Bitcoin\Transaction\TransactionInput;
13
14
class CheckSequenceVerify
15
{
16
    /**
17
     * @var int
18
     */
19
    private $relativeTimeLock;
20
21
    /**
22
     * CheckLocktimeVerify constructor.
23
     * @param int $relativeTimeLock
24
     */
25 7
    public function __construct(int $relativeTimeLock)
26
    {
27 7
        if ($relativeTimeLock < 0) {
28
            throw new \RuntimeException("relative locktime cannot be negative");
29
        }
30
31 7
        if ($relativeTimeLock > Locktime::INT_MAX) {
32
            throw new \RuntimeException("nLockTime exceeds maximum value");
33
        }
34
35 7
        $this->relativeTimeLock = $relativeTimeLock;
36 7
    }
37
38
    /**
39
     * @param Operation[] $chunks
40
     * @param bool $fMinimal
41
     * @return static
42
     */
43 117
    public static function fromDecodedScript(array $chunks, $fMinimal = false): CheckSequenceVerify
44
    {
45 117
        if (count($chunks) !== 3) {
46 117
            throw new \RuntimeException("Invalid number of items for CSV");
47
        }
48
49 88
        if (!$chunks[0]->isPush()) {
50 81
            throw new \InvalidArgumentException('CSV script had invalid value for time');
51
        }
52
53 7
        if ($chunks[1]->getOp() !== Opcodes::OP_CHECKSEQUENCEVERIFY) {
54
            throw new \InvalidArgumentException('CSV script invalid opcode');
55
        }
56
57 7
        if ($chunks[2]->getOp() !== Opcodes::OP_DROP) {
58
            throw new \InvalidArgumentException('CSV script invalid opcode');
59
        }
60
61 7
        $numLockTime = Number::buffer($chunks[0]->getData(), $fMinimal, 5);
62
63 7
        return new CheckSequenceVerify($numLockTime->getInt());
64
    }
65
66
    /**
67
     * @param ScriptInterface $script
68
     * @return CheckSequenceVerify
69
     */
70
    public static function fromScript(ScriptInterface $script): self
71
    {
72
        return static::fromDecodedScript($script->getScriptParser()->decode());
73
    }
74
75
    /**
76
     * @return int
77
     */
78 7
    public function getRelativeLockTime(): int
79
    {
80 7
        return $this->relativeTimeLock;
81
    }
82
83
    /**
84
     * @return bool
85
     */
86
    public function isRelativeToBlock(): bool
87
    {
88
        if ($this->isDisabled()) {
89
            throw new \RuntimeException("This opcode seems to be disabled");
90
        }
91
92
        return ($this->relativeTimeLock & TransactionInput::SEQUENCE_LOCKTIME_TYPE_FLAG) === 0;
93
    }
94
95
    /**
96
     * @return bool
97
     */
98
    public function isDisabled(): bool
99
    {
100
        return ($this->relativeTimeLock & TransactionInput::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0;
101
    }
102
}
103