Update tests to use bitcoind_sim event-wise

Also clean son unused imports
This commit is contained in:
Sergi Delgado Segura
2019-10-17 19:08:34 +01:00
parent 1643a7b887
commit 6735aac094
6 changed files with 91 additions and 63 deletions

View File

@@ -1,14 +1,15 @@
import pytest import pytest
import requests
from time import sleep from time import sleep
from threading import Thread from threading import Thread
from pisa.api import start_api from pisa.api import start_api
from test2.simulator.bitcoind_sim import run_simulator from test.simulator.bitcoind_sim import run_simulator, HOST, PORT
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def run_bitcoind(): def run_bitcoind():
bitcoind_thread = Thread(target=run_simulator) bitcoind_thread = Thread(target=run_simulator, kwargs={"mode": "event"})
bitcoind_thread.daemon = True bitcoind_thread.daemon = True
bitcoind_thread.start() bitcoind_thread.start()
@@ -24,3 +25,10 @@ def run_api():
# It takes a little bit of time to start the API (otherwise the requests are sent too early and they fail) # It takes a little bit of time to start the API (otherwise the requests are sent too early and they fail)
sleep(0.1) sleep(0.1)
def generate_block():
requests.post(url="http://{}:{}/generate".format(HOST, PORT), timeout=5)
sleep(0.5)

View File

@@ -1,37 +1,42 @@
import os
import json import json
import pytest import pytest
import time
import requests import requests
from hashlib import sha256 from hashlib import sha256
from binascii import unhexlify from binascii import unhexlify
from apps.cli.blob import Blob from apps.cli.blob import Blob
from pisa import HOST, PORT, logging from pisa import HOST, PORT, logging
from test.simulator.utils import sha256d
from test.simulator.transaction import TX
from test.unit.conftest import generate_block
from pisa.utils.auth_proxy import AuthServiceProxy from pisa.utils.auth_proxy import AuthServiceProxy
from test2.simulator.bitcoind_sim import TIME_BETWEEN_BLOCKS, create_dummy_transaction
from pisa.conf import BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT, MAX_APPOINTMENTS from pisa.conf import BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT, MAX_APPOINTMENTS
logging.getLogger().disabled = True logging.getLogger().disabled = True
PISA_API = "http://{}:{}".format(HOST, PORT) PISA_API = "http://{}:{}".format(HOST, PORT)
MULTIPLE_APPOINTMENTS = 10 MULTIPLE_APPOINTMENTS = 10
appointments = [] appointments = []
locator_dispute_txid_map = {} locator_dispute_tx_map = {}
def generate_dummy_appointment(dispute_txid): def generate_dummy_appointment():
r = requests.get(url=PISA_API + '/get_block_count', timeout=5) r = requests.get(url=PISA_API + '/get_block_count', timeout=5)
current_height = r.json().get("block_count") current_height = r.json().get("block_count")
dummy_appointment_data = {"tx": create_dummy_transaction(), "tx_id": dispute_txid, "start_time": current_height + 5, dispute_tx = TX.create_dummy_transaction()
dispute_txid = sha256d(dispute_tx)
justice_tx = TX.create_dummy_transaction(dispute_txid)
dummy_appointment_data = {"tx": justice_tx, "tx_id": dispute_txid, "start_time": current_height + 5,
"end_time": current_height + 30, "dispute_delta": 20} "end_time": current_height + 30, "dispute_delta": 20}
cipher = "AES-GCM-128" cipher = "AES-GCM-128"
hash_function = "SHA256" hash_function = "SHA256"
locator = sha256(unhexlify(dummy_appointment_data.get("tx_id"))).hexdigest() locator = sha256(unhexlify(dispute_txid)).hexdigest()
blob = Blob(dummy_appointment_data.get("tx"), cipher, hash_function) blob = Blob(dummy_appointment_data.get("tx"), cipher, hash_function)
encrypted_blob = blob.encrypt((dummy_appointment_data.get("tx_id"))) encrypted_blob = blob.encrypt((dummy_appointment_data.get("tx_id")))
@@ -41,22 +46,13 @@ def generate_dummy_appointment(dispute_txid):
"dispute_delta": dummy_appointment_data.get("dispute_delta"), "dispute_delta": dummy_appointment_data.get("dispute_delta"),
"encrypted_blob": encrypted_blob, "cipher": cipher, "hash_function": hash_function} "encrypted_blob": encrypted_blob, "cipher": cipher, "hash_function": hash_function}
return appointment return appointment, dispute_tx
@pytest.fixture @pytest.fixture
def new_appointment(dispute_txid=None): def new_appointment():
appointment = create_appointment(dispute_txid) appointment, dispute_tx = generate_dummy_appointment()
locator_dispute_tx_map[appointment["locator"]] = dispute_tx
return appointment
def create_appointment(dispute_txid=None):
if dispute_txid is None:
dispute_txid = os.urandom(32).hex()
appointment = generate_dummy_appointment(dispute_txid)
locator_dispute_txid_map[appointment["locator"]] = dispute_txid
return appointment return appointment
@@ -147,12 +143,12 @@ def test_get_all_appointments_responder():
bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT)) bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT))
locators = [appointment["locator"] for appointment in appointments] locators = [appointment["locator"] for appointment in appointments]
for locator, dispute_txid in locator_dispute_txid_map.items(): for locator, dispute_tx in locator_dispute_tx_map.items():
if locator in locators: if locator in locators:
bitcoin_cli.sendrawtransaction(dispute_txid) bitcoin_cli.sendrawtransaction(dispute_tx)
# Wait a bit for them to get confirmed # Wait a bit for them to get confirmed
time.sleep(TIME_BETWEEN_BLOCKS) generate_block()
# Get all appointments # Get all appointments
r = requests.get(url=PISA_API + "/get_all_appointments") r = requests.get(url=PISA_API + "/get_all_appointments")

