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 requests
from time import sleep
from threading import Thread
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')
def run_bitcoind():
bitcoind_thread = Thread(target=run_simulator)
bitcoind_thread = Thread(target=run_simulator, kwargs={"mode": "event"})
bitcoind_thread.daemon = True
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)
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 pytest
import time
import requests
from hashlib import sha256
from binascii import unhexlify
from apps.cli.blob import Blob
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 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
logging.getLogger().disabled = True
PISA_API = "http://{}:{}".format(HOST, PORT)
MULTIPLE_APPOINTMENTS = 10
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)
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}
cipher = "AES-GCM-128"
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)
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"),
"encrypted_blob": encrypted_blob, "cipher": cipher, "hash_function": hash_function}
return appointment
return appointment, dispute_tx
@pytest.fixture
def new_appointment(dispute_txid=None):
appointment = create_appointment(dispute_txid)
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
def new_appointment():
appointment, dispute_tx = generate_dummy_appointment()
locator_dispute_tx_map[appointment["locator"]] = dispute_tx
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))
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:
bitcoin_cli.sendrawtransaction(dispute_txid)
bitcoin_cli.sendrawtransaction(dispute_tx)
# Wait a bit for them to get confirmed
time.sleep(TIME_BETWEEN_BLOCKS)
generate_block()
# Get all appointments
r = requests.get(url=PISA_API + "/get_all_appointments")

View File

@@ -1,11 +1,13 @@
import pytest
import logging
from os import urandom
from time import sleep
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 test2.simulator.bitcoind_sim import TIME_BETWEEN_BLOCKS
logging.getLogger().disabled = True
@@ -24,23 +26,28 @@ def carrier():
def test_send_transaction(run_bitcoind, carrier):
# We are mocking bitcoind and in our simulator txid == tx
tx = urandom(32).hex()
receipt = carrier.send_transaction(tx, tx)
tx = TX.create_dummy_transaction()
txid = sha256d(tx)
receipt = carrier.send_transaction(tx, txid)
assert(receipt.delivered is True)
def test_send_double_spending_transaction(carrier):
# We can test what happens if the same transaction is sent twice
tx = urandom(32).hex()
receipt = carrier.send_transaction(tx, tx)
sent_txs.append(tx)
tx = TX.create_dummy_transaction()
txid = sha256d(tx)
receipt = carrier.send_transaction(tx, txid)
sent_txs.append(txid)
# Wait for a block to be mined
sleep(2*TIME_BETWEEN_BLOCKS)
for _ in range(2):
generate_block()
# 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
# (either by himself or someone else)
@@ -51,8 +58,9 @@ def test_send_double_spending_transaction(carrier):
def test_send_transaction_invalid_format(carrier):
# Test sending a transaction that does not fits the format
tx = urandom(31).hex()
receipt = carrier.send_transaction(tx, tx)
tx = TX.create_dummy_transaction()
txid = sha256d(tx)
receipt = carrier.send_transaction(txid, txid)
assert (receipt.delivered is False and receipt.reason == RPC_DESERIALIZATION_ERROR)

View File

@@ -1,5 +1,4 @@
from os import urandom
from cryptography.exceptions import InvalidTag
from pisa import logging
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 can_connect_to_bitcoind, in_correct_network

View File

@@ -1,22 +1,25 @@
import pytest
import logging
from os import urandom
from time import sleep
from uuid import uuid4
from hashlib import sha256
from threading import Thread
from binascii import unhexlify
from queue import Queue, Empty
from apps.cli.blob import Blob
from pisa.watcher import Watcher
from pisa.responder import Responder
from pisa.conf import MAX_APPOINTMENTS
from pisa.appointment import Appointment
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 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
logging.getLogger().disabled = True
APPOINTMENTS = 5
START_TIME_OFFSET = 1
END_TIME_OFFSET = 1
@@ -27,37 +30,44 @@ def 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))
if locator is None:
locator = urandom(32).hex()
dispute_tx = TX.create_dummy_transaction()
dispute_txid = sha256d(dispute_tx)
justice_tx = TX.create_dummy_transaction(dispute_txid)
start_time = bitcoin_cli.getblockcount() + 1
end_time = start_time + 1
dispute_delta = 20
encrypted_blob_data = urandom(100).hex()
cipher = "AES-GCM-128"
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):
locator_uuid_map = dict()
appointments = dict()
txids = []
dispute_txs = []
for i in range(n):
txid = urandom(32)
appointment, dispute_tx = generate_dummy_appointment()
uuid = uuid4().hex
locator = sha256(txid).hexdigest()
appointments[uuid] = create_appointment(locator)
locator_uuid_map[locator] = [uuid]
txids.append(txid.hex())
appointments[uuid] = appointment
locator_uuid_map[appointment.locator] = [uuid]
dispute_txs.append(dispute_tx)
return appointments, locator_uuid_map, txids
return appointments, locator_uuid_map, dispute_txs
def test_init(watcher):
@@ -71,13 +81,14 @@ def test_init(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.
watcher.asleep = False
# We should be able to add appointments up to the limit
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
@@ -87,11 +98,13 @@ def test_add_too_many_appointments(watcher):
watcher.appointments = dict()
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
added_appointment = watcher.add_appointment(create_appointment())
appointment, dispute_tx = generate_dummy_appointment()
added_appointment = watcher.add_appointment(appointment)
assert added_appointment is False
@@ -104,7 +117,8 @@ def test_do_subscribe(watcher):
zmq_thread.start()
try:
block_hash = watcher.block_queue.get(timeout=MAX_APPOINTMENTS)
generate_block()
block_hash = watcher.block_queue.get()
assert check_txid_format(block_hash)
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))
# 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.daemon = True
watch_thread.start()
# Broadcast the first two
for txid in txids[:2]:
bitcoin_cli.sendrawtransaction(txid)
for dispute_tx in dispute_txs[:2]:
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
# 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
# The rest of appointments will timeout after the end (2) + EXPIRY_DELTA
# 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 watcher.asleep is True