mirror of
https://github.com/aljazceru/python-teos.git
synced 2025-12-17 14:14:22 +01:00
107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
import binascii
|
|
from hashlib import sha256
|
|
|
|
from pisa import bitcoin_cli, Logger
|
|
from pisa.utils.auth_proxy import JSONRPCException
|
|
|
|
logger = Logger("BlockProcessor")
|
|
|
|
|
|
class BlockProcessor:
|
|
@staticmethod
|
|
def get_block(block_hash):
|
|
|
|
try:
|
|
block = bitcoin_cli.getblock(block_hash)
|
|
|
|
except JSONRPCException as e:
|
|
block = None
|
|
logger.error("couldn't get block from bitcoind.", error_code=e)
|
|
|
|
return block
|
|
|
|
@staticmethod
|
|
def get_best_block_hash():
|
|
|
|
try:
|
|
block_hash = bitcoin_cli.getbestblockhash()
|
|
|
|
except JSONRPCException as e:
|
|
block_hash = None
|
|
logger.error("couldn't get block hash.", error_code=e)
|
|
|
|
return block_hash
|
|
|
|
@staticmethod
|
|
def get_block_count():
|
|
|
|
try:
|
|
block_count = bitcoin_cli.getblockcount()
|
|
|
|
except JSONRPCException as e:
|
|
block_count = None
|
|
logger.error("couldn't get block block count", error_code=e)
|
|
|
|
return block_count
|
|
|
|
# FIXME: The following two functions does not seem to belong here. They come from the Watcher, and need to be
|
|
# separated since they will be reused by the TimeTraveller.
|
|
# DISCUSS: 36-who-should-check-appointment-trigger
|
|
@staticmethod
|
|
def get_potential_matches(txids, locator_uuid_map):
|
|
potential_locators = {sha256(binascii.unhexlify(txid)).hexdigest(): txid for txid in txids}
|
|
|
|
# Check is any of the tx_ids in the received block is an actual match
|
|
intersection = set(locator_uuid_map.keys()).intersection(potential_locators.keys())
|
|
potential_matches = {locator: potential_locators[locator] for locator in intersection}
|
|
|
|
if len(potential_matches) > 0:
|
|
logger.info("list of potential matches", potential_matches=potential_matches)
|
|
|
|
else:
|
|
logger.info("no potential matches found")
|
|
|
|
return potential_matches
|
|
|
|
@staticmethod
|
|
def get_matches(potential_matches, locator_uuid_map, appointments):
|
|
matches = []
|
|
|
|
for locator, dispute_txid in potential_matches.items():
|
|
for uuid in locator_uuid_map[locator]:
|
|
try:
|
|
# ToDo: #20-test-tx-decrypting-edge-cases
|
|
justice_rawtx = appointments[uuid].encrypted_blob.decrypt(dispute_txid)
|
|
justice_txid = bitcoin_cli.decoderawtransaction(justice_rawtx).get('txid')
|
|
matches.append((locator, uuid, dispute_txid, justice_txid, justice_rawtx))
|
|
|
|
logger.info("match found for locator.", locator=locator, uuid=uuid, justice_txid=justice_txid)
|
|
|
|
except JSONRPCException as e:
|
|
# Tx decode failed returns error code -22, maybe we should be more strict here. Leaving it simple
|
|
# for the POC
|
|
logger.error("can't build transaction from decoded data.", error_code=e)
|
|
|
|
return matches
|
|
|
|
# DISCUSS: This method comes from the Responder and seems like it could go back there.
|
|
@staticmethod
|
|
def check_confirmations(txs, unconfirmed_txs, tx_job_map, missed_confirmations):
|
|
|
|
for tx in txs:
|
|
if tx in tx_job_map and tx in unconfirmed_txs:
|
|
unconfirmed_txs.remove(tx)
|
|
|
|
logger.info("confirmation received for transaction", tx=tx)
|
|
|
|
elif tx in unconfirmed_txs:
|
|
if tx in missed_confirmations:
|
|
missed_confirmations[tx] += 1
|
|
|
|
else:
|
|
missed_confirmations[tx] = 1
|
|
|
|
logger.info("transaction missed a confirmation", tx=tx, missed_confirmations=missed_confirmations[tx])
|
|
|
|
return unconfirmed_txs, missed_confirmations
|