View File

@@ -1,11 +1,13 @@
import pytest import pytest
import logging import logging
from os import urandom from os import urandom
from time import sleep
from pisa.carrier import Carrier from pisa.carrier import Carrier
from test.simulator.utils import sha256d
from test.simulator.transaction import TX
from test.unit.conftest import generate_block
from pisa.rpc_errors import RPC_VERIFY_ALREADY_IN_CHAIN, RPC_DESERIALIZATION_ERROR from pisa.rpc_errors import RPC_VERIFY_ALREADY_IN_CHAIN, RPC_DESERIALIZATION_ERROR
from test2.simulator.bitcoind_sim import TIME_BETWEEN_BLOCKS
logging.getLogger().disabled = True logging.getLogger().disabled = True
@@ -24,23 +26,28 @@ def carrier():
def test_send_transaction(run_bitcoind, carrier): def test_send_transaction(run_bitcoind, carrier):
# We are mocking bitcoind and in our simulator txid == tx # We are mocking bitcoind and in our simulator txid == tx
tx = urandom(32).hex() tx = TX.create_dummy_transaction()
receipt = carrier.send_transaction(tx, tx) txid = sha256d(tx)
receipt = carrier.send_transaction(tx, txid)
assert(receipt.delivered is True) assert(receipt.delivered is True)
def test_send_double_spending_transaction(carrier): def test_send_double_spending_transaction(carrier):
# We can test what happens if the same transaction is sent twice # We can test what happens if the same transaction is sent twice
tx = urandom(32).hex() tx = TX.create_dummy_transaction()
receipt = carrier.send_transaction(tx, tx) txid = sha256d(tx)
sent_txs.append(tx)
receipt = carrier.send_transaction(tx, txid)
sent_txs.append(txid)
# Wait for a block to be mined # Wait for a block to be mined
sleep(2*TIME_BETWEEN_BLOCKS) for _ in range(2):
generate_block()
# Try to send it again # Try to send it again
receipt2 = carrier.send_transaction(tx, tx) receipt2 = carrier.send_transaction(tx, txid)
# The carrier should report delivered True for both, but in the second case the transaction was already delivered # The carrier should report delivered True for both, but in the second case the transaction was already delivered
# (either by himself or someone else) # (either by himself or someone else)
@@ -51,8 +58,9 @@ def test_send_double_spending_transaction(carrier):
def test_send_transaction_invalid_format(carrier): def test_send_transaction_invalid_format(carrier):
# Test sending a transaction that does not fits the format # Test sending a transaction that does not fits the format
tx = urandom(31).hex() tx = TX.create_dummy_transaction()
receipt = carrier.send_transaction(tx, tx) txid = sha256d(tx)
receipt = carrier.send_transaction(txid, txid)
assert (receipt.delivered is False and receipt.reason == RPC_DESERIALIZATION_ERROR) assert (receipt.delivered is False and receipt.reason == RPC_DESERIALIZATION_ERROR)

