Completed
Pull Request — master (#524)
by thomas
71:45
created

ParsedScript::getBranchIdx()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace BitWasp\Bitcoin\Script\Path;
4
5
use BitWasp\Bitcoin\Script\ScriptFactory;
6
use BitWasp\Bitcoin\Script\ScriptInterface;
7
8
class ParsedScript
9
{
10
    /**
11
     * @var ScriptInterface
12
     */
13
    private $script;
14
15
    /**
16
     * @var LogicOpNode
17
     */
18
    private $ast;
19
20
    /**
21
     * @var array
22
     */
23
    private $branches;
0 ignored issues
show
Unused Code introduced by
The property $branches is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
24
25
    /**
26
     * @var array
27
     */
28
    private $branchMap;
29
30
    /**
31
     * @var array
32
     */
33
    private $descriptorMap;
34
35
    /**
36
     * ParsedScript constructor.
37
     * @param ScriptInterface $script
38
     * @param LogicOpNode $ast
39
     * @param ScriptBranch[] $branches
40
     */
41
    public function __construct(ScriptInterface $script, LogicOpNode $ast, array $branches)
42
    {
43
        if (!$ast->isRoot()) {
44
            throw new \RuntimeException("AST is for invalid node, wasn't root");
45
        }
46
47
        $descriptorIdx = 0;
48
        $keyedBranchMap = []; // idx => ScriptBranch
49
        $keyedIdxMap = []; // descriptor => ScriptBranch
50
        foreach ($branches as $branch) {
51
            $descriptor = $branch->getPath();
52
            $descriptorKey = json_encode($descriptor);
53
            if (array_key_exists($descriptorKey, $keyedBranchMap)) {
54
                throw new \RuntimeException("Duplicate branch descriptor, invalid ScriptBranch found");
55
            }
56
57
            $keyedBranchMap[] = $branch;
58
            $keyedIdxMap[$descriptorKey] = $descriptorIdx;
59
            $descriptorIdx++;
60
        }
61
62
        $this->branchMap = $keyedBranchMap;
63
        $this->descriptorMap = $keyedIdxMap;
64
        $this->script = $script;
65
        $this->ast = $ast;
66
    }
67
68
    /**
69
     * @return bool
70
     */
71
    public function hasMultipleBranches()
72
    {
73
        return $this->ast->hasChildren();
74
    }
75
76
    /**
77
     * @param array $branchDesc
78
     * @return int
79
     */
80
    private function getBranchIdx(array $branchDesc)
81
    {
82
        $descriptorKey = json_encode($branchDesc);
83
84
        if (array_key_exists($descriptorKey, $this->descriptorMap)) {
85
            return $this->descriptorMap[$descriptorKey];
86
        }
87
88
        throw new \RuntimeException("Unknown branch");
89
    }
90
91
    /**
92
     * @param array $branchDesc
93
     * @return bool|ScriptBranch
94
     */
95
    public function getBranchByDesc(array $branchDesc)
96
    {
97
        $idx = $this->getBranchIdx($branchDesc);
98
        if (!array_key_exists($idx, $this->branchMap)) {
99
            throw new \RuntimeException("Coding error, missing entry in branch map for desc");
100
        }
101
102
        return $this->branchMap[$idx];
103
    }
104
105
    /**
106
     * @param int $idx
107
     * @return bool|ScriptBranch
108
     */
109
    public function getBranchByIdx($idx)
110
    {
111
        if (array_key_exists($idx, $this->branchMap)) {
112
            return $this->branchMap[$idx];
113
        }
114
115
        throw new \RuntimeException("Unknown branch index");
116
    }
117
118
    /**
119
     * @param $branch
120
     * @return ScriptInterface|bool
121
     */
122
    public function getMutuallyExclusiveOps($branch)
123
    {
124
        if (!($branch = $this->getBranchByDesc($branch))) {
125
            return false;
126
        }
127
128
        $steps = $branch->getSignSteps();
129
        $ops = [];
130
        foreach ($steps as $step) {
131
            $ops = array_merge($ops, $step->all());
132
        }
133
134
        return ScriptFactory::fromOperations($ops);
135
    }
136
}
137