Selaa lähdekoodia

add logging for verification issues

Malte Kraus 8 vuotta sitten
vanhempi
sitoutus
20b99cbc15
3 muutettua tiedostoa jossa 21 lisäystä ja 3 poistoa
  1. 8 1
      src/block.py
  2. 2 1
      src/blockchain.py
  3. 11 1
      src/transaction.py

+ 8 - 1
src/block.py

@@ -1,6 +1,7 @@
 from datetime import datetime
 from binascii import hexlify, unhexlify
 import json
+import logging
 
 from .merkle import merkle_tree
 from .crypto import get_hasher
@@ -84,8 +85,12 @@ class Block:
         """ Verify that the hash value is correct and fulfills its difficulty promise. """
         # TODO: move this some better place
         if self.hash != self.get_hash():
+            logging.warning("block has invalid hash value")
             return False
-        return verify_proof_of_work(self)
+        if not verify_proof_of_work(self):
+            logging.warning("block does not satisfy proof of work")
+            return False
+        return True
 
     def verify_prev_block(self, chain):
         """ Verify the previous block pointer points to a valid block in the given block chain. """
@@ -106,6 +111,7 @@ class Block:
         for t in self.transactions:
             if not t.inputs:
                 if mining_reward is not None:
+                    logging.warning("block has more than one reward transaction")
                     return False
                 mining_reward = t
 
@@ -113,6 +119,7 @@ class Block:
                 return False
         if mining_reward is not None:
             if sum(map(lambda t: t.amount, mining_reward.targets)) > chain.compute_blockreward(chain.get_block_by_hash(self.prev_block_hash)):
+                logging.warning("mining reward is too large")
                 return False
         return True
 

+ 2 - 1
src/blockchain.py

@@ -1,4 +1,5 @@
 __all__ = ['Blockchain']
+import logging
 
 class Blockchain:
     def __init__(self, blocks: list):
@@ -17,7 +18,7 @@ class Blockchain:
                     return trans
         return None
 
-    def is_coin_still_valid(self, transaction_input, prev_block=None):
+    def is_coin_still_valid(self, transaction_input: 'TransactionInput', prev_block: 'Block'=None):
         """
         Validates that the coins that were sent in the transaction identified
         by `transaction_hash_val` to the nth receiver (n=output_idx) have not been

+ 11 - 1
src/transaction.py

@@ -1,5 +1,7 @@
 from collections import namedtuple
 from binascii import hexlify, unhexlify
+import logging
+
 from .blockchain import Blockchain
 from .block import Block
 
@@ -92,6 +94,7 @@ class Transaction:
     def _verify_signatures(self, chain: Blockchain):
         """ Verify that all inputs are signed and the signatures are valid. """
         if len(self.signatures) != len(self.inputs):
+            logging.warning("wrong number of signatures")
             return False
 
         for (s, i) in zip(self.signatures, self.inputs):
@@ -103,22 +106,29 @@ class Transaction:
         """ Verifies the signature on a single input. """
         trans = chain.get_transaction_by_hash(inp.transaction_hash)
         if trans is None:
+            logging.warning("Referenced transaction input could not be found.")
             return False
         sender_pk = trans.targets[inp.output_idx].recipient_pk
-        return sender_pk.verify_sign(self.get_hash(), sig)
+        if not sender_pk.verify_sign(self.get_hash(), sig):
+            logging.warning("Transaction signature does not verify.")
+            return False
+        return True
 
 
     def _verify_single_spend(self, chain: Blockchain, other_trans: set, prev_block: Block):
         """ Verifies that all inputs have not been spent yet. """
         inp_set = set(self.inputs)
         if len(self.inputs) != len(inp_set):
+            logging.warning("Transaction may not spend the same coin twice.")
             return False
         other_inputs = {i for t in other_trans for i in t.inputs}
         if other_inputs.intersection(inp_set):
+            logging.warning("Transaction may not spend the same coin as another transaction in the same block.")
             return False
 
         for i in self.inputs:
             if not chain.is_coin_still_valid(i, prev_block):
+                logging.debug("Transaction refers to a coin that was already spent.")
                 return False
         return True