def test_signature_validate(self): """ GIVEN success tx, invalid public key tx, invalid signature tx, WHEN validate 3 tx THEN only success tx validate return true """ # GIVEN # init peer_auth for signautre peer_auth = PeerAuthorization(public_file=conf.PUBLIC_PATH, pri_file=conf.PRIVATE_PATH, cert_pass=conf.DEFAULT_PW) # create txs success_tx = test_util.create_basic_tx("aaa", peer_auth) # public key and signature property must don't have setter invalid_public_tx = test_util.create_basic_tx("aaa", peer_auth) invalid_public_tx._Transaction__public_key = b'invalid_public' invalid_sign_tx = test_util.create_basic_tx("aaa", peer_auth) invalid_sign_tx._Transaction__signature = b'invalid_sign' # WHEN THEN self.assertTrue(Transaction.validate(success_tx)) logging.debug("start validate invalid public key") self.assertFalse( Transaction.validate(invalid_public_tx, is_exception_log=False)) logging.debug("start validate invalid signature") self.assertFalse( Transaction.validate(invalid_sign_tx, is_exception_log=False))
def put_transaction(self, tx): """Block Generator 에서만 사용한다. tx는 단수 혹은 여러개 일 수 있다 :param tx: transaction (transaction을 담고 있는 list도 처리 가능) :return: True: 성공적으로 담겼을 때. """ if type(tx) is list: result = True for t in tx: result &= self.put_transaction(t) return result elif not isinstance(tx, Transaction): logging.error("트랜잭션 타입이 아님 %s", type(tx)) return False # TX 검증은 현재 받아들인 TX의 Hash값(Peer 생성)과 # block generator (leader) 에서 만든 Hash 값이 일치하는지 확인 후 block 에 추가합니다. # TX 는 최초 생성한 Peer 에서 block 에 담겨오는지 여부를 확인 할 때까지 보관해야 합니다. (TODO) if tx.status == TransactionStatus.unconfirmed: # transaction 검증 # logging.debug("Transaction Hash %s", tx.get_tx_hash()) if Transaction.validate(tx): tx.status = TransactionStatus.confirmed else: return False # Block 에 검증된 Transaction 추가 : 목록에 존재하는지 확인 필요 if tx not in self.confirmed_transaction_list: self.confirmed_transaction_list.append(tx) return True
def validate(block, tx_queue=None) -> bool: """validate block and all transactions in block :param: block :param: tx_queue :return validate success return true """ mk_hash = Block.__calculate_merkle_tree_root_hash(block) if block.height == 0 and len(block.confirmed_transaction_list) == 0: # Genesis Block 은 검증하지 않습니다. return True if len(block.confirmed_transaction_list) > 0: # 머클트리 검증은 Tx가 있을때에만 합니다. if mk_hash != block.merkle_tree_root_hash: raise BlockInValidError('Merkle Tree Root hash is not same') if block.block_hash != Block.__generate_hash(block): raise BlockInValidError('block Hash is not same generate hash') leader = ObjectManager().peer_service.channel_manager.get_peer_manager( block.__channel_name).get_leader_object() if not leader.cert_verifier.verify_hash(block.block_hash, block.signature): raise BlockInValidError('block signature invalid') if block.time_stamp == 0: raise BlockError('block time stamp is 0') if len(block.prev_block_hash) == 0: raise BlockError('Prev Block Hash not Exist') # Transaction Validate confirmed_tx_list = [] for tx in block.confirmed_transaction_list: if Transaction.validate(tx): confirmed_tx_list.append(tx.tx_hash) else: raise BlockInValidError( f"block ({block.block_hash}) validate fails \n" f"tx {tx.tx_hash} is invalid") if tx_queue is not None: block.__tx_validate_with_queue(tx_queue, confirmed_tx_list) return True