mirror of
https://github.com/yzernik/squeaknode.git
synced 2026-08-14 12:43:24 +02:00
Use blockchain client to get subscription (#205)
* Use blockchain client in subscription class * Refactor bitcoin blockchain client * Use blockchain client instead of lightning client in squeak maker
This commit is contained in:
parent
9db19bcb46
commit
ad0632bd1c
7 changed files with 116 additions and 41 deletions
|
|
@ -4,18 +4,46 @@ from typing import Optional
|
|||
|
||||
import requests
|
||||
|
||||
from squeakserver.blockchain.block_info import BlockInfo
|
||||
from squeakserver.blockchain.blockchain_client import BlockchainClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BitcoinBlockchainClient:
|
||||
class BitcoinBlockchainClient(BlockchainClient):
|
||||
"""Access a bitcoin daemon using RPC."""
|
||||
|
||||
def __init__(self, host: str, port: int, rpc_user: str, rpc_password: str,) -> None:
|
||||
self.url = f"https://{rpc_user}:{rpc_password}@{host}:{port}"
|
||||
self.headers = {"content-type": "application/json"}
|
||||
|
||||
def get_block_hash(self, block_height: int) -> Optional[bytes]:
|
||||
# return self.access.getblockhash(block_height)
|
||||
def get_best_block_info(self) -> BlockInfo:
|
||||
block_height = self.get_block_count() - 1
|
||||
return self.get_block_info_by_height(block_height)
|
||||
|
||||
def get_block_info_by_height(self, block_height: int) -> BlockInfo:
|
||||
block_hash = self.get_block_hash(block_height)
|
||||
block_header = self.get_block_header(block_hash, False)
|
||||
return BlockInfo(block_height, block_hash, block_header)
|
||||
|
||||
def get_block_count(self) -> Optional[int]:
|
||||
payload = {
|
||||
"method": "getblockcount",
|
||||
"params": [],
|
||||
"jsonrpc": "2.0",
|
||||
"id": 0,
|
||||
}
|
||||
response = requests.post(
|
||||
self.url, data=json.dumps(payload), headers=self.headers,
|
||||
).json()
|
||||
|
||||
logger.info("Got response for get_block_count: {}".format(response))
|
||||
result = response["result"]
|
||||
block_count = int(result)
|
||||
logger.info("Got block_count: {}".format(block_count))
|
||||
return block_count
|
||||
|
||||
def get_block_hash(self, block_height: int) -> Optional[str]:
|
||||
payload = {
|
||||
"method": "getblockhash",
|
||||
"params": [block_height],
|
||||
|
|
@ -26,11 +54,28 @@ class BitcoinBlockchainClient:
|
|||
self.url, data=json.dumps(payload), headers=self.headers,
|
||||
).json()
|
||||
|
||||
logger.info("Got response for get_block_hash: {}".format(response))
|
||||
result = response["result"]
|
||||
block_hash = bytes.fromhex(result)
|
||||
block_hash = result
|
||||
logger.info("Got block_hash: {}".format(block_hash))
|
||||
return block_hash
|
||||
|
||||
def get_block_header(self, block_hash: int, verbose: bool) -> Optional[bytes]:
|
||||
# def get_best_block_hash(self) -> Optional[bytes]:
|
||||
# payload = {
|
||||
# "method": "getblockhash",
|
||||
# "params": [],
|
||||
# "jsonrpc": "2.0",
|
||||
# "id": 0,
|
||||
# }
|
||||
# response = requests.post(
|
||||
# self.url, data=json.dumps(payload), headers=self.headers,
|
||||
# ).json()
|
||||
|
||||
# result = response["result"]
|
||||
# block_hash = bytes.fromhex(result)
|
||||
# return block_hash
|
||||
|
||||
def get_block_header(self, block_hash: str, verbose: bool) -> Optional[bytes]:
|
||||
payload = {
|
||||
"method": "getblockheader",
|
||||
"params": [block_hash, verbose],
|
||||
|
|
@ -41,6 +86,7 @@ class BitcoinBlockchainClient:
|
|||
self.url, data=json.dumps(payload), headers=self.headers,
|
||||
).json()
|
||||
|
||||
logger.info("Got header request result: {}".format(response))
|
||||
logger.info("Got response for get_block_header: {}".format(response))
|
||||
result = response["result"]
|
||||
logger.info("Got block_header: {}".format(result))
|
||||
return result
|
||||
|
|
|
|||
6
squeakserver/blockchain/block_info.py
Normal file
6
squeakserver/blockchain/block_info.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
from collections import namedtuple
|
||||
|
||||
BlockInfo = namedtuple(
|
||||
"BlockInfo",
|
||||
"block_height, block_hash, block_header",
|
||||
)
|
||||
22
squeakserver/blockchain/blockchain_client.py
Normal file
22
squeakserver/blockchain/blockchain_client.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import json
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from squeakserver.blockchain.block_info import BlockInfo
|
||||
|
||||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BlockchainClient(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def get_best_block_info(self) -> BlockInfo:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_block_info_by_height(self) -> BlockInfo:
|
||||
pass
|
||||
|
|
@ -13,13 +13,16 @@ class SqueakBlockVerifier:
|
|||
def verify_squeak_block(self, squeak_hash):
|
||||
logger.info("Verifying squeak hash: {}".format(squeak_hash))
|
||||
squeak = self._get_squeak(squeak_hash)
|
||||
valid_block_info = self._check_block_info(squeak)
|
||||
logger.info("Is block hash correct: {}".format(valid_block_info))
|
||||
if valid_block_info:
|
||||
block_header = self._get_block_header(squeak)
|
||||
self._mark_squeak_verified(squeak_hash, block_header)
|
||||
block_info = self._get_block_info_for_height(squeak.nBlockHeight)
|
||||
|
||||
logger.info("Checking block height: {}".format(squeak.nBlockHeight))
|
||||
logger.info("Checking block hash: {}".format(squeak.hashBlock.hex()))
|
||||
if squeak.hashBlock.hex() == block_info.block_hash:
|
||||
logger.info("block hash correct: {}".format(block_info))
|
||||
self._mark_squeak_verified(squeak_hash, block_info)
|
||||
else:
|
||||
self._delete_squeak
|
||||
logger.info("block hash incorrect: {}".format(block_info))
|
||||
self._delete_squeak(squeak_hash)
|
||||
|
||||
def verify_all_unverified_squeaks(self):
|
||||
logger.info("Calling verify_squeaks.")
|
||||
|
|
@ -42,24 +45,12 @@ class SqueakBlockVerifier:
|
|||
squeak_entry = self.postgres_db.get_squeak_entry(squeak_hash)
|
||||
return squeak_entry.squeak
|
||||
|
||||
def _mark_squeak_verified(self, squeak_hash, block_header):
|
||||
self.postgres_db.mark_squeak_block_valid(squeak_hash, block_header)
|
||||
def _mark_squeak_verified(self, squeak_hash, block_info):
|
||||
block_header_bytes = bytes.fromhex(block_info.block_header)
|
||||
self.postgres_db.mark_squeak_block_valid(squeak_hash, block_header_bytes)
|
||||
|
||||
def _delete_squeak(self, squeak_hash):
|
||||
self.postgres_db.delete_squeak(squeak_hash)
|
||||
|
||||
def _check_block_info(self, squeak):
|
||||
block_height = squeak.nBlockHeight
|
||||
block_hash = self._get_block_hash(block_height)
|
||||
return squeak.hashBlock == block_hash
|
||||
|
||||
def _get_block_header(self, squeak):
|
||||
block_hash_str = squeak.hashBlock.hex()
|
||||
block_header = self.blockchain_client.get_block_header(block_hash_str, False)
|
||||
logger.info("Got block header from blockchain: {}".format(block_header))
|
||||
return bytes.fromhex(block_header)
|
||||
|
||||
def _get_block_hash(self, block_height):
|
||||
block_hash = self.blockchain_client.get_block_hash(block_height)
|
||||
logger.info("Got block hash from blockchain: {}".format(block_hash))
|
||||
return block_hash
|
||||
def _get_block_info_for_height(self, block_height):
|
||||
return self.blockchain_client.get_block_info_by_height(block_height)
|
||||
|
|
|
|||
|
|
@ -10,17 +10,17 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
class SqueakMaker:
|
||||
def __init__(self, lightning_client):
|
||||
self.lightning_client = lightning_client
|
||||
def __init__(self, blockchain_client):
|
||||
self.blockchain_client = blockchain_client
|
||||
|
||||
def make_squeak(self, signing_profile, content_str, replyto_hash=None):
|
||||
signing_key_str = signing_profile.private_key.decode()
|
||||
signing_key = CSigningKey(signing_key_str)
|
||||
logger.info("Creating squeak with signing key: {}".format(signing_key))
|
||||
logger.info("Creating squeak with replyto_hash: {}".format(replyto_hash))
|
||||
latest_block = self._get_latest_block()
|
||||
block_height = latest_block.block_height
|
||||
block_hash = latest_block.block_hash
|
||||
block_info = self._get_latest_block_info()
|
||||
block_height = block_info.block_height
|
||||
block_hash = bytes.fromhex(block_info.block_hash)
|
||||
timestamp = self._get_current_time_s()
|
||||
logger.info("Creating squeak with block height: {}".format(block_height))
|
||||
logger.info("Creating squeak with block hash: {}".format(block_hash))
|
||||
|
|
@ -38,11 +38,14 @@ class SqueakMaker:
|
|||
replyto_hash,
|
||||
)
|
||||
|
||||
def _get_latest_block(self):
|
||||
get_info_response = self.lightning_client.get_info()
|
||||
block_hash = bytes.fromhex(get_info_response.block_hash)
|
||||
block_height = get_info_response.block_height
|
||||
return BlockInfo(block_hash, block_height)
|
||||
# def _get_latest_block(self):
|
||||
# get_info_response = self.lightning_client.get_info()
|
||||
# block_hash = bytes.fromhex(get_info_response.block_hash)
|
||||
# block_height = get_info_response.block_height
|
||||
# return BlockInfo(block_hash, block_height)
|
||||
|
||||
def _get_latest_block_info(self):
|
||||
return self.blockchain_client.get_best_block_info()
|
||||
|
||||
def _get_current_time_s(self):
|
||||
return int(time.time())
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class SqueakNode:
|
|||
self.squeak_subscription_downloader = SqueakSubscriptionDownloader(
|
||||
postgres_db,
|
||||
self.squeak_store,
|
||||
self.blockchain_client,
|
||||
)
|
||||
|
||||
def start_running(self):
|
||||
|
|
@ -173,7 +174,7 @@ class SqueakNode:
|
|||
|
||||
def make_squeak(self, profile_id, content_str, replyto_hash):
|
||||
squeak_profile = self.postgres_db.get_profile(profile_id)
|
||||
squeak_maker = SqueakMaker(self.lightning_client)
|
||||
squeak_maker = SqueakMaker(self.blockchain_client)
|
||||
squeak = squeak_maker.make_squeak(squeak_profile, content_str, replyto_hash)
|
||||
return self.save_created_squeak(squeak)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,15 @@ SUBSCRIBE_UPDATE_INTERVAL_S = 10.0
|
|||
|
||||
|
||||
class SqueakSubscriptionDownloader:
|
||||
def __init__(self, postgres_db, squeak_store, update_interval_s=SUBSCRIBE_UPDATE_INTERVAL_S):
|
||||
def __init__(self,
|
||||
postgres_db,
|
||||
squeak_store,
|
||||
blockchain_client,
|
||||
update_interval_s=SUBSCRIBE_UPDATE_INTERVAL_S,
|
||||
):
|
||||
self.postgres_db = postgres_db
|
||||
self.squeak_store = squeak_store
|
||||
self.blockchain_client = blockchain_client
|
||||
self.update_interval_s = update_interval_s
|
||||
|
||||
def sync_subscriptions(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue