mirror of
https://github.com/yzernik/squeaknode.git
synced 2026-08-13 12:33:25 +02:00
Use data classes instead of namedtuples (#508)
* Build mypy files for protos in tox env * Include mypy check in make test * Improve building offer from remote peer download * Remove old methods from peer task
This commit is contained in:
parent
462626035c
commit
0a5a54554c
7 changed files with 102 additions and 97 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -18,5 +18,6 @@ dist/
|
|||
# Ignore generated python proto files
|
||||
*pb2.py
|
||||
*pb2_grpc.py
|
||||
*.pyi
|
||||
|
||||
libs/
|
||||
2
Makefile
2
Makefile
|
|
@ -7,11 +7,13 @@ clean:
|
|||
find . -name '*~' -delete
|
||||
find . -name '*pb2_grpc.py' -delete
|
||||
find . -name '*pb2.py' -delete
|
||||
find . -name '*.pyi' -delete
|
||||
make --directory=frontend clean;
|
||||
|
||||
test:
|
||||
tox
|
||||
tox -e codechecks
|
||||
tox -e mypy
|
||||
|
||||
codeformat:
|
||||
tox -e autoflake
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ argparse
|
|||
googleapis-common-protos
|
||||
grpcio
|
||||
grpcio-tools
|
||||
mypy-protobuf
|
||||
psycopg2
|
||||
requests
|
||||
SQLAlchemy
|
||||
|
|
|
|||
44
setup.py
44
setup.py
|
|
@ -1,11 +1,16 @@
|
|||
import io
|
||||
import os
|
||||
import pkg_resources
|
||||
import sys
|
||||
|
||||
import setuptools.command.build_py
|
||||
import setuptools.command.test
|
||||
# from grpc_tools.command import BuildPackageProtos
|
||||
from setuptools import find_packages, setup
|
||||
from setuptools import Command
|
||||
|
||||
from grpc_tools import protoc
|
||||
|
||||
|
||||
PACKAGE_DIRECTORIES = {
|
||||
'': '.',
|
||||
}
|
||||
|
|
@ -22,13 +27,32 @@ class BuildPyCommand(setuptools.command.build_py.build_py):
|
|||
setuptools.command.build_py.build_py.run(self)
|
||||
|
||||
|
||||
# class TestCommand(setuptools.command.test.test):
|
||||
# """Custom test command."""
|
||||
def build_package_protos(package_root, strict_mode=False):
|
||||
proto_files = []
|
||||
inclusion_root = os.path.abspath(package_root)
|
||||
for root, _, files in os.walk(inclusion_root):
|
||||
for filename in files:
|
||||
if filename.endswith('.proto'):
|
||||
proto_files.append(os.path.abspath(os.path.join(root,
|
||||
filename)))
|
||||
|
||||
# def run(self):
|
||||
# print("Running custom test command...")
|
||||
# self.run_command('build_proto_modules')
|
||||
# # setuptools.command.test.test.run(self)
|
||||
well_known_protos_include = pkg_resources.resource_filename(
|
||||
'grpc_tools', '_proto')
|
||||
|
||||
for proto_file in proto_files:
|
||||
command = [
|
||||
'grpc_tools.protoc',
|
||||
'--proto_path={}'.format(inclusion_root),
|
||||
'--proto_path={}'.format(well_known_protos_include),
|
||||
'--python_out={}'.format(inclusion_root),
|
||||
'--grpc_python_out={}'.format(inclusion_root),
|
||||
'--mypy_out={}'.format(inclusion_root),
|
||||
] + [proto_file]
|
||||
if protoc.main(command) != 0:
|
||||
if strict_mode:
|
||||
raise Exception('error: {} failed'.format(command))
|
||||
else:
|
||||
sys.stderr.write('warning: {} failed'.format(command))
|
||||
|
||||
|
||||
class BuildPackageProtos(Command):
|
||||
|
|
@ -44,8 +68,9 @@ class BuildPackageProtos(Command):
|
|||
pass
|
||||
|
||||
def run(self):
|
||||
import grpc_tools.command
|
||||
grpc_tools.command.build_package_protos('.')
|
||||
# import grpc_tools.command
|
||||
# grpc_tools.command.build_package_protos('.')
|
||||
build_package_protos('.')
|
||||
|
||||
setup(
|
||||
name="squeaknode",
|
||||
|
|
@ -66,6 +91,5 @@ setup(
|
|||
cmdclass={
|
||||
'build_proto_modules': BuildPackageProtos,
|
||||
'build_py': BuildPyCommand,
|
||||
# 'test': TestCommand,
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
from collections import namedtuple
|
||||
from dataclasses import dataclass
|
||||
|
||||
Offer = namedtuple(
|
||||
"Offer",
|
||||
[
|
||||
"offer_id",
|
||||
"squeak_hash",
|
||||
"price_msat",
|
||||
"payment_hash",
|
||||
"nonce",
|
||||
"payment_point",
|
||||
"invoice_timestamp",
|
||||
"invoice_expiry",
|
||||
"payment_request",
|
||||
"destination",
|
||||
"node_host",
|
||||
"node_port",
|
||||
"peer_id",
|
||||
],
|
||||
)
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class Offer:
|
||||
"""Class for saving an offer from a remote peer."""
|
||||
offer_id: Optional[int]
|
||||
squeak_hash: str
|
||||
price_msat: bytes
|
||||
payment_hash: str
|
||||
nonce: str
|
||||
payment_point: str
|
||||
invoice_timestamp: int
|
||||
invoice_expiry: int
|
||||
payment_request: str
|
||||
destination: str
|
||||
node_host: str
|
||||
node_port: int
|
||||
peer_id: int
|
||||
|
|
|
|||
|
|
@ -149,7 +149,45 @@ class PeerSyncTask:
|
|||
squeak = self._get_local_squeak(squeak_hash)
|
||||
|
||||
# Download the buy offer
|
||||
offer = self._download_buy_offer(squeak_hash)
|
||||
offer_msg = self._download_offer_msg(squeak_hash)
|
||||
|
||||
# Decode the payment request
|
||||
pay_req = self._decode_payment_request(offer_msg.payment_request)
|
||||
logger.info("Decoded payment request: {}".format(pay_req))
|
||||
|
||||
# TODO: Use the real payment point, not a fake value.
|
||||
squeak_payment_point = squeak.paymentPoint
|
||||
payment_point = b''
|
||||
payment_hash = bytes.fromhex(pay_req.payment_hash)
|
||||
price_msat = pay_req.num_msat
|
||||
destination = pay_req.destination
|
||||
invoice_timestamp = pay_req.timestamp
|
||||
invoice_expiry = pay_req.expiry
|
||||
node_host = offer_msg.host or self.peer.host
|
||||
node_port = offer_msg.port
|
||||
|
||||
logger.info("price_msat: {}".format(price_msat))
|
||||
logger.info("destination: {}".format(destination))
|
||||
logger.info("invoice_timestamp: {}".format(invoice_timestamp))
|
||||
logger.info("invoice_expiry: {}".format(invoice_expiry))
|
||||
logger.info("node_host: {}".format(node_host))
|
||||
logger.info("node_port: {}".format(node_port))
|
||||
|
||||
decoded_offer = Offer(
|
||||
offer_id=None,
|
||||
squeak_hash=offer_msg.squeak_hash,
|
||||
price_msat=price_msat,
|
||||
payment_hash=payment_hash,
|
||||
nonce=offer_msg.nonce,
|
||||
payment_point=squeak_payment_point,
|
||||
invoice_timestamp=invoice_timestamp,
|
||||
invoice_expiry=invoice_expiry,
|
||||
payment_request=offer_msg.payment_request,
|
||||
destination=destination,
|
||||
node_host=node_host,
|
||||
node_port=node_port,
|
||||
peer_id=self.peer.peer_id,
|
||||
)
|
||||
|
||||
# TODO: Check the payment point
|
||||
# payment_point = offer.payment_point
|
||||
|
|
@ -164,9 +202,6 @@ class PeerSyncTask:
|
|||
# )
|
||||
# )
|
||||
|
||||
# Get the decoded offer from the payment request string
|
||||
decoded_offer = self._get_decoded_offer(offer)
|
||||
|
||||
# Save the offer
|
||||
self._save_offer(decoded_offer)
|
||||
|
||||
|
|
@ -232,75 +267,15 @@ class PeerSyncTask:
|
|||
sharing_profiles = self.squeak_db.get_sharing_profiles()
|
||||
return [profile.address for profile in sharing_profiles]
|
||||
|
||||
def _download_buy_offer(self, squeak_hash):
|
||||
def _download_offer_msg(self, squeak_hash):
|
||||
logger.info(
|
||||
"Downloading buy offer for squeak hash: {}".format(squeak_hash)
|
||||
)
|
||||
offer_msg = self.peer_client.buy_squeak(squeak_hash)
|
||||
offer = self._offer_from_msg(offer_msg)
|
||||
return offer
|
||||
return self.peer_client.buy_squeak(squeak_hash)
|
||||
|
||||
def _save_offer(self, offer):
|
||||
logger.info("Saving offer: {}".format(offer))
|
||||
self.squeak_db.insert_offer(offer)
|
||||
|
||||
def _offer_from_msg(self, offer_msg):
|
||||
if not offer_msg:
|
||||
return None
|
||||
return Offer(
|
||||
offer_id=None,
|
||||
squeak_hash=offer_msg.squeak_hash,
|
||||
price_msat=None,
|
||||
payment_hash=None,
|
||||
nonce=offer_msg.nonce,
|
||||
payment_point=None,
|
||||
invoice_timestamp=None,
|
||||
invoice_expiry=None,
|
||||
payment_request=offer_msg.payment_request,
|
||||
destination=None,
|
||||
node_host=offer_msg.host,
|
||||
node_port=offer_msg.port,
|
||||
peer_id=self.peer.peer_id,
|
||||
)
|
||||
|
||||
def _decode_payment_request(self, payment_request):
|
||||
return self.lightning_client.decode_pay_req(payment_request)
|
||||
|
||||
def _get_decoded_offer(self, offer):
|
||||
pay_req = self._decode_payment_request(offer.payment_request)
|
||||
logger.info("Decoded payment request: {}".format(pay_req))
|
||||
|
||||
# TODO: Use the real payment point, not a fake value.
|
||||
payment_point = b''
|
||||
payment_hash = bytes.fromhex(pay_req.payment_hash)
|
||||
price_msat = pay_req.num_msat
|
||||
destination = pay_req.destination
|
||||
invoice_timestamp = pay_req.timestamp
|
||||
invoice_expiry = pay_req.expiry
|
||||
node_host = offer.node_host or self.peer.host
|
||||
node_port = offer.node_port
|
||||
|
||||
logger.info("price_msat: {}".format(price_msat))
|
||||
logger.info("destination: {}".format(destination))
|
||||
logger.info("invoice_timestamp: {}".format(invoice_timestamp))
|
||||
logger.info("invoice_expiry: {}".format(invoice_expiry))
|
||||
logger.info("node_host: {}".format(node_host))
|
||||
logger.info("node_port: {}".format(node_port))
|
||||
|
||||
decoded_offer = Offer(
|
||||
offer_id=offer.offer_id,
|
||||
squeak_hash=offer.squeak_hash,
|
||||
price_msat=price_msat,
|
||||
payment_hash=payment_hash,
|
||||
nonce=offer.nonce,
|
||||
payment_point=payment_point,
|
||||
invoice_timestamp=invoice_timestamp,
|
||||
invoice_expiry=invoice_expiry,
|
||||
payment_request=offer.payment_request,
|
||||
destination=destination,
|
||||
node_host=node_host,
|
||||
node_port=node_port,
|
||||
peer_id=offer.peer_id,
|
||||
)
|
||||
|
||||
return decoded_offer
|
||||
|
|
|
|||
5
tox.ini
5
tox.ini
|
|
@ -9,6 +9,7 @@ deps =
|
|||
-rrequirements.txt
|
||||
passenv = MY_APP_CONFIG_FILE
|
||||
commands =
|
||||
{envbindir}/python setup.py build_proto_modules
|
||||
py.test {posargs:tests}
|
||||
|
||||
[testenv:coverage]
|
||||
|
|
@ -40,8 +41,8 @@ codechecks_paths =
|
|||
tests
|
||||
itests
|
||||
commands =
|
||||
flake8
|
||||
reorder-python-imports
|
||||
flake8 {posargs:{[testenv:codechecks]codechecks_paths}}
|
||||
reorder-python-imports {posargs:{[testenv:codechecks]codechecks_paths}}
|
||||
|
||||
[testenv:black]
|
||||
basepython = python3.8
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue