mirror of
https://github.com/yzernik/squeaknode.git
synced 2026-08-13 12:33:25 +02:00
Use squeak store to encapsulate all core fns (#2030)
* Revert "Remove usage of squeak_core from squeak_store (#2029)"
This reverts commit bd15c653aa.
* Add make squeak method to squeak store class
* Add pay offer method to squeak store
* Remove squeak_core from controller constructor
* Remove default port param from controller constructor
* Fix broken itests
* Got download single squeak working synchronously
This commit is contained in:
parent
bd15c653aa
commit
bff7bbbc4b
12 changed files with 404 additions and 276 deletions
|
|
@ -18,7 +18,7 @@ rpc_ssl_cert=/rpc/rpc.cert
|
|||
|
||||
[server]
|
||||
external_address=myexternaladdress.com
|
||||
port=8765
|
||||
external_port=8765
|
||||
|
||||
[postgresql]
|
||||
host=db
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ from tests.util import delete_profile
|
|||
from tests.util import delete_squeak
|
||||
from tests.util import download_squeak
|
||||
from tests.util import free_price
|
||||
from tests.util import get_default_peer_port
|
||||
from tests.util import get_external_address
|
||||
from tests.util import get_hash
|
||||
from tests.util import get_network
|
||||
|
|
@ -94,14 +93,6 @@ def test_get_external_address(admin_stub):
|
|||
assert external_address.port == 8765
|
||||
|
||||
|
||||
def test_get_default_peer_port(admin_stub):
|
||||
# Get the default peer port
|
||||
default_peer_port = get_default_peer_port(admin_stub)
|
||||
|
||||
print(default_peer_port)
|
||||
assert default_peer_port == 18777
|
||||
|
||||
|
||||
def test_reprocess_received_payments(admin_stub):
|
||||
# Reprocess received payments
|
||||
reprocess_received_payments_response = admin_stub.ReprocessReceivedPayments(
|
||||
|
|
|
|||
|
|
@ -296,13 +296,6 @@ def get_external_address(node_stub):
|
|||
return get_external_address_response.peer_address
|
||||
|
||||
|
||||
def get_default_peer_port(node_stub):
|
||||
get_default_peer_port_response = node_stub.GetDefaultPeerPort(
|
||||
squeak_admin_pb2.GetDefaultPeerPortRequest()
|
||||
)
|
||||
return get_default_peer_port_response.port
|
||||
|
||||
|
||||
def make_squeak(node_stub, profile_id, squeak_content, reply_to_hash=None, recipient_profile_id=None):
|
||||
make_squeak_response = node_stub.MakeSqueak(
|
||||
squeak_admin_pb2.MakeSqueakRequest(
|
||||
|
|
|
|||
|
|
@ -703,7 +703,7 @@ class SqueakAdminServerHandler(object):
|
|||
author_profile_id,
|
||||
),
|
||||
)
|
||||
self.squeak_controller.unlock_squeak(
|
||||
self.squeak_controller.decrypt_private_squeak(
|
||||
squeak_hash=squeak_hash,
|
||||
author_profile_id=author_profile_id,
|
||||
recipient_profile_id=recipient_profile_id,
|
||||
|
|
|
|||
|
|
@ -20,12 +20,15 @@
|
|||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
import logging
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from concurrent.futures import wait
|
||||
from typing import Optional
|
||||
|
||||
from squeak.core.keys import SqueakPublicKey
|
||||
|
||||
from squeaknode.client.peer_downloader import RangeDownloader
|
||||
from squeaknode.client.peer_downloader import SingleDownloader
|
||||
from squeaknode.node.squeak_store import SqueakStore
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -37,11 +40,11 @@ class NetworkController:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
squeak_controller,
|
||||
squeak_store: SqueakStore,
|
||||
proxy_host: Optional[str],
|
||||
proxy_port: Optional[int],
|
||||
):
|
||||
self.squeak_controller = squeak_controller
|
||||
self.squeak_store = squeak_store
|
||||
self.proxy_host = proxy_host
|
||||
self.proxy_port = proxy_port
|
||||
|
||||
|
|
@ -49,14 +52,14 @@ class NetworkController:
|
|||
self,
|
||||
interest_block_interval: int,
|
||||
) -> None:
|
||||
max_block = self.squeak_controller.get_latest_block()
|
||||
max_block = self.squeak_store.get_latest_block()
|
||||
min_block = max(0, max_block - interest_block_interval)
|
||||
followed_public_keys = self.squeak_controller.get_followed_public_keys()
|
||||
peers = self.squeak_controller.get_autoconnect_peers()
|
||||
followed_public_keys = self.squeak_store.get_followed_public_keys()
|
||||
peers = self.squeak_store.get_autoconnect_peers()
|
||||
for peer in peers:
|
||||
downloader = RangeDownloader(
|
||||
peer,
|
||||
self.squeak_controller,
|
||||
self.squeak_store,
|
||||
self.proxy_host,
|
||||
self.proxy_port,
|
||||
min_block,
|
||||
|
|
@ -68,11 +71,11 @@ class NetworkController:
|
|||
def download_pubkey_squeaks_async(self, pubkey: SqueakPublicKey) -> None:
|
||||
min_block = 0 # TODO
|
||||
max_block = 999999999999 # TODO
|
||||
peers = self.squeak_controller.get_autoconnect_peers()
|
||||
peers = self.squeak_store.get_autoconnect_peers()
|
||||
for peer in peers:
|
||||
downloader = RangeDownloader(
|
||||
peer,
|
||||
self.squeak_controller,
|
||||
self.squeak_store,
|
||||
self.proxy_host,
|
||||
self.proxy_port,
|
||||
min_block,
|
||||
|
|
@ -82,13 +85,20 @@ class NetworkController:
|
|||
downloader.download_async()
|
||||
|
||||
def download_single_squeak(self, squeak_hash: bytes) -> None:
|
||||
peers = self.squeak_controller.get_autoconnect_peers()
|
||||
for peer in peers:
|
||||
downloader = SingleDownloader(
|
||||
peers = self.squeak_store.get_autoconnect_peers()
|
||||
downloaders = [
|
||||
SingleDownloader(
|
||||
peer,
|
||||
self.squeak_controller,
|
||||
self.squeak_store,
|
||||
self.proxy_host,
|
||||
self.proxy_port,
|
||||
squeak_hash,
|
||||
)
|
||||
downloader.download_async()
|
||||
) for peer in peers
|
||||
]
|
||||
with ThreadPoolExecutor(50) as executor:
|
||||
# submit tasks and collect futures
|
||||
futures = [executor.submit(downloader.download)
|
||||
for downloader in downloaders]
|
||||
# wait for all tasks to complete
|
||||
wait(futures)
|
||||
logger.info('All downloads are done!')
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ from squeak.core.keys import SqueakPublicKey
|
|||
from squeaknode.client.peer_client import PeerClient
|
||||
from squeaknode.core.squeak_peer import SqueakPeer
|
||||
from squeaknode.core.squeaks import get_hash
|
||||
from squeaknode.node.squeak_store import SqueakStore
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -44,7 +45,7 @@ class PeerDownloader(ABC):
|
|||
def __init__(
|
||||
self,
|
||||
peer: SqueakPeer,
|
||||
squeak_controller,
|
||||
squeak_store: SqueakStore,
|
||||
proxy_host: Optional[str],
|
||||
proxy_port: Optional[int],
|
||||
):
|
||||
|
|
@ -52,7 +53,7 @@ class PeerDownloader(ABC):
|
|||
self.proxy_host = proxy_host
|
||||
self.proxy_port = proxy_port
|
||||
self.client = PeerClient(peer, proxy_host, proxy_port)
|
||||
self.squeak_controller = squeak_controller
|
||||
self.squeak_store = squeak_store
|
||||
|
||||
@abstractmethod
|
||||
def get_hashes(self) -> List[bytes]:
|
||||
|
|
@ -83,33 +84,33 @@ class PeerDownloader(ABC):
|
|||
|
||||
def get_squeak(self, squeak_hash: bytes) -> None:
|
||||
# Download the squeak if not already owned.
|
||||
if self.squeak_controller.get_squeak(squeak_hash):
|
||||
if self.squeak_store.get_squeak(squeak_hash):
|
||||
return
|
||||
squeak = self.client.get_squeak(squeak_hash)
|
||||
if squeak and self.is_squeak_wanted(squeak):
|
||||
self.squeak_controller.save_squeak(squeak)
|
||||
self.squeak_store.save_squeak(squeak)
|
||||
|
||||
def get_secret_key(self, squeak_hash: bytes) -> None:
|
||||
# Get the squeak from the database.
|
||||
squeak = self.squeak_controller.get_squeak(squeak_hash)
|
||||
squeak = self.squeak_store.get_squeak(squeak_hash)
|
||||
if squeak and self.is_squeak_wanted(squeak):
|
||||
# Download the secret key is not already unlocked.
|
||||
if self.squeak_controller.get_squeak_secret_key(squeak_hash):
|
||||
if self.squeak_store.get_squeak_secret_key(squeak_hash):
|
||||
return
|
||||
secret_key = self.client.get_secret_key(squeak_hash)
|
||||
if secret_key:
|
||||
self.squeak_controller.save_secret_key(squeak_hash, secret_key)
|
||||
self.squeak_store.save_secret_key(squeak_hash, secret_key)
|
||||
|
||||
def get_offer(self, squeak_hash: bytes) -> None:
|
||||
# Get the squeak from the database.
|
||||
squeak = self.squeak_controller.get_squeak(squeak_hash)
|
||||
squeak = self.squeak_store.get_squeak(squeak_hash)
|
||||
if squeak and self.is_squeak_wanted(squeak):
|
||||
# Download the secret key is not already unlocked.
|
||||
if self.squeak_controller.get_squeak_secret_key(squeak_hash):
|
||||
if self.squeak_store.get_squeak_secret_key(squeak_hash):
|
||||
return
|
||||
offer = self.client.get_offer(squeak_hash)
|
||||
if offer:
|
||||
self.squeak_controller.handle_offer(
|
||||
self.squeak_store.handle_offer(
|
||||
squeak,
|
||||
offer,
|
||||
self.peer.address,
|
||||
|
|
@ -121,14 +122,14 @@ class RangeDownloader(PeerDownloader):
|
|||
def __init__(
|
||||
self,
|
||||
peer: SqueakPeer,
|
||||
squeak_controller,
|
||||
squeak_store: SqueakStore,
|
||||
proxy_host: Optional[str],
|
||||
proxy_port: Optional[int],
|
||||
min_block: int,
|
||||
max_block: int,
|
||||
pubkeys: List[SqueakPublicKey],
|
||||
):
|
||||
super().__init__(peer, squeak_controller, proxy_host, proxy_port)
|
||||
super().__init__(peer, squeak_store, proxy_host, proxy_port)
|
||||
self.min_block = min_block
|
||||
self.max_block = max_block
|
||||
self.pubkeys = pubkeys
|
||||
|
|
@ -151,12 +152,12 @@ class SingleDownloader(PeerDownloader):
|
|||
def __init__(
|
||||
self,
|
||||
peer: SqueakPeer,
|
||||
squeak_controller,
|
||||
squeak_store: SqueakStore,
|
||||
proxy_host: Optional[str],
|
||||
proxy_port: Optional[int],
|
||||
squeak_hash: bytes,
|
||||
):
|
||||
super().__init__(peer, squeak_controller, proxy_host, proxy_port)
|
||||
super().__init__(peer, squeak_store, proxy_host, proxy_port)
|
||||
self.squeak_hash = squeak_hash
|
||||
|
||||
def get_hashes(self) -> List[bytes]:
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ from squeak.core import CSqueak
|
|||
from squeak.core.keys import SqueakPrivateKey
|
||||
from squeak.core.keys import SqueakPublicKey
|
||||
|
||||
from squeaknode.client.network_controller import NetworkController
|
||||
from squeaknode.core.download_result import DownloadResult
|
||||
from squeaknode.core.lightning_address import LightningAddressHostPort
|
||||
from squeaknode.core.offer import Offer
|
||||
|
|
@ -37,10 +36,8 @@ from squeaknode.core.peer_address import PeerAddress
|
|||
from squeaknode.core.received_offer import ReceivedOffer
|
||||
from squeaknode.core.received_payment import ReceivedPayment
|
||||
from squeaknode.core.received_payment_summary import ReceivedPaymentSummary
|
||||
from squeaknode.core.sent_offer import SentOffer
|
||||
from squeaknode.core.sent_payment import SentPayment
|
||||
from squeaknode.core.sent_payment_summary import SentPaymentSummary
|
||||
from squeaknode.core.squeak_core import SqueakCore
|
||||
from squeaknode.core.squeak_entry import SqueakEntry
|
||||
from squeaknode.core.squeak_peer import SqueakPeer
|
||||
from squeaknode.core.squeak_profile import SqueakProfile
|
||||
|
|
@ -61,22 +58,19 @@ class SqueakController:
|
|||
def __init__(
|
||||
self,
|
||||
squeak_store: SqueakStore,
|
||||
squeak_core: SqueakCore,
|
||||
payment_processor,
|
||||
tweet_forwarder,
|
||||
network_controller,
|
||||
node_settings,
|
||||
config,
|
||||
):
|
||||
self.squeak_store = squeak_store
|
||||
self.squeak_core = squeak_core
|
||||
self.payment_processor = payment_processor
|
||||
self.tweet_forwarder = tweet_forwarder
|
||||
self.network_controller = network_controller
|
||||
self.node_settings = node_settings
|
||||
self.config = config
|
||||
|
||||
def save_squeak(self, squeak: CSqueak) -> Optional[bytes]:
|
||||
# Get the block header.
|
||||
block_header = self.squeak_core.get_block_header(squeak)
|
||||
return self.squeak_store.save_squeak(squeak, block_header)
|
||||
|
||||
def make_squeak(
|
||||
self,
|
||||
profile_id: int,
|
||||
|
|
@ -84,118 +78,15 @@ class SqueakController:
|
|||
replyto_hash: Optional[bytes],
|
||||
recipient_profile_id: Optional[int],
|
||||
) -> Optional[bytes]:
|
||||
squeak_profile = self.squeak_store.get_squeak_profile(profile_id)
|
||||
if squeak_profile is None:
|
||||
raise Exception("Profile with id {} not found.".format(
|
||||
profile_id,
|
||||
))
|
||||
if recipient_profile_id:
|
||||
recipient_profile = self.squeak_store.get_squeak_profile(
|
||||
recipient_profile_id)
|
||||
if recipient_profile is None:
|
||||
raise Exception("Recipient profile with id {} not found.".format(
|
||||
recipient_profile_id,
|
||||
))
|
||||
squeak, secret_key = self.squeak_core.make_squeak(
|
||||
squeak_profile,
|
||||
return self.squeak_store.make_squeak(
|
||||
profile_id,
|
||||
content_str,
|
||||
replyto_hash,
|
||||
recipient_profile=recipient_profile if recipient_profile_id else None,
|
||||
recipient_profile_id,
|
||||
)
|
||||
inserted_squeak_hash = self.save_squeak(squeak)
|
||||
if inserted_squeak_hash is None:
|
||||
raise Exception("Failed to save squeak.")
|
||||
self.squeak_store.save_secret_key(inserted_squeak_hash, secret_key)
|
||||
if squeak.is_private_message:
|
||||
self.unlock_squeak(
|
||||
inserted_squeak_hash,
|
||||
author_profile_id=profile_id,
|
||||
)
|
||||
else:
|
||||
self.unlock_squeak(
|
||||
inserted_squeak_hash,
|
||||
)
|
||||
return inserted_squeak_hash
|
||||
|
||||
def save_secret_key(self, squeak_hash: bytes, secret_key: bytes):
|
||||
squeak = self.squeak_store.get_squeak(squeak_hash)
|
||||
if squeak is None:
|
||||
raise Exception("Squeakdoes not exist.")
|
||||
self.squeak_store.save_secret_key(squeak_hash, secret_key)
|
||||
if not squeak.is_private_message:
|
||||
self.unlock_squeak(squeak_hash)
|
||||
|
||||
def unlock_squeak(
|
||||
self,
|
||||
squeak_hash: bytes,
|
||||
author_profile_id: Optional[int] = None,
|
||||
recipient_profile_id: Optional[int] = None,
|
||||
):
|
||||
squeak = self.squeak_store.get_squeak(squeak_hash)
|
||||
secret_key = self.squeak_store.get_squeak_secret_key(squeak_hash)
|
||||
if squeak is None:
|
||||
raise Exception("Squeakdoes not exist.")
|
||||
if secret_key is None:
|
||||
raise Exception("Secret key does not exist.")
|
||||
if recipient_profile_id:
|
||||
recipient_profile = self.squeak_store.get_squeak_profile(
|
||||
recipient_profile_id)
|
||||
if recipient_profile is None:
|
||||
raise Exception("Recipient profile does not exist.")
|
||||
decrypted_content = self.squeak_core.get_decrypted_content(
|
||||
squeak,
|
||||
secret_key,
|
||||
recipient_profile=recipient_profile,
|
||||
)
|
||||
elif author_profile_id:
|
||||
author_profile = self.squeak_store.get_squeak_profile(
|
||||
author_profile_id)
|
||||
if author_profile is None:
|
||||
raise Exception("Author profile does not exist.")
|
||||
decrypted_content = self.squeak_core.get_decrypted_content(
|
||||
squeak,
|
||||
secret_key,
|
||||
author_profile=author_profile,
|
||||
)
|
||||
else:
|
||||
decrypted_content = self.squeak_core.get_decrypted_content(
|
||||
squeak,
|
||||
secret_key,
|
||||
)
|
||||
self.squeak_store.set_decrypted_content(
|
||||
squeak_hash,
|
||||
decrypted_content,
|
||||
)
|
||||
logger.info("Unlocked squeak content: {}".format(
|
||||
squeak_hash.hex(),
|
||||
))
|
||||
|
||||
def pay_offer(self, received_offer_id: int) -> int:
|
||||
received_offer = self.squeak_store.get_received_offer(
|
||||
received_offer_id,
|
||||
)
|
||||
if received_offer is None:
|
||||
raise Exception("Received offer with id {} not found.".format(
|
||||
received_offer_id,
|
||||
))
|
||||
squeak = self.squeak_store.get_squeak(received_offer.squeak_hash)
|
||||
if squeak is None:
|
||||
raise Exception("Squeak for received offer with id {} not found.".format(
|
||||
received_offer_id,
|
||||
))
|
||||
logger.info("Paying received offer: {}".format(received_offer))
|
||||
sent_payment = self.squeak_core.pay_offer(received_offer)
|
||||
sent_payment_id = self.squeak_store.save_sent_payment(sent_payment)
|
||||
self.squeak_store.mark_received_offer_paid(
|
||||
sent_payment.payment_hash,
|
||||
)
|
||||
self.squeak_store.save_secret_key(
|
||||
received_offer.squeak_hash,
|
||||
sent_payment.secret_key,
|
||||
)
|
||||
if not squeak.is_private_message:
|
||||
self.unlock_squeak(received_offer.squeak_hash)
|
||||
return sent_payment_id
|
||||
return self.squeak_store.pay_offer(received_offer_id)
|
||||
|
||||
def get_packaged_offer(
|
||||
self,
|
||||
|
|
@ -212,53 +103,24 @@ class SqueakController:
|
|||
price_msat = self.get_sell_price_msat()
|
||||
if price_msat == 0:
|
||||
return None
|
||||
# return self.squeak_store.get_packaged_offer(
|
||||
# squeak_hash,
|
||||
# peer_address,
|
||||
# price_msat,
|
||||
# lnd_external_address,
|
||||
# )
|
||||
sent_offer = self.get_sent_offer_for_peer(
|
||||
return self.squeak_store.get_packaged_offer(
|
||||
squeak_hash,
|
||||
peer_address,
|
||||
price_msat,
|
||||
)
|
||||
if sent_offer is None:
|
||||
return None
|
||||
return self.squeak_core.package_offer(
|
||||
sent_offer,
|
||||
lnd_external_address,
|
||||
)
|
||||
|
||||
def get_sent_offer_for_peer(
|
||||
def decrypt_private_squeak(
|
||||
self,
|
||||
squeak_hash: bytes,
|
||||
peer_address: PeerAddress,
|
||||
price_msat: int,
|
||||
) -> Optional[SentOffer]:
|
||||
# Check if there is an existing offer for the hash/peer_address combination
|
||||
sent_offer = self.squeak_store.get_sent_offer_by_squeak_hash_and_peer(
|
||||
author_profile_id: Optional[int],
|
||||
recipient_profile_id: Optional[int],
|
||||
):
|
||||
self.squeak_store.unlock_squeak(
|
||||
squeak_hash,
|
||||
peer_address,
|
||||
author_profile_id=author_profile_id,
|
||||
recipient_profile_id=recipient_profile_id,
|
||||
)
|
||||
if sent_offer:
|
||||
return sent_offer
|
||||
squeak = self.squeak_store.get_squeak(squeak_hash)
|
||||
secret_key = self.squeak_store.get_squeak_secret_key(squeak_hash)
|
||||
if squeak is None or secret_key is None:
|
||||
return None
|
||||
try:
|
||||
sent_offer = self.squeak_core.create_offer(
|
||||
squeak,
|
||||
secret_key,
|
||||
peer_address,
|
||||
price_msat,
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Failed to create offer.")
|
||||
return None
|
||||
self.squeak_store.save_sent_offer(sent_offer)
|
||||
return sent_offer
|
||||
|
||||
def get_squeak(self, squeak_hash: bytes) -> Optional[CSqueak]:
|
||||
return self.squeak_store.get_squeak(squeak_hash)
|
||||
|
|
@ -314,9 +176,6 @@ class SqueakController:
|
|||
def get_squeak_profile_private_key(self, profile_id: int) -> bytes:
|
||||
return self.squeak_store.get_squeak_profile_private_key(profile_id)
|
||||
|
||||
def get_followed_public_keys(self) -> List[SqueakPublicKey]:
|
||||
return self.squeak_store.get_followed_public_keys()
|
||||
|
||||
def create_peer(self, peer_name: str, peer_address: PeerAddress):
|
||||
return self.squeak_store.create_peer(peer_name, peer_address)
|
||||
|
||||
|
|
@ -344,14 +203,6 @@ class SqueakController:
|
|||
def delete_peer(self, peer_id: int):
|
||||
return self.squeak_store.delete_peer(peer_id)
|
||||
|
||||
def handle_offer(self, squeak: CSqueak, offer: Offer, peer_address: PeerAddress):
|
||||
received_offer = self.squeak_core.unpack_offer(
|
||||
squeak,
|
||||
offer,
|
||||
peer_address,
|
||||
)
|
||||
self.squeak_store.save_received_offer(received_offer)
|
||||
|
||||
def get_received_offers(self, squeak_hash: bytes) -> List[ReceivedOffer]:
|
||||
return self.squeak_store.get_received_offers(squeak_hash)
|
||||
|
||||
|
|
@ -402,12 +253,7 @@ class SqueakController:
|
|||
return self.squeak_store.get_squeak_entry(squeak_hash)
|
||||
|
||||
def download_single_squeak(self, squeak_hash: bytes) -> DownloadResult:
|
||||
network_controller = NetworkController(
|
||||
self,
|
||||
self.config.tor.proxy_ip,
|
||||
self.config.tor.proxy_port,
|
||||
)
|
||||
network_controller.download_single_squeak(squeak_hash)
|
||||
self.network_controller.download_single_squeak(squeak_hash)
|
||||
return DownloadResult(1, 1, 0, 9999)
|
||||
|
||||
def get_timeline_squeak_entries(
|
||||
|
|
@ -450,12 +296,7 @@ class SqueakController:
|
|||
) -> List[SqueakEntry]:
|
||||
# TODO: remove this temporary hack, after converting this to websockets.
|
||||
logger.info('Start downloading pubkey squeaks...')
|
||||
network_controller = NetworkController(
|
||||
self,
|
||||
self.config.tor.proxy_ip,
|
||||
self.config.tor.proxy_port,
|
||||
)
|
||||
network_controller.download_pubkey_squeaks_async(public_key)
|
||||
self.network_controller.download_pubkey_squeaks_async(public_key)
|
||||
logger.info('Finished downloading pubkey squeaks.')
|
||||
return self.squeak_store.get_squeak_entries_for_public_key(
|
||||
public_key,
|
||||
|
|
@ -566,7 +407,7 @@ class SqueakController:
|
|||
)
|
||||
|
||||
def get_default_peer_port(self) -> int:
|
||||
return 0 # TODO: maybe remove this method.
|
||||
return 0 # TODO: remove default port method.
|
||||
|
||||
def set_sell_price_msat(self, sell_price_msat: int) -> None:
|
||||
self.node_settings.set_sell_price_msat(sell_price_msat)
|
||||
|
|
@ -589,7 +430,7 @@ class SqueakController:
|
|||
profile_id,
|
||||
bearer_token,
|
||||
)
|
||||
# self.update_twitter_stream()
|
||||
self.update_twitter_stream()
|
||||
return twitter_account_id
|
||||
|
||||
def get_twitter_accounts(self) -> List[TwitterAccountEntry]:
|
||||
|
|
@ -597,10 +438,7 @@ class SqueakController:
|
|||
|
||||
def delete_twitter_account(self, twitter_account_id: int) -> None:
|
||||
self.squeak_store.delete_twitter_account(twitter_account_id)
|
||||
# self.update_twitter_stream()
|
||||
self.update_twitter_stream()
|
||||
|
||||
# def update_twitter_stream(self) -> None:
|
||||
# self.tweet_forwarder.start_processing()
|
||||
|
||||
def get_latest_block(self) -> int:
|
||||
return self.squeak_core.get_best_block_height()
|
||||
def update_twitter_stream(self) -> None:
|
||||
self.tweet_forwarder.start_processing()
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ class SqueakNode:
|
|||
self.create_squeak_core()
|
||||
self.create_squeak_store()
|
||||
self.create_payment_processor()
|
||||
self.create_squeak_controller()
|
||||
self.create_network_controller()
|
||||
self.create_twitter_forwarder()
|
||||
self.create_network_controller()
|
||||
self.create_squeak_controller()
|
||||
|
||||
self.create_peer_handler()
|
||||
self.create_peer_web_server()
|
||||
|
|
@ -144,6 +144,7 @@ class SqueakNode:
|
|||
def create_squeak_store(self):
|
||||
self.squeak_store = SqueakStore(
|
||||
self.squeak_db,
|
||||
self.squeak_core,
|
||||
self.config.node.max_squeaks,
|
||||
self.config.node.max_squeaks_per_public_key_per_block,
|
||||
self.config.node.squeak_retention_s,
|
||||
|
|
@ -160,27 +161,28 @@ class SqueakNode:
|
|||
|
||||
def create_twitter_forwarder(self):
|
||||
self.twitter_forwarder = TwitterForwarder(
|
||||
self.squeak_controller,
|
||||
self.squeak_store,
|
||||
self.squeak_core,
|
||||
self.config.twitter.forward_tweets_retry_s,
|
||||
)
|
||||
|
||||
def create_network_controller(self):
|
||||
self.network_controller = NetworkController(
|
||||
self.squeak_store,
|
||||
self.config.tor.proxy_ip,
|
||||
self.config.tor.proxy_port,
|
||||
)
|
||||
|
||||
def create_squeak_controller(self):
|
||||
self.squeak_controller = SqueakController(
|
||||
self.squeak_store,
|
||||
self.squeak_core,
|
||||
self.payment_processor,
|
||||
self.twitter_forwarder,
|
||||
self.network_controller,
|
||||
self.node_settings,
|
||||
self.config,
|
||||
)
|
||||
|
||||
def create_network_controller(self):
|
||||
self.network_controller = NetworkController(
|
||||
self.squeak_controller,
|
||||
self.config.tor.proxy_ip,
|
||||
self.config.tor.proxy_port,
|
||||
)
|
||||
|
||||
def create_admin_handler(self):
|
||||
self.admin_handler = SqueakAdminServerHandler(
|
||||
self.lightning_client,
|
||||
|
|
|
|||
|
|
@ -25,13 +25,14 @@ from typing import Iterator
|
|||
from typing import List
|
||||
from typing import Optional
|
||||
|
||||
from bitcoin.core import CBlockHeader
|
||||
from squeak.core import CheckSqueak
|
||||
from squeak.core import CheckSqueakSecretKey
|
||||
from squeak.core import CSqueak
|
||||
from squeak.core.keys import SqueakPrivateKey
|
||||
from squeak.core.keys import SqueakPublicKey
|
||||
|
||||
from squeaknode.core.lightning_address import LightningAddressHostPort
|
||||
from squeaknode.core.offer import Offer
|
||||
from squeaknode.core.peer_address import PeerAddress
|
||||
from squeaknode.core.peers import create_saved_peer
|
||||
from squeaknode.core.profiles import create_contact_profile
|
||||
|
|
@ -43,6 +44,7 @@ from squeaknode.core.received_payment_summary import ReceivedPaymentSummary
|
|||
from squeaknode.core.sent_offer import SentOffer
|
||||
from squeaknode.core.sent_payment import SentPayment
|
||||
from squeaknode.core.sent_payment_summary import SentPaymentSummary
|
||||
from squeaknode.core.squeak_core import SqueakCore
|
||||
from squeaknode.core.squeak_entry import SqueakEntry
|
||||
from squeaknode.core.squeak_peer import SqueakPeer
|
||||
from squeaknode.core.squeak_profile import SqueakProfile
|
||||
|
|
@ -61,6 +63,7 @@ class SqueakStore:
|
|||
def __init__(
|
||||
self,
|
||||
squeak_db: SqueakDb,
|
||||
squeak_core: SqueakCore,
|
||||
max_squeaks,
|
||||
max_squeaks_per_public_key_per_block,
|
||||
squeak_retention_s,
|
||||
|
|
@ -68,6 +71,7 @@ class SqueakStore:
|
|||
sent_offer_retention_s,
|
||||
):
|
||||
self.squeak_db = squeak_db
|
||||
self.squeak_core = squeak_core
|
||||
self.max_squeaks = max_squeaks
|
||||
self.max_squeaks_per_public_key_per_block = max_squeaks_per_public_key_per_block
|
||||
self.squeak_retention_s = squeak_retention_s
|
||||
|
|
@ -79,12 +83,51 @@ class SqueakStore:
|
|||
self.new_follow_listener = EventListener()
|
||||
self.twitter_stream_change_listener = EventListener()
|
||||
|
||||
def save_squeak(self, squeak: CSqueak, block_header: CBlockHeader) -> Optional[bytes]:
|
||||
def make_squeak(
|
||||
self,
|
||||
profile_id: int,
|
||||
content_str: str,
|
||||
replyto_hash: Optional[bytes],
|
||||
recipient_profile_id: Optional[int],
|
||||
) -> Optional[bytes]:
|
||||
squeak_profile = self.get_squeak_profile(profile_id)
|
||||
if squeak_profile is None:
|
||||
raise Exception("Profile with id {} not found.".format(
|
||||
profile_id,
|
||||
))
|
||||
if recipient_profile_id:
|
||||
recipient_profile = self.get_squeak_profile(
|
||||
recipient_profile_id)
|
||||
if recipient_profile is None:
|
||||
raise Exception("Recipient profile with id {} not found.".format(
|
||||
recipient_profile_id,
|
||||
))
|
||||
squeak, secret_key = self.squeak_core.make_squeak(
|
||||
squeak_profile,
|
||||
content_str,
|
||||
replyto_hash,
|
||||
recipient_profile=recipient_profile if recipient_profile_id else None,
|
||||
)
|
||||
inserted_squeak_hash = self.save_squeak(squeak)
|
||||
if inserted_squeak_hash is None:
|
||||
raise Exception("Failed to save squeak.")
|
||||
self.save_secret_key(inserted_squeak_hash, secret_key)
|
||||
if squeak.is_private_message:
|
||||
self.unlock_squeak(
|
||||
inserted_squeak_hash,
|
||||
author_profile_id=profile_id,
|
||||
)
|
||||
return inserted_squeak_hash
|
||||
|
||||
def save_squeak(self, squeak: CSqueak) -> Optional[bytes]:
|
||||
# Check if the squeak is valid context free.
|
||||
CheckSqueak(squeak)
|
||||
# Get the block header.
|
||||
block_header = self.squeak_core.get_block_header(squeak)
|
||||
# Check if limit exceeded.
|
||||
if self.squeak_db.get_number_of_squeaks() >= self.max_squeaks:
|
||||
raise Exception("Exceeded max number of squeaks.")
|
||||
# Check if limit per public key per block is exceeded.
|
||||
# TODO: Check if limit per public key per block is exceeded.
|
||||
if self.squeak_db.number_of_squeaks_with_public_key_with_block_height(
|
||||
squeak.GetPubKey(),
|
||||
squeak.nBlockHeight,
|
||||
|
|
@ -117,12 +160,74 @@ class SqueakStore:
|
|||
squeak_hash.hex(),
|
||||
))
|
||||
self.new_secret_key_listener.handle_new_item(squeak)
|
||||
# Unlock the squeak if it is not private.
|
||||
if not squeak.is_private_message:
|
||||
self.unlock_squeak(squeak_hash)
|
||||
|
||||
def set_decrypted_content(self, squeak_hash: bytes, content: str):
|
||||
def unlock_squeak(
|
||||
self,
|
||||
squeak_hash: bytes,
|
||||
author_profile_id: Optional[int] = None,
|
||||
recipient_profile_id: Optional[int] = None,
|
||||
):
|
||||
squeak = self.squeak_db.get_squeak(squeak_hash)
|
||||
secret_key = self.squeak_db.get_squeak_secret_key(squeak_hash)
|
||||
if squeak is None:
|
||||
raise Exception("Squeakdoes not exist.")
|
||||
if secret_key is None:
|
||||
raise Exception("Secret key does not exist.")
|
||||
if recipient_profile_id:
|
||||
recipient_profile = self.squeak_db.get_profile(
|
||||
recipient_profile_id)
|
||||
if recipient_profile is None:
|
||||
raise Exception("Recipient profile does not exist.")
|
||||
decrypted_content = self.squeak_core.get_decrypted_content(
|
||||
squeak,
|
||||
secret_key,
|
||||
recipient_profile=recipient_profile,
|
||||
)
|
||||
elif author_profile_id:
|
||||
author_profile = self.squeak_db.get_profile(
|
||||
author_profile_id)
|
||||
if author_profile is None:
|
||||
raise Exception("Author profile does not exist.")
|
||||
decrypted_content = self.squeak_core.get_decrypted_content(
|
||||
squeak,
|
||||
secret_key,
|
||||
author_profile=author_profile,
|
||||
)
|
||||
else:
|
||||
decrypted_content = self.squeak_core.get_decrypted_content(
|
||||
squeak,
|
||||
secret_key,
|
||||
)
|
||||
self.squeak_db.set_squeak_decrypted_content(
|
||||
squeak_hash,
|
||||
content,
|
||||
decrypted_content,
|
||||
)
|
||||
logger.info("Unlocked squeak content: {}".format(
|
||||
squeak_hash.hex(),
|
||||
))
|
||||
|
||||
def pay_offer(self, received_offer_id: int) -> int:
|
||||
received_offer = self.get_received_offer(
|
||||
received_offer_id,
|
||||
)
|
||||
if received_offer is None:
|
||||
raise Exception("Received offer with id {} not found.".format(
|
||||
received_offer_id,
|
||||
))
|
||||
logger.info("Paying received offer: {}".format(received_offer))
|
||||
sent_payment = self.squeak_core.pay_offer(received_offer)
|
||||
sent_payment_id = self.save_sent_payment(sent_payment)
|
||||
self.mark_received_offer_paid(
|
||||
sent_payment.payment_hash,
|
||||
)
|
||||
self.save_secret_key(
|
||||
received_offer.squeak_hash,
|
||||
sent_payment.secret_key,
|
||||
)
|
||||
return sent_payment_id
|
||||
|
||||
def get_squeak(self, squeak_hash: bytes) -> Optional[CSqueak]:
|
||||
return self.squeak_db.get_squeak(squeak_hash)
|
||||
|
|
@ -142,6 +247,56 @@ class SqueakStore:
|
|||
def save_sent_offer(self, sent_offer: SentOffer) -> int:
|
||||
return self.squeak_db.insert_sent_offer(sent_offer)
|
||||
|
||||
def get_sent_offer_for_peer(
|
||||
self,
|
||||
squeak_hash: bytes,
|
||||
peer_address: PeerAddress,
|
||||
price_msat: int,
|
||||
) -> Optional[SentOffer]:
|
||||
# Check if there is an existing offer for the hash/peer_address combination
|
||||
sent_offer = self.get_sent_offer_by_squeak_hash_and_peer(
|
||||
squeak_hash,
|
||||
peer_address,
|
||||
)
|
||||
if sent_offer:
|
||||
return sent_offer
|
||||
squeak = self.get_squeak(squeak_hash)
|
||||
secret_key = self.get_squeak_secret_key(squeak_hash)
|
||||
if squeak is None or secret_key is None:
|
||||
return None
|
||||
try:
|
||||
sent_offer = self.squeak_core.create_offer(
|
||||
squeak,
|
||||
secret_key,
|
||||
peer_address,
|
||||
price_msat,
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Failed to create offer.")
|
||||
return None
|
||||
self.save_sent_offer(sent_offer)
|
||||
return sent_offer
|
||||
|
||||
# TODO: remove this method. Do this logic in squeakcontroller.
|
||||
def get_packaged_offer(
|
||||
self,
|
||||
squeak_hash: bytes,
|
||||
peer_address: PeerAddress,
|
||||
price_msat: int,
|
||||
lnd_external_address: Optional[LightningAddressHostPort],
|
||||
) -> Optional[Offer]:
|
||||
sent_offer = self.get_sent_offer_for_peer(
|
||||
squeak_hash,
|
||||
peer_address,
|
||||
price_msat,
|
||||
)
|
||||
if sent_offer is None:
|
||||
return None
|
||||
return self.squeak_core.package_offer(
|
||||
sent_offer,
|
||||
lnd_external_address,
|
||||
)
|
||||
|
||||
def create_signing_profile(self, profile_name: str) -> int:
|
||||
squeak_profile = create_signing_profile(
|
||||
profile_name,
|
||||
|
|
@ -380,6 +535,14 @@ class SqueakStore:
|
|||
self.new_received_offer_listener.handle_new_item(received_offer)
|
||||
return received_offer_id
|
||||
|
||||
def handle_offer(self, squeak: CSqueak, offer: Offer, peer_address: PeerAddress):
|
||||
received_offer = self.squeak_core.unpack_offer(
|
||||
squeak,
|
||||
offer,
|
||||
peer_address,
|
||||
)
|
||||
self.save_received_offer(received_offer)
|
||||
|
||||
def get_followed_public_keys(self) -> List[SqueakPublicKey]:
|
||||
followed_profiles = self.squeak_db.get_following_profiles()
|
||||
return [profile.public_key for profile in followed_profiles]
|
||||
|
|
@ -481,3 +644,6 @@ class SqueakStore:
|
|||
|
||||
def delete_twitter_account(self, twitter_account_id: int) -> None:
|
||||
self.squeak_db.delete_twitter_account(twitter_account_id)
|
||||
|
||||
def get_latest_block(self) -> int:
|
||||
return self.squeak_core.get_best_block_height()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ from typing import Dict
|
|||
|
||||
from squeaknode.core.squeak_core import SqueakCore
|
||||
from squeaknode.core.twitter_account_entry import TwitterAccountEntry
|
||||
from squeaknode.node.squeak_controller import SqueakController
|
||||
from squeaknode.node.squeak_store import SqueakStore
|
||||
from squeaknode.twitter.twitter_stream import TwitterStream
|
||||
|
||||
|
||||
|
|
@ -36,11 +36,11 @@ class TwitterForwarder:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
squeak_controller: SqueakController,
|
||||
squeak_store: SqueakStore,
|
||||
squeak_core: SqueakCore,
|
||||
retry_s: int,
|
||||
):
|
||||
self.squeak_controller = squeak_controller
|
||||
self.squeak_store = squeak_store
|
||||
self.squeak_core = squeak_core
|
||||
self.retry_s = retry_s
|
||||
self.lock = threading.Lock()
|
||||
|
|
@ -54,9 +54,9 @@ class TwitterForwarder:
|
|||
del self.current_tasks[handle]
|
||||
|
||||
# Start new tasks.
|
||||
for account in self.squeak_controller.get_twitter_accounts():
|
||||
for account in self.squeak_store.get_twitter_accounts():
|
||||
task = TwitterForwarderTask(
|
||||
self.squeak_controller,
|
||||
self.squeak_store,
|
||||
self.squeak_core,
|
||||
account,
|
||||
self.retry_s,
|
||||
|
|
@ -83,12 +83,12 @@ class TwitterForwarderTask:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
squeak_controller: SqueakController,
|
||||
squeak_store: SqueakStore,
|
||||
squeak_core: SqueakCore,
|
||||
twitter_account: TwitterAccountEntry,
|
||||
retry_s: int,
|
||||
):
|
||||
self.squeak_controller = squeak_controller
|
||||
self.squeak_store = squeak_store
|
||||
self.squeak_core = squeak_core
|
||||
self.twitter_account = twitter_account
|
||||
self.retry_s = retry_s
|
||||
|
|
@ -166,7 +166,7 @@ class TwitterForwarderTask:
|
|||
self.forward_tweet(tweet)
|
||||
|
||||
def make_squeak(self, profile_id: int, content_str: str):
|
||||
squeak_profile = self.squeak_controller.get_squeak_profile(profile_id)
|
||||
squeak_profile = self.squeak_store.get_squeak_profile(profile_id)
|
||||
if squeak_profile is None:
|
||||
raise Exception("Profile with id {} not found.".format(
|
||||
profile_id,
|
||||
|
|
@ -175,10 +175,9 @@ class TwitterForwarderTask:
|
|||
squeak_profile,
|
||||
content_str,
|
||||
)
|
||||
inserted_squeak_hash = self.squeak_controller.save_squeak(
|
||||
inserted_squeak_hash = self.squeak_store.save_squeak(
|
||||
squeak,
|
||||
)
|
||||
if inserted_squeak_hash is None:
|
||||
return None
|
||||
self.squeak_controller.save_secret_key(
|
||||
inserted_squeak_hash, secret_key)
|
||||
self.squeak_store.save_secret_key(inserted_squeak_hash, secret_key)
|
||||
|
|
|
|||
|
|
@ -22,15 +22,16 @@
|
|||
import mock
|
||||
import pytest
|
||||
|
||||
from squeaknode.client.network_controller import NetworkController
|
||||
from squeaknode.config.config import SqueaknodeConfig
|
||||
from squeaknode.core.lightning_address import LightningAddressHostPort
|
||||
from squeaknode.core.peer_address import Network
|
||||
from squeaknode.core.peer_address import PeerAddress
|
||||
from squeaknode.core.squeak_core import SqueakCore
|
||||
from squeaknode.node.node_settings import NodeSettings
|
||||
from squeaknode.node.payment_processor import PaymentProcessor
|
||||
from squeaknode.node.squeak_controller import SqueakController
|
||||
from squeaknode.node.squeak_store import SqueakStore
|
||||
from squeaknode.twitter.twitter_forwarder import TwitterForwarder
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -59,11 +60,6 @@ def node_settings():
|
|||
return mock.Mock(spec=NodeSettings)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def squeak_core():
|
||||
return mock.Mock(spec=SqueakCore)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def lightning_host_port():
|
||||
return LightningAddressHostPort(host="my_lightning_host", port=8765)
|
||||
|
|
@ -97,18 +93,30 @@ def payment_processor():
|
|||
return mock.Mock(spec=PaymentProcessor)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def twitter_forwarder():
|
||||
return mock.Mock(spec=TwitterForwarder)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def network_controller():
|
||||
return mock.Mock(spec=NetworkController)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def squeak_controller(
|
||||
squeak_store,
|
||||
squeak_core,
|
||||
payment_processor,
|
||||
twitter_forwarder,
|
||||
network_controller,
|
||||
node_settings,
|
||||
config,
|
||||
):
|
||||
return SqueakController(
|
||||
squeak_store,
|
||||
squeak_core,
|
||||
payment_processor,
|
||||
twitter_forwarder,
|
||||
network_controller,
|
||||
node_settings,
|
||||
config,
|
||||
)
|
||||
|
|
@ -117,15 +125,17 @@ def squeak_controller(
|
|||
@pytest.fixture
|
||||
def regtest_squeak_controller(
|
||||
squeak_store,
|
||||
squeak_core,
|
||||
payment_processor,
|
||||
twitter_forwarder,
|
||||
network_controller,
|
||||
node_settings,
|
||||
regtest_config,
|
||||
):
|
||||
return SqueakController(
|
||||
squeak_store,
|
||||
squeak_core,
|
||||
payment_processor,
|
||||
twitter_forwarder,
|
||||
network_controller,
|
||||
node_settings,
|
||||
regtest_config,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import mock
|
|||
import pytest
|
||||
|
||||
from squeaknode.core.lightning_address import LightningAddressHostPort
|
||||
from squeaknode.core.squeak_core import SqueakCore
|
||||
from squeaknode.db.squeak_db import SqueakDb
|
||||
from squeaknode.node.squeak_store import SqueakStore
|
||||
|
||||
|
|
@ -32,6 +33,11 @@ def squeak_db():
|
|||
return mock.Mock(spec=SqueakDb)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def squeak_core():
|
||||
return mock.Mock(spec=SqueakCore)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def lightning_host_port():
|
||||
return LightningAddressHostPort(host="my_lightning_host", port=8765)
|
||||
|
|
@ -75,6 +81,7 @@ def inserted_signing_profile_id(squeak_db, signing_profile):
|
|||
@pytest.fixture
|
||||
def squeak_store(
|
||||
squeak_db,
|
||||
squeak_core,
|
||||
max_squeaks,
|
||||
max_squeaks_per_public_key_per_block,
|
||||
squeak_retention_s,
|
||||
|
|
@ -83,6 +90,7 @@ def squeak_store(
|
|||
):
|
||||
return SqueakStore(
|
||||
squeak_db,
|
||||
squeak_core,
|
||||
max_squeaks,
|
||||
max_squeaks_per_public_key_per_block,
|
||||
squeak_retention_s,
|
||||
|
|
@ -91,27 +99,31 @@ def squeak_store(
|
|||
)
|
||||
|
||||
|
||||
def test_save_squeak(squeak_store, squeak_db, block_header, squeak, squeak_hash):
|
||||
def test_save_squeak(squeak_store, squeak_db, squeak_core, block_header, squeak, squeak_hash):
|
||||
with mock.patch.object(squeak_db, 'get_number_of_squeaks', autospec=True) as mock_get_number_of_squeaks, \
|
||||
mock.patch.object(squeak_db, 'number_of_squeaks_with_public_key_with_block_height', autospec=True) as mock_number_of_squeaks_with_public_key_with_block_height, \
|
||||
mock.patch.object(squeak_db, 'insert_squeak', autospec=True) as mock_insert_squeak, \
|
||||
mock.patch.object(squeak_store.new_squeak_listener, 'handle_new_item', autospec=True) as mock_handle_new_squeak:
|
||||
mock.patch.object(squeak_store.new_squeak_listener, 'handle_new_item', autospec=True) as mock_handle_new_squeak, \
|
||||
mock.patch.object(squeak_core, 'get_block_header', autospec=True) as mock_get_block_header:
|
||||
mock_get_number_of_squeaks.return_value = 0
|
||||
mock_number_of_squeaks_with_public_key_with_block_height.return_value = 0
|
||||
mock_get_block_header.return_value = block_header
|
||||
mock_insert_squeak.return_value = squeak_hash
|
||||
squeak_store.save_squeak(squeak, block_header)
|
||||
squeak_store.save_squeak(squeak)
|
||||
|
||||
mock_insert_squeak.assert_called_once_with(squeak, block_header)
|
||||
mock_handle_new_squeak.assert_called_once_with(squeak)
|
||||
|
||||
|
||||
def test_save_squeak_above_max(squeak_store, squeak_db, block_header, squeak, squeak_hash, max_squeaks):
|
||||
def test_save_squeak_above_max(squeak_store, squeak_db, squeak_core, block_header, squeak, squeak_hash, max_squeaks):
|
||||
with mock.patch.object(squeak_db, 'get_number_of_squeaks', autospec=True) as mock_get_number_of_squeaks, \
|
||||
mock.patch.object(squeak_db, 'number_of_squeaks_with_public_key_with_block_height', autospec=True) as mock_number_of_squeaks_with_public_key_with_block_height, \
|
||||
mock.patch.object(squeak_db, 'insert_squeak', autospec=True) as mock_insert_squeak, \
|
||||
mock.patch.object(squeak_store.new_squeak_listener, 'handle_new_item', autospec=True) as mock_handle_new_squeak:
|
||||
mock.patch.object(squeak_store.new_squeak_listener, 'handle_new_item', autospec=True) as mock_handle_new_squeak, \
|
||||
mock.patch.object(squeak_core, 'get_block_header', autospec=True) as mock_get_block_header:
|
||||
mock_get_number_of_squeaks.return_value = max_squeaks + 1
|
||||
mock_number_of_squeaks_with_public_key_with_block_height.return_value = 0
|
||||
mock_get_block_header.return_value = block_header
|
||||
mock_insert_squeak.return_value = squeak_hash
|
||||
|
||||
with pytest.raises(Exception):
|
||||
|
|
@ -121,13 +133,15 @@ def test_save_squeak_above_max(squeak_store, squeak_db, block_header, squeak, sq
|
|||
assert mock_handle_new_squeak.call_count == 0
|
||||
|
||||
|
||||
def test_save_squeak_above_max_per_pubkey(squeak_store, squeak_db, block_header, squeak, squeak_hash, max_squeaks_per_public_key_per_block):
|
||||
def test_save_squeak_above_max_per_pubkey(squeak_store, squeak_db, squeak_core, block_header, squeak, squeak_hash, max_squeaks_per_public_key_per_block):
|
||||
with mock.patch.object(squeak_db, 'get_number_of_squeaks', autospec=True) as mock_get_number_of_squeaks, \
|
||||
mock.patch.object(squeak_db, 'number_of_squeaks_with_public_key_with_block_height', autospec=True) as mock_number_of_squeaks_with_public_key_with_block_height, \
|
||||
mock.patch.object(squeak_db, 'insert_squeak', autospec=True) as mock_insert_squeak, \
|
||||
mock.patch.object(squeak_store.new_squeak_listener, 'handle_new_item', autospec=True) as mock_handle_new_squeak:
|
||||
mock.patch.object(squeak_store.new_squeak_listener, 'handle_new_item', autospec=True) as mock_handle_new_squeak, \
|
||||
mock.patch.object(squeak_core, 'get_block_header', autospec=True) as mock_get_block_header:
|
||||
mock_get_number_of_squeaks.return_value = 0
|
||||
mock_number_of_squeaks_with_public_key_with_block_height.return_value = max_squeaks_per_public_key_per_block + 1
|
||||
mock_get_block_header.return_value = block_header
|
||||
mock_insert_squeak.return_value = squeak_hash
|
||||
|
||||
with pytest.raises(Exception):
|
||||
|
|
@ -137,9 +151,10 @@ def test_save_squeak_above_max_per_pubkey(squeak_store, squeak_db, block_header,
|
|||
assert mock_handle_new_squeak.call_count == 0
|
||||
|
||||
|
||||
def test_save_secret_key(squeak_store, squeak_db, squeak, squeak_hash, secret_key):
|
||||
def test_save_secret_key(squeak_store, squeak_db, squeak_core, squeak, squeak_hash, secret_key):
|
||||
with mock.patch.object(squeak_db, 'get_squeak', autospec=True) as mock_get_squeak, \
|
||||
mock.patch.object(squeak_db, 'set_squeak_secret_key', autospec=True) as mock_set_squeak_secret_key, \
|
||||
mock.patch.object(squeak_store, 'unlock_squeak', autospec=True) as mock_unlock_squeak, \
|
||||
mock.patch.object(squeak_store.new_secret_key_listener, 'handle_new_item', autospec=True) as mock_handle_new_secret_key:
|
||||
mock_get_squeak.return_value = squeak
|
||||
squeak_store.save_secret_key(squeak_hash, secret_key)
|
||||
|
|
@ -147,6 +162,21 @@ def test_save_secret_key(squeak_store, squeak_db, squeak, squeak_hash, secret_ke
|
|||
mock_set_squeak_secret_key.assert_called_once_with(
|
||||
squeak_hash, secret_key)
|
||||
mock_handle_new_secret_key.assert_called_once_with(squeak)
|
||||
mock_unlock_squeak.assert_called_once_with(squeak_hash)
|
||||
|
||||
|
||||
def test_unlock_squeak(squeak_store, squeak_db, squeak_core, squeak, squeak_hash, secret_key, squeak_content):
|
||||
with mock.patch.object(squeak_db, 'get_squeak', autospec=True) as mock_get_squeak, \
|
||||
mock.patch.object(squeak_db, 'get_squeak_secret_key', autospec=True) as mock_get_squeak_secret_key, \
|
||||
mock.patch.object(squeak_db, 'set_squeak_decrypted_content', autospec=True) as mock_set_squeak_decrypted_content, \
|
||||
mock.patch.object(squeak_core, 'get_decrypted_content', autospec=True) as mock_get_decrypted_content:
|
||||
mock_get_squeak.return_value = squeak
|
||||
mock_get_squeak_secret_key.return_value = secret_key
|
||||
mock_get_decrypted_content.return_value = squeak_content
|
||||
squeak_store.unlock_squeak(squeak_hash)
|
||||
|
||||
mock_set_squeak_decrypted_content.assert_called_once_with(
|
||||
squeak_hash, squeak_content)
|
||||
|
||||
|
||||
# @pytest.fixture
|
||||
|
|
@ -215,3 +245,91 @@ def test_get_received_offer(squeak_store, squeak_db, received_offer):
|
|||
|
||||
assert retrieved_received_offer == received_offer
|
||||
mock_get_received_offer.assert_called_once_with(789)
|
||||
|
||||
|
||||
# def test_get_free_secret_key(squeak_store, squeak_core, unlocked_squeak, secret_key, peer_address):
|
||||
# unlocked_squeak_hash = get_hash(unlocked_squeak)
|
||||
# secret_key_reply = squeak_store.get_secret_key_reply(
|
||||
# unlocked_squeak_hash, peer_address, 0, None)
|
||||
|
||||
# assert secret_key_reply.squeak_hash == unlocked_squeak_hash
|
||||
# assert secret_key_reply.secret_key == secret_key
|
||||
|
||||
|
||||
# def test_get_offer_secret_key(squeak_store, squeak_core, unlocked_squeak, secret_key, peer_address, sent_offer, offer):
|
||||
# with mock.patch.object(squeak_core, 'create_offer', autospec=True) as mock_create_offer, \
|
||||
# mock.patch.object(squeak_core, 'package_offer', autospec=True) as mock_package_offer:
|
||||
# mock_create_offer.return_value = sent_offer
|
||||
# mock_package_offer.return_value = offer
|
||||
# unlocked_squeak_hash = get_hash(unlocked_squeak)
|
||||
# secret_key_reply = squeak_store.get_secret_key_reply(
|
||||
# unlocked_squeak_hash, peer_address, 1000, None)
|
||||
|
||||
# assert secret_key_reply.squeak_hash == unlocked_squeak_hash
|
||||
# assert secret_key_reply.offer == offer
|
||||
|
||||
|
||||
# def test_pay_offer(
|
||||
# squeak_store,
|
||||
# squeak_db,
|
||||
# squeak_core,
|
||||
# unlocked_squeak,
|
||||
# block_header,
|
||||
# squeak_content,
|
||||
# secret_key,
|
||||
# peer_address,
|
||||
# inserted_received_offer_id,
|
||||
# sent_payment,
|
||||
# ):
|
||||
# with mock.patch.object(squeak_core, 'pay_offer', autospec=True) as mock_pay_offer, \
|
||||
# mock.patch.object(squeak_core, 'get_block_header', autospec=True) as mock_get_block_header, \
|
||||
# mock.patch.object(squeak_core, 'get_decrypted_content', autospec=True) as mock_get_decrypted_content:
|
||||
# mock_pay_offer.return_value = sent_payment
|
||||
# mock_get_block_header.return_value = block_header
|
||||
# mock_get_decrypted_content.return_value = squeak_content
|
||||
# sent_payment_id = squeak_store.pay_offer(inserted_received_offer_id)
|
||||
|
||||
# retrieved_sent_payment = squeak_db.get_sent_payment(
|
||||
# sent_payment_id,
|
||||
# )
|
||||
|
||||
# assert sent_payment_id is not None
|
||||
# assert retrieved_sent_payment is not None
|
||||
|
||||
|
||||
# def test_save_received_offer_already_unlocked(
|
||||
# squeak_store,
|
||||
# unlocked_squeak,
|
||||
# offer,
|
||||
# peer_address,
|
||||
# ):
|
||||
# received_offer_id = squeak_store.save_received_offer(
|
||||
# offer,
|
||||
# peer_address,
|
||||
# )
|
||||
|
||||
# assert received_offer_id is None
|
||||
|
||||
|
||||
# def test_save_received_offer(
|
||||
# squeak_store,
|
||||
# squeak_db,
|
||||
# squeak_core,
|
||||
# saved_squeak,
|
||||
# offer,
|
||||
# received_offer,
|
||||
# peer_address,
|
||||
# ):
|
||||
# with mock.patch.object(squeak_core, 'unpack_offer', autospec=True) as mock_unpack_offer:
|
||||
# mock_unpack_offer.return_value = received_offer
|
||||
# received_offer_id = squeak_store.save_received_offer(
|
||||
# offer,
|
||||
# peer_address,
|
||||
# )
|
||||
|
||||
# assert received_offer_id is not None
|
||||
# retrieved_received_offer = squeak_db.get_received_offer(received_offer_id)
|
||||
|
||||
# assert retrieved_received_offer == received_offer._replace(
|
||||
# received_offer_id=received_offer_id,
|
||||
# )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue