Completed
Pull Request — master (#446)
by thomas
116:20 queued 46:28
created

TransactionSerializer::fromParser()   C

Complexity

Conditions 10
Paths 24

Size

Total Lines 50
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 25.7901

Importance

Changes 0
Metric Value
cc 10
eloc 32
c 0
b 0
f 0
nc 24
nop 1
dl 0
loc 50
ccs 17
cts 37
cp 0.4595
crap 25.7901
rs 5.7647

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace BitWasp\Bitcoin\Serializer\Transaction;
4
5
use BitWasp\Bitcoin\Serializer\Script\ScriptWitnessSerializer;
6
use BitWasp\Bitcoin\Serializer\Types;
7
use BitWasp\Bitcoin\Transaction\Transaction;
8
use BitWasp\Bitcoin\Transaction\TransactionInterface;
9
use BitWasp\Buffertools\BufferInterface;
10
use BitWasp\Buffertools\Parser;
11
12
class TransactionSerializer implements TransactionSerializerInterface
13
{
14
    const NO_WITNESS = 1;
15
16
    /**
17
     * @var \BitWasp\Buffertools\Types\Int32
18
     */
19
    private $int32le;
20
21
    /**
22
     * @var \BitWasp\Buffertools\Types\Uint32
23
     */
24
    private $uint32le;
25
26
    /**
27
     * @var \BitWasp\Buffertools\Types\VarInt
28
     */
29
    private $varint;
30
31
    /**
32
     * @var TransactionInputSerializer
33
     */
34
    private $inputSerializer;
35
36 270
    /**
37
     * @var TransactionOutputSerializer
38 270
     */
39 270
    private $outputSerializer;
40 270
41 270
    /**
42
     * @var ScriptWitnessSerializer
43
     */
44
    private $witnessSerializer;
45
46
    public function __construct(TransactionInputSerializer $inputSerializer = null, TransactionOutputSerializer $outputSerializer = null, ScriptWitnessSerializer $witnessSerializer = null)
47 186
    {
48
        $this->int32le = Types::int32le();
49 186
        $this->uint32le = Types::uint32le();
50 186
        $this->varint = Types::varint();
51 186
52 186
        $this->inputSerializer = $inputSerializer ?: new TransactionInputSerializer(new OutPointSerializer());
53
        $this->outputSerializer = $outputSerializer ?: new TransactionOutputSerializer;
54 186
        $this->witnessSerializer = $witnessSerializer ?: new ScriptWitnessSerializer();
55
    }
56 186
57 186
    /**
58 186
     * @param Parser $parser
59 186
     * @return TransactionInterface
60 93
     */
61
    public function fromParser(Parser $parser)
62 186
    {
63 186
        $version = $this->int32le->read($parser);
64 186
65
        $vin = [];
66
        $vinCount = $this->varint->read($parser);
67
        for ($i = 0; $i < $vinCount; $i++) {
68
            $vin[] = $this->inputSerializer->fromParser($parser);
69
        }
70
71
        $vout = [];
72
        $flags = 0;
73
        if (count($vin) === 0) {
74
            $flags = (int) $this->varint->read($parser);
75
            if ($flags !== 0) {
76
                $vinCount = $this->varint->read($parser);
77
                for ($i = 0; $i < $vinCount; $i++) {
78 186
                    $vin[] = $this->inputSerializer->fromParser($parser);
79 186
                }
80 186
81 93
                $voutCount = $this->varint->read($parser);
82
                for ($i = 0; $i < $voutCount; $i++) {
83
                    $vout[] = $this->outputSerializer->fromParser($parser);
84 186
                }
85 186
            }
86
        } else {
87
            $voutCount = $this->varint->read($parser);
88
            for ($i = 0; $i < $voutCount; $i++) {
89
                $vout[] = $this->outputSerializer->fromParser($parser);
90
            }
91
        }
92
93
        $vwit = [];
94 186
        if (($flags & 1)) {
95
            $flags ^= 1;
96
            $witCount = count($vin);
97
            for ($i = 0; $i < $witCount; $i++) {
98 186
                $vectorCount = $this->varint->read($parser);
99
                $vwit[] = $this->witnessSerializer->fromParser($parser, $vectorCount);
100 186
            }
101 93
        }
102 93
103 93
        if ($flags) {
104 93
            throw new \RuntimeException('Flags byte was 0');
105
        }
106 93
107
        $lockTime = $this->uint32le->read($parser);
108
109
        return new Transaction($version, $vin, $vout, $vwit, $lockTime);
110
    }
111
112
    /**
113 120
     * @param string|BufferInterface $data
114
     * @return TransactionInterface
115 120
     */
116
    public function parse($data)
117
    {
118
        return $this->fromParser(new Parser($data));
119
    }
120
121
    /**
122 66
     * @param TransactionInterface $transaction
123
     * @param int $opt
124 66
     * @return BufferInterface
125 66
     */
126 66
    public function serialize(TransactionInterface $transaction, $opt = 0)
127 66
    {
128 66
        $parser = new Parser();
129 66
        $parser->appendBinary($this->int32le->write($transaction->getVersion()));
0 ignored issues
show
Bug introduced by
The method appendBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
130 66
131
        $flags = 0;
132 66
        $allowWitness = !($opt & self::NO_WITNESS);
133 66
        if ($allowWitness && $transaction->hasWitness()) {
134
            $flags |= 1;
135 66
        }
136 66
137 33
        if ($flags) {
138
            $parser->appendBinary(pack("CC", 0, $flags));
0 ignored issues
show
Bug introduced by
The method appendBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
139 66
        }
140 66
141 66
        $parser->appendBinary($this->varint->write(count($transaction->getInputs())), true);
0 ignored issues
show
Bug introduced by
The method appendBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
142 33
        foreach ($transaction->getInputs() as $input) {
143
            $parser->appendBuffer($this->inputSerializer->serialize($input));
0 ignored issues
show
Bug introduced by
The method appendBuffer() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
144 66
        }
145 66
146
        $parser->appendBinary($this->varint->write(count($transaction->getOutputs())), true);
0 ignored issues
show
Bug introduced by
The method appendBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
147 66
        foreach ($transaction->getOutputs() as $output) {
148 66
            $parser->appendBuffer($this->outputSerializer->serialize($output));
0 ignored issues
show
Bug introduced by
The method appendBuffer() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
149 66
        }
150 33
151 33
        if ($flags & 1) {
152
            foreach ($transaction->getWitnesses() as $witness) {
153 66
                $parser->appendBuffer($this->witnessSerializer->serialize($witness));
0 ignored issues
show
Bug introduced by
The method appendBuffer() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
154
            }
155 66
        }
156
157
        $parser->writeRawBinary(4, $this->uint32le->write($transaction->getLockTime()));
0 ignored issues
show
Bug introduced by
The method writeRawBinary() does not seem to exist on object<BitWasp\Buffertools\Parser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
158
159
        return $parser->getBuffer();
160
    }
161
}
162