Completed
Pull Request — master (#127)
by thomas
67:16 queued 63:10
created

BlocktrailBatchUnspentOutputFinder   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 84.62%

Importance

Changes 0
Metric Value
dl 0
loc 96
ccs 33
cts 39
cp 0.8462
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 2

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setPaginationLimit() 0 3 1
A getUTXOs() 0 17 4
A getUnspentOutputs() 0 40 4
1
<?php
2
3
namespace Blocktrail\SDK\Services;
4
5
use Blocktrail\SDK\BlocktrailSDK;
6
use Blocktrail\SDK\UnspentOutputFinder;
7
8
class BlocktrailBatchUnspentOutputFinder extends UnspentOutputFinder {
9
10
    protected $client;
11
    protected $retryLimit;
12
    protected $sleepTime;
13
    protected $paginationLimit = 200;   //max results to retrieve at a time
14
15
    /**
16
     * @param        $apiKey
17
     * @param        $apiSecret
18
     * @param string $network
19
     * @param bool   $testnet
20
     * @param string $apiVersion
21
     * @param null   $apiEndpoint
22
     */
23 1
    public function __construct($apiKey, $apiSecret, $network = 'BTC', $testnet = false, $apiVersion = 'v1', $apiEndpoint = null) {
24 1
        $this->client = new BlocktrailSDK($apiKey, $apiSecret, $network, $testnet, $apiVersion, $apiEndpoint);
25
26 1
        $this->retryLimit = 5;
27 1
        $this->sleepTime = 20;
28 1
    }
29
30
    /**
31
     * modify the default limit on how many utxo results are returned per page
32
     * @param $limit
33
     */
34 1
    public function setPaginationLimit($limit) {
35 1
        $this->paginationLimit = $limit;
36 1
    }
37
38 1
    public function getUTXOs(array $addresses) {
39 1
        $results = array();
40
41 1
        foreach (array_chunk($addresses, 500) as $addresses) {
42 1
            if ($this->debug) {
43
                echo "\nchecking " . count($addresses) . " addresses ...";
44
            }
45
            //get the utxos for this address
46 1
            $utxos = $this->getUnspentOutputs($addresses);
47
48 1
            if (count($utxos) > 0) {
49 1
                $results = array_merge($results, $utxos);
50
            }
51
        }
52
53 1
        return $results;
54
    }
55
56
    /**
57
     * gets unspent outputs for a batch of addresses, returning and array of outputs with hash, index, value, and script pub hex
58
     *
59
     * @param string[] $addresses
60
     * @return array        2d array of unspent outputs as ['hash' => $hash, 'index' => $index, 'value' => $value, 'address' => $address, 'script_hex' => $scriptHex]
61
     * @throws \Exception
62
     */
63 1
    protected function getUnspentOutputs($addresses) {
64
        //get unspent outputs for the address - required data: hash, index, value, and script hex
65 1
        $utxos = array();
66 1
        $retries = 0;
67
68 1
        $page = 1;
69
70
        do {
71 1
            $more = true;
72
73
            try {
74 1
                $results = $this->client->batchAddressUnspentOutputs($addresses, $page, $this->paginationLimit);
75 1
                $utxos = array_merge($utxos, $results['data']);
76 1
                $page++;
77
78 1
                $more = count($results['data']) > 0;
79
            } catch (\Exception $e) {
80
                //if rate limit hit, sleep for a short while and try again
81
                if ($retries < $this->retryLimit) {
82
                    $retries++;
83
                    sleep($this->sleepTime);
84
                } else {
85
                    throw $e;
86
                }
87
            }
88 1
        } while ($more);
89
90
        //reduce the returned data into the values we're interested in
91 1
        $result = array_map(function ($utxo) {
92
            return array(
93 1
                'hash'       => $utxo['hash'],
94 1
                'index'      => $utxo['index'],
95 1
                'value'      => $utxo['value'],
96 1
                'address'    => $utxo['address'],
97 1
                'script_hex' => $utxo['script_hex'],
98
            );
99 1
        }, $utxos);
100
101
        return $result;
102
    }
103
}
104