Completed
Pull Request — master (#593)
by thomas
15:02
created

CheckLocktimeVerify   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 5

Test Coverage

Coverage 20%

Importance

Changes 0
Metric Value
dl 0
loc 83
ccs 5
cts 25
cp 0.2
rs 10
c 0
b 0
f 0
wmc 11
lcom 0
cbo 5

5 Methods

Rating   Name   Duplication   Size   Complexity  
A fromScript() 0 4 1
A __construct() 0 13 3
B fromDecodedScript() 0 22 5
A getLocktime() 0 4 1
A isLockedToBlock() 0 4 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
13
class CheckLocktimeVerify
14
{
15
    /**
16
     * @var int
17
     */
18
    private $nLockTime;
19
20
    /**
21
     * @var bool
22
     */
23
    private $toBlock;
24
25
    /**
26
     * CheckLocktimeVerify constructor.
27
     * @param int $nLockTime
28
     */
29
    public function __construct(int $nLockTime)
30
    {
31
        if ($nLockTime < 0) {
32
            throw new \RuntimeException("locktime cannot be negative");
33
        }
34
35
        if ($nLockTime > Locktime::INT_MAX) {
36
            throw new \RuntimeException("nLockTime exceeds maximum value");
37
        }
38
39
        $this->nLockTime = $nLockTime;
40
        $this->toBlock = (new Locktime())->isLockedToBlock($nLockTime);
41
    }
42
43
    /**
44
     * @param Operation[] $chunks
45
     * @param bool $fMinimal
46
     * @return static
47
     */
48 3
    public static function fromDecodedScript(array $chunks, bool $fMinimal = false): self
49
    {
50 3
        if (count($chunks) !== 3) {
51 3
            throw new \RuntimeException("Invalid number of items for CLTV");
52
        }
53
54 2
        if (!$chunks[0]->isPush()) {
55 2
            throw new \InvalidArgumentException('CLTV script had invalid value for time');
56
        }
57
58
        if ($chunks[1]->getOp() !== Opcodes::OP_CHECKLOCKTIMEVERIFY) {
59
            throw new \InvalidArgumentException('CLTV script invalid opcode');
60
        }
61
62
        if ($chunks[2]->getOp() !== Opcodes::OP_DROP) {
63
            throw new \InvalidArgumentException('CLTV script invalid opcode');
64
        }
65
66
        $numLockTime = Number::buffer($chunks[0]->getData(), $fMinimal, 5);
67
68
        return new static((int) $numLockTime->getInt());
69
    }
70
71
    /**
72
     * @param ScriptInterface $script
73
     * @return CheckLocktimeVerify
74
     */
75
    public static function fromScript(ScriptInterface $script): self
76
    {
77
        return static::fromDecodedScript($script->getScriptParser()->decode());
78
    }
79
80
    /**
81
     * @return int
82
     */
83
    public function getLocktime(): int
84
    {
85
        return $this->nLockTime;
86
    }
87
88
    /**
89
     * @return bool
90
     */
91
    public function isLockedToBlock(): bool
92
    {
93
        return $this->toBlock;
94
    }
95
}
96