Completed
Push — master ( 7ac9fb...3b1821 )
by thomas
28:43
created

CheckSequenceVerify   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 57.14%

Importance

Changes 0
Metric Value
dl 0
loc 89
ccs 16
cts 28
cp 0.5714
rs 10
c 0
b 0
f 0
wmc 13
lcom 1
cbo 4

6 Methods

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