From 6f15f8196d9549787dedc96ebae37b6ca4b8ee19 Mon Sep 17 00:00:00 2001 From: Jonathan Zernik Date: Sat, 18 Jul 2020 22:35:26 -0700 Subject: [PATCH] Save block header in squeak table after verifying block hash of squeak (#87) --- itests/test.py | 3 ++ .../blockchain/bitcoin_blockchain_client.py | 35 ++++++++++--------- squeakserver/blockchain/util.py | 5 +++ squeakserver/node/squeak_block_verifier.py | 33 +++++++++++++---- squeakserver/server/postgres_db.py | 8 +++-- 5 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 squeakserver/blockchain/util.py diff --git a/itests/test.py b/itests/test.py index 8b58c0d3..72957321 100644 --- a/itests/test.py +++ b/itests/test.py @@ -125,6 +125,9 @@ def run(): ) print("Direct server post response: " + str(post_response)) + # Wait a few seconds for the squeak to be verified on the server. + time.sleep(5) + # Get the same squeak from the server get_response = server_stub.GetSqueak( squeak_server_pb2.GetSqueakRequest(hash=squeak_hash) diff --git a/squeakserver/blockchain/bitcoin_blockchain_client.py b/squeakserver/blockchain/bitcoin_blockchain_client.py index 008664e6..97f260ba 100644 --- a/squeakserver/blockchain/bitcoin_blockchain_client.py +++ b/squeakserver/blockchain/bitcoin_blockchain_client.py @@ -1,9 +1,13 @@ +import logging import json from typing import Optional import requests +logger = logging.getLogger(__name__) + + class BitcoinBlockchainClient: """Access a bitcoin daemon using RPC.""" @@ -27,20 +31,19 @@ class BitcoinBlockchainClient: block_hash = bytes.fromhex(result) return block_hash - # def get_block_hash(self, block_height: int) -> Optional[bytes]: - # # return self.access.getblockhash(block_height) - # payload = { - # "method": "getblockhash", - # "params": [block_height], - # "jsonrpc": "2.0", - # "id": 0, - # } - # response = requests.post( - # self.url, - # data=json.dumps(payload), - # headers=self.headers, - # ).json() + def get_block_header(self, block_hash: int, verbose: bool) -> Optional[bytes]: + payload = { + "method": "getblockheader", + "params": [block_hash, verbose], + "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 + logger.info("Got header request result: {}".format(response)) + result = response["result"] + return result diff --git a/squeakserver/blockchain/util.py b/squeakserver/blockchain/util.py new file mode 100644 index 00000000..f9407858 --- /dev/null +++ b/squeakserver/blockchain/util.py @@ -0,0 +1,5 @@ +from bitcoin.core import CBlockHeader + + +def parse_block_header(header_bytes: bytes): + return CBlockHeader.deserialize(header_bytes) diff --git a/squeakserver/node/squeak_block_verifier.py b/squeakserver/node/squeak_block_verifier.py index 281a541d..3650b59b 100644 --- a/squeakserver/node/squeak_block_verifier.py +++ b/squeakserver/node/squeak_block_verifier.py @@ -1,6 +1,8 @@ import logging import queue +from squeakserver.blockchain.util import parse_block_header + logger = logging.getLogger(__name__) @@ -13,7 +15,13 @@ class SqueakBlockVerifier: def verify_squeak_block(self, squeak_hash): logger.info("Verifying squeak hash: {}".format(squeak_hash)) squeak = self._get_squeak(squeak_hash) - block_info = self._get_block_info(squeak) + 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) + else: + self._delete_squeak def verify_all_unverified_squeaks(self): logger.info("Calling verify_squeaks.") @@ -32,13 +40,24 @@ class SqueakBlockVerifier: def _get_squeak(self, squeak_hash): return self.postgres_db.get_squeak(squeak_hash) - def _mark_squeak_verified(self, squeak_hash): - # TODO - pass + def _mark_squeak_verified(self, squeak_hash, block_header): + self.postgres_db.mark_squeak_block_valid(squeak_hash, block_header) - def _get_block_info(self, squeak): + 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 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)) - logger.info("Got block hash from squeak: {}".format(squeak.hashBlock)) - logger.info("Is block hash correct: {}".format(squeak.hashBlock == block_hash)) + return block_hash diff --git a/squeakserver/server/postgres_db.py b/squeakserver/server/postgres_db.py index 0798304a..7ef93c84 100644 --- a/squeakserver/server/postgres_db.py +++ b/squeakserver/server/postgres_db.py @@ -111,7 +111,10 @@ class PostgresDb: SELECT hash FROM squeak WHERE address IN %s AND nBlockHeight >= %s - AND nBlockHeight <= %s""" + AND nBlockHeight <= %s + AND vchDecryptionKey IS NOT NULL + AND block_header IS NOT NULL; + """ addresses_tuple = tuple(addresses) if not addresses: @@ -200,5 +203,4 @@ class PostgresDb: squeak_hash_str = squeak_hash.hex() with self.get_cursor() as curs: # execute the UPDATE statement - curs.execute(sql, (block_header, squeak_hash,)) - logger.info("Updated squeak with block header") + curs.execute(sql, (block_header, squeak_hash_str,))