You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
5.0 KiB
133 lines
5.0 KiB
#! /usr/bin/env python |
|
from __future__ import absolute_import |
|
'''Blockchain access via blockr tests.''' |
|
|
|
import sys |
|
import os |
|
import time |
|
import binascii |
|
from mock import patch |
|
import json |
|
|
|
import jmbitcoin as btc |
|
import pytest |
|
from jmclient import (load_program_config, jm_single, sync_wallet, BlockrInterface, |
|
get_p2pk_vbyte, get_log, Wallet) |
|
log = get_log() |
|
|
|
#TODO: some kind of mainnet testing, harder. |
|
blockr_root_url = "https://tbtc.blockr.io/api/v1/" |
|
|
|
def test_blockr_bad_request(): |
|
with pytest.raises(Exception) as e_info: |
|
btc.make_request_blockr(blockr_root_url+"address/txs/", "0000") |
|
|
|
def test_blockr_bad_pushtx(): |
|
inps = [("00000000", "btc"), ("00000000", "testnet"), |
|
('\x00'*8, "testnet"), ('\x00'*8, "x")] |
|
for i in inps: |
|
with pytest.raises(Exception) as e_info: |
|
btc.blockr_pushtx(i[0],i[1]) |
|
|
|
def test_bci_bad_pushtx(): |
|
inps = [("00000000"), ('\x00'*8)] |
|
for i in inps: |
|
with pytest.raises(Exception) as e_info: |
|
btc.bci_pushtx(i[0]) |
|
|
|
def test_blockr_estimate_fee(setup_blockr): |
|
res = [] |
|
for N in [1,3,6]: |
|
res.append(jm_single().bc_interface.estimate_fee_per_kb(N)) |
|
assert res[0] >= res[2] |
|
#Note this can fail, it isn't very accurate. |
|
#assert res[1] >= res[2] |
|
#sanity checks: |
|
assert res[0] < 200000 |
|
assert res[2] < 150000 |
|
|
|
@pytest.mark.parametrize( |
|
"net, seed, gaplimit, showprivkey, method", |
|
[ |
|
("testnet", |
|
#Dont take these testnet coins, itll botch up our tests!! |
|
"I think i did pretty good with Christmas", |
|
6, |
|
True, |
|
#option "displayall" here will show all addresses from beginning |
|
"display"), |
|
]) |
|
def test_blockr_sync(setup_blockr, net, seed, gaplimit, showprivkey, method): |
|
jm_single().config.set("BLOCKCHAIN", "network", net) |
|
wallet = Wallet(seed, None, max_mix_depth = 5) |
|
sync_wallet(wallet) |
|
|
|
#copy pasted from wallet-tool; some boiled down form of |
|
#this should really be in wallet.py in the joinmarket module. |
|
def cus_print(s): |
|
print s |
|
|
|
total_balance = 0 |
|
for m in range(wallet.max_mix_depth): |
|
cus_print('mixing depth %d m/0/%d/' % (m, m)) |
|
balance_depth = 0 |
|
for forchange in [0, 1]: |
|
cus_print(' ' + ('external' if forchange == 0 else 'internal') + |
|
' addresses m/0/%d/%d/' % (m, forchange)) |
|
|
|
for k in range(wallet.index[m][forchange] + gaplimit): |
|
addr = wallet.get_addr(m, forchange, k) |
|
balance = 0.0 |
|
for addrvalue in wallet.unspent.values(): |
|
if addr == addrvalue['address']: |
|
balance += addrvalue['value'] |
|
balance_depth += balance |
|
used = ('used' if k < wallet.index[m][forchange] else ' new') |
|
if showprivkey: |
|
privkey = btc.wif_compressed_privkey( |
|
wallet.get_key(m, forchange, k), get_p2pk_vbyte()) |
|
else: |
|
privkey = '' |
|
if (method == 'displayall' or balance > 0 or |
|
(used == ' new' and forchange == 0)): |
|
cus_print(' m/0/%d/%d/%03d %-35s%s %.8f btc %s' % |
|
(m, forchange, k, addr, used, balance / 1e8, |
|
privkey)) |
|
total_balance += balance_depth |
|
print('for mixdepth=%d balance=%.8fbtc' % (m, balance_depth / 1e8)) |
|
assert total_balance == 96085297 |
|
|
|
@patch('jmbitcoin.bci.make_request') |
|
def test_blockr_error_429(make_request): |
|
error = {u'code': 429, |
|
u'data': None, |
|
u'message': u'Too many requests. Wait a bit...', |
|
u'status': u'error'} |
|
success = {u'code': 200, |
|
u'data': {u'address': u'mqG1k82TDWfxSYFyDRkomjYonDUYjPRbsb', |
|
u'limit_txs': 200, |
|
u'nb_txs': 1, |
|
u'nb_txs_displayed': 1, |
|
u'txs': [{u'amount': 1, |
|
u'amount_multisig': 0, |
|
u'confirmations': 400, |
|
u'time_utc': u'2016-09-15T19:46:14Z', |
|
u'tx': u'6a1bfbdd011cbb2ab2a000d477bd6372150238b4c24e43a850220dba4dbf2c0d'}]}, |
|
u'message': u'', |
|
u'status': u'success'} |
|
make_request.side_effect = map(json.dumps, [error]*3 + [success]) |
|
|
|
d = btc.make_request_blockr(blockr_root_url + "address/txs/", "mqG1k82TDWfxSYFyDRkomjYonDUYjPRbsb") |
|
assert d['code'] == 200 |
|
assert d['data'] is not None |
|
|
|
|
|
@pytest.fixture(scope="module") |
|
def setup_blockr(request): |
|
def blockr_teardown(): |
|
jm_single().config.set("BLOCKCHAIN", "blockchain_source", "regtest") |
|
jm_single().config.set("BLOCKCHAIN", "network", "testnet") |
|
request.addfinalizer(blockr_teardown) |
|
load_program_config() |
|
jm_single().config.set("BLOCKCHAIN", "blockchain_source", "blockr") |
|
jm_single().bc_interface = BlockrInterface(True)
|
|
|