View File

@@ -1,5 +1,4 @@
from os import urandom from os import urandom
from cryptography.exceptions import InvalidTag
from pisa import logging from pisa import logging
from pisa.encrypted_blob import EncryptedBlob from pisa.encrypted_blob import EncryptedBlob

View File

@@ -1,4 +1,4 @@
from pisa import logging, bitcoin_cli from pisa import logging
from pisa.tools import check_txid_format from pisa.tools import check_txid_format
from pisa.tools import can_connect_to_bitcoind, in_correct_network from pisa.tools import can_connect_to_bitcoind, in_correct_network

View File

@@ -1,22 +1,25 @@
import pytest import pytest
import logging import logging
from os import urandom
from time import sleep
from uuid import uuid4 from uuid import uuid4
from hashlib import sha256 from hashlib import sha256
from threading import Thread from threading import Thread
from binascii import unhexlify
from queue import Queue, Empty from queue import Queue, Empty
from apps.cli.blob import Blob
from pisa.watcher import Watcher from pisa.watcher import Watcher
from pisa.responder import Responder from pisa.responder import Responder
from pisa.conf import MAX_APPOINTMENTS from pisa.conf import MAX_APPOINTMENTS
from pisa.appointment import Appointment from pisa.appointment import Appointment
from pisa.tools import check_txid_format from pisa.tools import check_txid_format
from test.simulator.utils import sha256d
from test.simulator.transaction import TX
from test.unit.conftest import generate_block
from pisa.utils.auth_proxy import AuthServiceProxy from pisa.utils.auth_proxy import AuthServiceProxy
from test2.simulator.bitcoind_sim import TIME_BETWEEN_BLOCKS
from pisa.conf import EXPIRY_DELTA, BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT from pisa.conf import EXPIRY_DELTA, BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT
logging.getLogger().disabled = True logging.getLogger().disabled = True
APPOINTMENTS = 5 APPOINTMENTS = 5
START_TIME_OFFSET = 1 START_TIME_OFFSET = 1
END_TIME_OFFSET = 1 END_TIME_OFFSET = 1
@@ -27,37 +30,44 @@ def watcher():
return Watcher() return Watcher()
def create_appointment(locator=None): def generate_dummy_appointment():
bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT)) bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT))
if locator is None: dispute_tx = TX.create_dummy_transaction()
locator = urandom(32).hex() dispute_txid = sha256d(dispute_tx)
justice_tx = TX.create_dummy_transaction(dispute_txid)
start_time = bitcoin_cli.getblockcount() + 1 start_time = bitcoin_cli.getblockcount() + 1
end_time = start_time + 1 end_time = start_time + 1
dispute_delta = 20 dispute_delta = 20
encrypted_blob_data = urandom(100).hex()
cipher = "AES-GCM-128" cipher = "AES-GCM-128"
hash_function = "SHA256" hash_function = "SHA256"
return Appointment(locator, start_time, end_time, dispute_delta, encrypted_blob_data, cipher, hash_function) locator = sha256(unhexlify(dispute_txid)).hexdigest()
blob = Blob(justice_tx, cipher, hash_function)
encrypted_blob = blob.encrypt(dispute_txid)
appointment = Appointment(locator, start_time, end_time, dispute_delta, encrypted_blob, cipher, hash_function)
return appointment, dispute_tx
def create_appointments(n): def create_appointments(n):
locator_uuid_map = dict() locator_uuid_map = dict()
appointments = dict() appointments = dict()
txids = [] dispute_txs = []
for i in range(n): for i in range(n):
txid = urandom(32) appointment, dispute_tx = generate_dummy_appointment()
uuid = uuid4().hex uuid = uuid4().hex
locator = sha256(txid).hexdigest()
appointments[uuid] = create_appointment(locator) appointments[uuid] = appointment
locator_uuid_map[locator] = [uuid] locator_uuid_map[appointment.locator] = [uuid]
txids.append(txid.hex()) dispute_txs.append(dispute_tx)
return appointments, locator_uuid_map, txids return appointments, locator_uuid_map, dispute_txs
def test_init(watcher): def test_init(watcher):
@@ -71,13 +81,14 @@ def test_init(watcher):
def test_add_appointment(run_bitcoind, watcher): def test_add_appointment(run_bitcoind, watcher):
# The watcher automatically fire do_watch and do_subscribe on adding an appointment if it is asleep (initial state). # The watcher automatically fires do_watch and do_subscribe on adding an appointment if it is asleep (initial state)
# Avoid this by setting the state to awake. # Avoid this by setting the state to awake.
watcher.asleep = False watcher.asleep = False
# We should be able to add appointments up to the limit # We should be able to add appointments up to the limit
for _ in range(10): for _ in range(10):
added_appointment = watcher.add_appointment(create_appointment()) appointment, dispute_tx = generate_dummy_appointment()
added_appointment = watcher.add_appointment(appointment)
assert added_appointment is True assert added_appointment is True
@@ -87,11 +98,13 @@ def test_add_too_many_appointments(watcher):
watcher.appointments = dict() watcher.appointments = dict()
for _ in range(MAX_APPOINTMENTS): for _ in range(MAX_APPOINTMENTS):
added_appointment = watcher.add_appointment(create_appointment()) appointment, dispute_tx = generate_dummy_appointment()
added_appointment = watcher.add_appointment(appointment)
assert added_appointment is True assert added_appointment is True
added_appointment = watcher.add_appointment(create_appointment()) appointment, dispute_tx = generate_dummy_appointment()
added_appointment = watcher.add_appointment(appointment)
assert added_appointment is False assert added_appointment is False
@@ -104,7 +117,8 @@ def test_do_subscribe(watcher):
zmq_thread.start() zmq_thread.start()
try: try:
block_hash = watcher.block_queue.get(timeout=MAX_APPOINTMENTS) generate_block()
block_hash = watcher.block_queue.get()
assert check_txid_format(block_hash) assert check_txid_format(block_hash)
except Empty: except Empty:
@@ -115,25 +129,28 @@ def test_do_watch(watcher):
bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT)) bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT))
# We will wipe all the previous data and add 5 appointments # We will wipe all the previous data and add 5 appointments
watcher.appointments, watcher.locator_uuid_map, txids = create_appointments(APPOINTMENTS) watcher.appointments, watcher.locator_uuid_map, dispute_txs = create_appointments(APPOINTMENTS)
watch_thread = Thread(target=watcher.do_watch) watch_thread = Thread(target=watcher.do_watch)
watch_thread.daemon = True watch_thread.daemon = True
watch_thread.start() watch_thread.start()
# Broadcast the first two # Broadcast the first two
for txid in txids[:2]: for dispute_tx in dispute_txs[:2]:
bitcoin_cli.sendrawtransaction(txid) r = bitcoin_cli.sendrawtransaction(dispute_tx)
# After leaving some time for the block to be mined and processed, the number of appointments should have reduced # After leaving some time for the block to be mined and processed, the number of appointments should have reduced
# by two # by two
sleep(TIME_BETWEEN_BLOCKS*(START_TIME_OFFSET+END_TIME_OFFSET + 1)) for _ in range(START_TIME_OFFSET + END_TIME_OFFSET):
generate_block()
assert len(watcher.appointments) == APPOINTMENTS - 2 assert len(watcher.appointments) == APPOINTMENTS - 2
# The rest of appointments will timeout after the end (2) + EXPIRY_DELTA # The rest of appointments will timeout after the end (2) + EXPIRY_DELTA
# Wait for an additional block to be safe # Wait for an additional block to be safe
sleep((EXPIRY_DELTA + 2 + 1) * TIME_BETWEEN_BLOCKS) for _ in range(EXPIRY_DELTA + START_TIME_OFFSET + END_TIME_OFFSET):
generate_block()
assert len(watcher.appointments) == 0 assert len(watcher.appointments) == 0
assert watcher.asleep is True assert watcher.asleep is True