Completed
Pull Request — master (#446)
by thomas
157:14 queued 87:18
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\Buffertools;
11
use BitWasp\Buffertools\Parser;
12
13
class TransactionSerializer implements TransactionSerializerInterface
14
{
15
    const NO_WITNESS = 1;
16
17
    /**
18
     * @var \BitWasp\Buffertools\Types\Int32
19
     */
20
    private $int32le;
21
22
    /**
23
     * @var \BitWasp\Buffertools\Types\Uint32
24
     */
25
    private $uint32le;
26
27
    /**
28
     * @var \BitWasp\Buffertools\Types\VarInt
29
     */
30
    private $varint;
31
32
    /**
33
     * @var TransactionInputSerializer
34
     */
35
    private $inputSerializer;
36 270
37
    /**
38 270
     * @var TransactionOutputSerializer
39 270
     */
40 270
    private $outputSerializer;
41 270
42
    /**
43
     * @var ScriptWitnessSerializer
44
     */
45
    private $witnessSerializer;
46
47 186
    public function __construct(TransactionInputSerializer $inputSerializer = null, TransactionOutputSerializer $outputSerializer = null, ScriptWitnessSerializer $witnessSerializer = null)
48
    {
49 186
        $this->int32le = Types::int32le();
50 186
        $this->uint32le = Types::uint32le();
51 186
        $this->varint = Types::varint();
52 186
53
        $this->inputSerializer = $inputSerializer ?: new TransactionInputSerializer(new OutPointSerializer());
54 186
        $this->outputSerializer = $outputSerializer ?: new TransactionOutputSerializer;
55
        $this->witnessSerializer = $witnessSerializer ?: new ScriptWitnessSerializer();
56 186
    }
57 186
58 186
    /**
59 186
     * @param Parser $parser
60 93
     * @return TransactionInterface
61
     */
62 186
    public function fromParser(Parser $parser)
63 186
    {
64 186
        $version = $this->int32le->read($parser);
65
66
        $vin = [];
67
        $vinCount = $this->varint->read($parser);
68
        for ($i = 0; $i < $vinCount; $i++) {
69
            $vin[] = $this->inputSerializer->fromParser($parser);
70
        }
71
72
        $vout = [];
73
        $flags = 0;
74
        if (count($vin) === 0) {
75
            $flags = (int) $this->varint->read($parser);
76
            if ($flags !== 0) {
77
                $vinCount = $this->varint->read($parser);
78 186
                for ($i = 0; $i < $vinCount; $i++) {
79 186
                    $vin[] = $this->inputSerializer->fromParser($parser);
80 186
                }
81 93
82
                $voutCount = $this->varint->read($parser);
83
                for ($i = 0; $i < $voutCount; $i++) {
84 186
                    $vout[] = $this->outputSerializer->fromParser($parser);
85 186
                }
86
            }
87
        } else {
88
            $voutCount = $this->varint->read($parser);
89
            for ($i = 0; $i < $voutCount; $i++) {
90
                $vout[] = $this->outputSerializer->fromParser($parser);
91
            }
92
        }
93
94 186
        $vwit = [];
95
        if (($flags & 1)) {
96
            $flags ^= 1;
97
            $witCount = count($vin);
98 186
            for ($i = 0; $i < $witCount; $i++) {
99
                $vectorCount = $this->varint->read($parser);
100 186
                $vwit[] = $this->witnessSerializer->fromParser($parser, $vectorCount);
101 93
            }
102 93
        }
103 93
104 93
        if ($flags) {
105
            throw new \RuntimeException('Flags byte was 0');
106 93
        }
107
108
        $lockTime = $this->uint32le->read($parser);
109
110
        return new Transaction($version, $vin, $vout, $vwit, $lockTime);
111
    }
112
113 120
    /**
114
     * @param string|BufferInterface $data
115 120
     * @return TransactionInterface
116
     */
117
    public function parse($data)
118
    {
119
        return $this->fromParser(new Parser($data));
120
    }
121
122 66
    /**
123
     * @param TransactionInterface $transaction
124 66
     * @param int $opt
125 66
     * @return BufferInterface
126 66
     */
127 66
    public function serialize(TransactionInterface $transaction, $opt = 0)
128 66
    {
129 66
        $parser = new Parser();
130 66
        $parser->writeRawBinary(4, $this->int32le->write($transaction->getVersion()));
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...
131
132 66
        $flags = 0;
133 66
        $allowWitness = !($opt & self::NO_WITNESS);
134
        if ($allowWitness && $transaction->hasWitness()) {
135 66
            $flags |= 1;
136 66
        }
137 33
138
        if ($flags) {
139 66
            $parser->writeRawBinary(2, "\x00" . chr($flags));
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...
140 66
        }
141 66
142 33
        $parser->appendBuffer(Buffertools::numToVarInt(count($transaction->getInputs())), true);
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...
143
        foreach ($transaction->getInputs() as $input) {
144 66
            $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...
145 66
        }
146
147 66
        $parser->appendBuffer(Buffertools::numToVarInt(count($transaction->getOutputs())), true);
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...
148 66
        foreach ($transaction->getOutputs() as $output) {
149 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...
150 33
        }
151 33
152
        if ($flags & 1) {
153 66
            foreach ($transaction->getWitnesses() as $witness) {
154
                $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...
155 66
            }
156
        }
157
158
        $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...
159
160
        return $parser->getBuffer();
161
    }
162
}
163