Got outline of tests for squeak core methods (#1562)

* Got outline of tests for squeak core methods

* Split squeak core test fixtures into seller and buyer

* Add unit tests for decrypt content from sent payment in squeak core
This commit is contained in:
Jonathan Zernik 2021-10-11 18:22:20 -07:00 committed by GitHub
parent f49874c1e6
commit 0f11eb4f99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 196 additions and 49 deletions

View file

@ -151,7 +151,14 @@ class SqueakCore:
block_info = self.bitcoin_client.get_best_block_info()
return block_info.block_height
def create_offer(self, squeak: CSqueak, secret_key: bytes, peer_address: PeerAddress, price_msat: int) -> SentOffer:
def create_offer(
self,
squeak: CSqueak,
secret_key: bytes,
peer_address: PeerAddress,
price_msat: int,
nonce: bytes = None,
) -> SentOffer:
"""Creates an offer to sell a squeak key to another node.
Args:
@ -166,7 +173,8 @@ class SqueakCore:
# Get the squeak hash
squeak_hash = get_hash(squeak)
# Generate a new random nonce
nonce = generate_tweak()
if nonce is None:
nonce = generate_tweak()
# Calculate the preimage
preimage = add_tweak(secret_key, nonce)
# Create the lightning invoice

View file

@ -26,11 +26,16 @@ from squeaknode.bitcoin.block_info import BlockInfo
from squeaknode.core.lightning_address import LightningAddressHostPort
from squeaknode.core.peer_address import Network
from squeaknode.core.peer_address import PeerAddress
from squeaknode.core.secret_keys import add_tweak
from squeaknode.core.secret_keys import generate_tweak
from squeaknode.core.squeak_core import SqueakCore
from squeaknode.core.squeaks import get_hash
from squeaknode.lightning.info import Info
from squeaknode.lightning.invoice import Invoice
from squeaknode.lightning.lightning_client import LightningClient
from tests.utils import gen_random_hash
from squeaknode.lightning.pay_req import PayReq
from squeaknode.lightning.payment import Payment
from tests.utils import sha256
@pytest.fixture
@ -44,15 +49,19 @@ def price_msat():
@pytest.fixture
def preimage():
# TODO: This should be generated from the tweak of the decryption key.
yield gen_random_hash()
def nonce():
yield generate_tweak()
@pytest.fixture
def preimage(secret_key, nonce):
yield add_tweak(secret_key, nonce)
@pytest.fixture
def payment_hash(preimage):
# TODO: This should be the hash of the preimage
yield gen_random_hash()
# TODO: When PTLC is used, this should be the payment point of preimage.
yield sha256(preimage)
@pytest.fixture
@ -65,13 +74,38 @@ def creation_date():
yield 777777
@pytest.fixture
def timestamp():
yield 8888888
@pytest.fixture
def expiry():
yield 5555
@pytest.fixture
def invoice(payment_hash, payment_request, price_msat, creation_date, expiry):
def seller_pubkey():
yield "fake_seller_pubkey"
@pytest.fixture
def uris():
yield [
'fake_pubkey@foobar.com:12345',
'fake_pubkey@fakehost.com:56789',
]
@pytest.fixture
def info(uris):
yield Info(
uris=uris,
)
@pytest.fixture
def invoice(payment_request, price_msat, creation_date, expiry):
yield Invoice(
r_hash=payment_hash,
payment_request=payment_request,
@ -83,6 +117,40 @@ def invoice(payment_hash, payment_request, price_msat, creation_date, expiry):
)
@pytest.fixture
def pay_req(
payment_hash,
price_msat,
payment_request,
seller_pubkey,
timestamp,
expiry,
):
yield PayReq(
payment_hash=payment_hash,
num_msat=price_msat,
destination=seller_pubkey,
timestamp=timestamp,
expiry=expiry,
)
@pytest.fixture
def successful_payment(preimage):
yield Payment(
payment_preimage=preimage,
payment_error='',
)
@pytest.fixture
def failed_payment(payment_request):
yield Payment(
payment_preimage=b'',
payment_error='Payment failed.',
)
class MockBitcoinClient(BitcoinClient):
def __init__(self, best_block_info):
@ -112,20 +180,23 @@ class MockBitcoinClient(BitcoinClient):
class MockLightningClient(LightningClient):
def __init__(self, invoice):
def __init__(self, info, invoice, pay_req, payment):
self.info = info
self.invoice = invoice
self.pay_req = pay_req
self.payment = payment
def get_info(self):
pass
return self.info
def create_invoice(self, preimage: bytes, amount_msat: int):
return self.invoice
def decode_pay_req(self, payment_request: str):
pass
return self.pay_req
def pay_invoice(self, payment_request: str):
pass
return self.payment
def subscribe_invoices(self, settle_index: int):
pass
@ -137,8 +208,8 @@ def bitcoin_client(genesis_block_info):
@pytest.fixture
def lightning_client(invoice):
return MockLightningClient(invoice)
def lightning_client(info, invoice, pay_req, successful_payment):
return MockLightningClient(info, invoice, pay_req, successful_payment)
@pytest.fixture
@ -146,24 +217,24 @@ def squeak_core(bitcoin_client, lightning_client):
yield SqueakCore(bitcoin_client, lightning_client)
@pytest.fixture
def squeak_and_decryption_key(squeak_core, signing_profile, squeak_content):
yield squeak_core.make_squeak(
signing_profile,
squeak_content,
)
# @pytest.fixture
# def squeak_and_decryption_key(squeak_core, signing_profile, squeak_content):
# yield squeak_core.make_squeak(
# signing_profile,
# squeak_content,
# )
@pytest.fixture
def squeak(squeak_and_decryption_key):
squeak, _ = squeak_and_decryption_key
yield squeak
# @pytest.fixture
# def squeak(squeak_and_decryption_key):
# squeak, _ = squeak_and_decryption_key
# yield squeak
@pytest.fixture
def decryption_key(squeak_and_decryption_key):
_, decryption_key = squeak_and_decryption_key
yield decryption_key
# @pytest.fixture
# def decryption_key(squeak_and_decryption_key):
# _, decryption_key = squeak_and_decryption_key
# yield decryption_key
@pytest.fixture
@ -175,6 +246,56 @@ def peer_address():
)
@pytest.fixture
def seller_peer_address():
yield PeerAddress(
network=Network.IPV4,
host="fake_seller_host",
port=4321,
)
@pytest.fixture
def created_offer(squeak_core, squeak, secret_key, peer_address, price_msat, nonce):
yield squeak_core.create_offer(
squeak,
secret_key,
peer_address,
price_msat,
nonce,
)
@pytest.fixture
def packaged_offer(squeak_core, created_offer):
yield squeak_core.package_offer(created_offer, None)
@pytest.fixture
def unpacked_offer(squeak_core, squeak, packaged_offer, seller_peer_address):
yield squeak_core.unpack_offer(squeak, packaged_offer, seller_peer_address)
@pytest.fixture
def sent_payment(squeak_core, unpacked_offer):
yield squeak_core.pay_offer(unpacked_offer)
def test_make_squeak(
squeak_core,
signing_profile,
squeak_content,
):
created_squeak, created_secret_key = squeak_core.make_squeak(
signing_profile, squeak_content)
decrypted_created_content = squeak_core.get_decrypted_content(
created_squeak,
created_secret_key,
)
assert decrypted_created_content == squeak_content
def test_get_block_header(
squeak_core,
squeak,
@ -185,13 +306,8 @@ def test_get_block_header(
assert block_header == genesis_block_info.block_header
def test_get_decrypted_content(squeak_core, squeak, decryption_key, squeak_content):
decrypted_content = squeak_core.get_decrypted_content(
squeak,
decryption_key,
)
assert decrypted_content == squeak_content
def test_check_squeak(squeak_core, squeak):
squeak_core.check_squeak(squeak)
def test_get_best_block_height(squeak_core, genesis_block_info):
@ -200,19 +316,37 @@ def test_get_best_block_height(squeak_core, genesis_block_info):
assert best_block_height == genesis_block_info.block_height
def test_create_offer(squeak_core, squeak, decryption_key, peer_address, price_msat, invoice):
created_sent_offer = squeak_core.create_offer(
def test_create_offer(squeak, peer_address, price_msat, created_offer, invoice):
assert created_offer.squeak_hash == get_hash(squeak)
assert created_offer.payment_hash == invoice.r_hash
# assert created_offer.secret_key == secret_key
assert created_offer.price_msat == price_msat
assert created_offer.payment_request == invoice.payment_request
assert created_offer.invoice_time == invoice.creation_date
assert created_offer.invoice_expiry == invoice.expiry
assert created_offer.peer_address == peer_address
def test_packaged_offer(squeak, packaged_offer):
assert packaged_offer is not None
def test_unpacked_offer(unpacked_offer):
assert unpacked_offer is not None
def test_sent_payment(sent_payment):
assert sent_payment is not None
def test_unlock_squeak(squeak_core, squeak, squeak_content, sent_payment):
decrypted_content = squeak_core.get_decrypted_content(
squeak,
decryption_key,
peer_address,
price_msat,
sent_payment.secret_key,
)
assert created_sent_offer.squeak_hash == get_hash(squeak)
assert created_sent_offer.payment_hash == invoice.r_hash
# assert created_sent_offer.secret_key == decryption_key
assert created_sent_offer.price_msat == price_msat
assert created_sent_offer.payment_request == invoice.payment_request
assert created_sent_offer.invoice_time == invoice.creation_date
assert created_sent_offer.invoice_expiry == invoice.expiry
assert created_sent_offer.peer_address == peer_address
assert decrypted_content == squeak_content

View file

@ -19,6 +19,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import hashlib
import os
import uuid
@ -40,6 +41,10 @@ def gen_random_hash():
return os.urandom(HASH_LENGTH)
def sha256(data):
return hashlib.sha256(data).digest()
def address_from_signing_key(signing_key):
verifying_key = signing_key.get_verifying_key()
return CSqueakAddress.from_verifying_key(verifying_key)