示例#1
0
    def test_post_transaction(self):
        self.prepare_app()

        # prepare a valid transaction
        w = Wallet()
        w.create_keys()
        tx = Transaction("0", w.get_address(), 1)
        w.sign_transaction(tx)

        client = app.test_client()

        response = client.post("/block/new", data=tx.to_json())
        self.assertEqual(response.status_code, 201)

        b = Block.from_json(response.get_data())
        mine(b)
        response = client.post("/block", data=b.to_json())
        self.assertEqual(response.status_code, 201)

        tx = Transaction(w.get_address(), 1, 0.5)

        # test without signature
        response = client.post("/transaction", data=tx.to_json())
        self.assertEqual(response.status_code, 400)

        # test with signature
        w.sign_transaction(tx)
        response = client.post("/transaction", data=tx.to_json())
        self.assertEqual(response.status_code, 201)
示例#2
0
    def test_use_pool(self):
        bc = BlockChain()
        w = Wallet()
        w.create_keys()

        # make some cash
        tx0 = Transaction("0", w.get_address(), 1)
        b = bc.new_block(tx0)
        mine(b)
        self.assertTrue(bc.discard_block(b))

        self.assertEqual(bc.get_wallet_balance(w.get_address()), 1)
        tx_count = 10
        for i in range(tx_count):
            t = Transaction(w.get_address(), 1, 1 / 100)
            w.sign_transaction(t)
            self.assertTrue(bc.add_transaction(t))
        self.assertEqual(len(bc.transaction_pool), tx_count)
        b = bc.new_block(self.tx)

        max_txs_in_block = 2**Tree.MAX_DEPTH
        self.assertEqual(len(list(b.get_transactions())),
                         min(max_txs_in_block, tx_count + 1))

        # Transactions in new block are removed from tx pool when new block is successfully discarded to chain
        b = bc.new_block(self.tx)  # coinbase tx
        mine(b)
        bc.discard_block(b)

        expected_txs_in_tx_pool = max(0, tx_count - (max_txs_in_block - 1))
        self.assertEqual(len(bc.transaction_pool), expected_txs_in_tx_pool)

        leftover_count = min(max_txs_in_block - 1, expected_txs_in_tx_pool)
        self.assertEqual(len(list(bc.new_block(self.tx).get_transactions())),
                         1 + leftover_count)
示例#3
0
    def test_block_serialize(self):
        a = Block(0, 1, datetime.datetime.utcnow().timestamp())
        t1 = Transaction(0, 1, 2)
        a.add_transaction(t1)
        t2 = Transaction(0, 1, 2)
        a.add_transaction(t2)

        b = Block.from_json(a.to_json())
        self.assertEqual(a.get_hash(), b.get_hash())
示例#4
0
 def test_walk_transactions(self):
     b = Block(0, 0, 0)
     t = Transaction(0, 1, 2)
     b.add_transaction(t)
     self.assertEqual(len(list(b.get_transactions())), 1)
     t = Transaction(0, 1, 2)
     b.add_transaction(t)
     self.assertEqual(len(list(b.get_transactions())), 2)
     for x in b.get_transactions():
         self.assertIsInstance(x, Transaction)
示例#5
0
    def test_locate_transaction(self):
        t = Tree()
        trans1 = Transaction(0, 1, 2)
        self.assertTrue(t.add_transaction(trans1))

        trans2 = Transaction(1, 2, 3)
        self.assertTrue(t.add_transaction(trans2))
        self.assertEqual(t.depth, 1)

        self.assertTrue(t.is_present(trans1))

        trans3 = Transaction(0, 1, 2)
        self.assertFalse(t.is_present(trans3))
示例#6
0
    def post(self):
        key = self.request.GET['key']
        try:
            category = self.request.get("category", "none")
            quantity = float(self.request.get("quantity", 0))
            type = self.request.get("type", "none")
            description = self.request.get("description", "none")
            date = self.request.get("date", "none")
            date_format = datetime.datetime.strptime(date, "%Y-%m-%d")
        except ValueError:
            url = "/viewAccount?key=" + str(
                key) + ";msg_error=Formato de campo incorrecto"
            self.redirect(url)
            return

        account_key = ndb.Key(urlsafe=key)

        #Store the answer

        new_transaction = Transaction(category=category,
                                      quantity=quantity,
                                      type=type,
                                      description=description,
                                      date=date_format,
                                      account=account_key)
        new_transaction.put()
        time.sleep(1)

        url = "/viewAccount?key=" + str(key)
        self.redirect(url)
示例#7
0
    def generate_wallet_and_coinbase():
        w = Wallet()
        w.create_keys()
        tx = Transaction("0", w.get_address(), 1)  # coinbase
        w.sign_transaction(tx)

        return w, tx
示例#8
0
    def test_transaction(self):
        """One tree node can contain only one transaction"""
        n = TreeNode()
        t = Transaction(0, 1, 1)
        self.assertTrue(n.add_child(t))

        n1 = TreeNode()
        self.assertFalse(n.add_child(n1))
示例#9
0
    def test_tree_serialize(self):
        t = Tree()
        u = Tree.from_json(t.to_json())

        self.assertEqual(t.root.get_hash(), u.root.get_hash())

        trans1 = Transaction(0, 1, 2)
        self.assertTrue(t.add_transaction(trans1))
        trans2 = Transaction(1, 2, 3)
        self.assertTrue(t.add_transaction(trans2))
        trans3 = Transaction(2, 3, 4)
        self.assertTrue(t.add_transaction(trans3))

        u = Tree.from_json(t.to_json())
        self.assertEqual(t.root._child_1.get_hash(),
                         u.root._child_1.get_hash())
        self.assertEqual(t.root.get_hash(), u.root.get_hash())
示例#10
0
 def withdrawal(self, date, description, amount):
     tx = Transaction(date=date,
                      description=description,
                      amount=amount * -1,
                      tx_type='W',
                      account_number=self.number)
     self.transactions.append(tx)
     return tx
示例#11
0
 def deposit(self, date, description, amount):
     tx = Transaction(date=date,
                      description=description,
                      amount=amount,
                      tx_type='D',
                      account_number=self.number)
     self.transactions.append(tx)
     return tx
示例#12
0
 def make_transaction(self, data: dict) -> Transaction:
     """
     Método disparado quando efetuado a chamada de um .load(object).data onde efetua o retorno
     de uma instancia de um dataclass de uma transação
     :param data: payload que irá ser transformado
     :return: Instancia dataclass de umma transação.
     """
     return Transaction(**data)
示例#13
0
    def test_transaction_serialize(self):
        t1 = Transaction(0, 1, 2)
        t2 = Transaction(0, 1, 2)

        self.assertNotEqual(t1.get_hash(), t2.get_hash())

        t3 = Transaction.from_json(t1.to_json())
        self.assertEqual(t1.get_hash(), t3.get_hash())
        self.assertEqual(t1.src, t3.src)
        self.assertEqual(t1.dst, t3.dst)
        self.assertEqual(t1.qty, t3.qty)

        w = Wallet()
        w.create_keys()
        w.sign_transaction(t1)
        t4 = Transaction.from_json(t1.to_json())
        self.assertEqual(t1.get_hash(), t4.get_hash())
示例#14
0
    def test_inf_nan_balance(self):
        bc = BlockChain()

        tx = Transaction("src", "dst", math.inf)

        is_found = False
        balance, is_found = bc.update_balance("src", math.inf, tx, is_found)
        self.assertEqual(is_found, True)
        self.assertEqual(balance, math.inf)
示例#15
0
    def test_verify_foreign_transaction(self):
        w = Wallet()
        w.create_keys()
        t = Transaction(w.get_address(), 1, 1)
        w.sign_transaction(t)

        # Create different keypair
        w.create_keys()

        self.assertTrue(w.verify_transaction(t))
示例#16
0
    def enrich_wallet_coinbase(cls):
        w = Wallet()
        w.create_keys()
        tx = Transaction("0", w.get_address(), 1)  # coinbase
        w.sign_transaction(tx)

        cls.w = w
        cls.tx = tx

        return w, tx
示例#17
0
    def test_secure_wallet_balance(self):
        bc = BlockChain()

        w1 = Wallet()
        w1.create_keys()
        addr1 = w1.get_address()

        tx0 = Transaction("0", addr1, 1)
        b = bc.new_block(tx0)
        mine(b)
        bc.discard_block(b)

        balance = bc.get_secure_wallet_balance(addr1)
        self.assertEqual(balance, None)

        tx1 = Transaction(addr1, "toto", 1)
        w1.sign_transaction(tx1)

        cbtx = WalletHelper.generate_coinbase_with_unused_wallet()
        b1 = bc.new_block(cbtx)
        b1.add_transaction(tx1)
        mine(b1)
        bc.discard_block(b1)

        self.assertEqual(bc.get_secure_wallet_balance("toto"), None)

        for i in range(5):
            tx0 = Transaction("0", addr1, 1)
            b = bc.new_block(tx0)
            mine(b)
            bc.discard_block(b)

        # only 5 confirmations so far, tx is not there yet for secure balance
        self.assertEqual(bc.get_secure_wallet_balance("toto"), None)

        cbtx = WalletHelper.generate_coinbase_with_unused_wallet()
        b6 = bc.new_block(cbtx)
        mine(b6)
        bc.discard_block(b6)

        # tx appears after 6 confirmations only
        self.assertEqual(bc.get_secure_wallet_balance("toto"), 1)
示例#18
0
    def to_object(self, row):
        if len(row) > 0:
            return (Transaction(id_=int(row[0]),
                                account_number=int(row[1]),
                                date=datetime.strptime(row[2],
                                                       '%Y/%m/%d  %H:%M:%S'),
                                tx_type=row[3],
                                description=row[4],
                                amount=row[5]))

        return None
示例#19
0
    def test_import_transactions(self):
        b = Block(0, 0)
        w = Wallet()
        w.create_keys()
        t = Transaction(w.get_address(), 1, 1)
        w.sign_transaction(t)
        b.add_transaction(t)

        tp = TransactionPool()
        self.assertTrue(tp.import_transactions(b))
        self.assertEqual(len(tp), 1)

        t2 = tp.pull_transaction()
        self.assertEqual(t.get_hash(), t2.get_hash())

        # Importing unsigned transactions returns False
        tp = TransactionPool()
        t2 = Transaction(0, 1, 1)
        b.add_transaction(t2)
        self.assertFalse(tp.import_transactions(b))
示例#20
0
 def insertTransactions(self, transactions):
     for t in transactions['transactions']:
         try:
             newTransaction = Transaction(tid=t['id'],
                                          iban=t['originIban'],
                                          transaction=t)
             self.session.merge(newTransaction)
             self.session.commit()
         except:
             self.session.rollback()
             print("transaction already exists")
             pass
示例#21
0
    def test_create_block(self):
        b = Block(0, 0, 0)
        self.assertIsInstance(b, Block)

        t = Transaction(0, 1, 2)

        self.assertTrue(b.add_transaction(t))

        header = b.get_header()
        header = json.loads(header)
        self.assertIsInstance(header, dict)
        self.assertIsInstance(header["trans_tree"], str)
示例#22
0
    def test_add_transactions(self):
        t = Tree()
        trans1 = Transaction(0, 1, 2)
        self.assertTrue(t.add_transaction(trans1))
        self.assertEqual(t.depth, 0)

        trans2 = Transaction(1, 2, 3)
        self.assertTrue(t.add_transaction(trans2))
        self.assertEqual(t.depth, 1)

        trans3 = Transaction(2, 3, 4)
        self.assertTrue(t.add_transaction(trans3))
        self.assertEqual(t.depth, 2)

        trans4 = Transaction(3, 4, 5)
        self.assertTrue(t.add_transaction(trans4))
        self.assertEqual(t.depth, 2)

        self.assertEqual(len(list(Tree.walk(t.root))), 7)

        expected_remaining_transactions_before_failure = 2**Tree.MAX_DEPTH - 4

        for i in range(expected_remaining_transactions_before_failure):
            tx = Transaction(0, 0, 1)
            t.add_transaction(tx)

        # Cannot add a fifth transaction, since the MAX_DEPTH equals to 2
        trans5 = Transaction(4, 5, 6)
        self.assertFalse(t.add_transaction(trans5))
        self.assertEqual(t.depth, Tree.MAX_DEPTH)
示例#23
0
 def save_transaction(self, account, detail):
     trading_date = self.convert_trading_date(detail[0].text)
     if trading_date is None:
         return 0
     description = detail[1].text
     account_id = account.get_account_id()
     balance = float(detail[2].text.replace(',', ''))
     reference_number = self.convert_reference_number(description)
     transaction = Transaction(account_id, reference_number, trading_date,
                               balance, description)
     if transaction.save() == 1:
         self.total_transactions = self.total_transactions + 1
         self.email_transport.send_transaction_email(account, transaction)
示例#24
0
    def test_sign_transaction(self):
        w = Wallet()
        w.create_keys()

        t = Transaction(w.get_address(), 1, 1)
        th = t.get_hash()

        self.assertIsNone(t.signature)

        self.assertTrue(w.sign_transaction(t))

        self.assertIsNotNone(t.signature)
        self.assertEqual(t.get_hash(), th)

        self.assertTrue(w.verify_transaction(t))
示例#25
0
    def send_tx(self, destination, quantity, p2p):
        """Perform a transaction."""
        w = self.get_active_wallet()
        magic = p2p.bc.magic
        tx = Transaction(w.get_address(), destination, quantity, magic=magic)
        w.sign_transaction(tx)

        success = p2p.bc.add_transaction(tx)
        if success:
            # broadcast transaction to p2p network
            p2p.broadcast_tx(tx)
            return True
        else:
            logging.debug("Failed to add transaction.")
            return False
示例#26
0
 def save_transaction(self, account, detail):
     trading_date = self.convert_trading_date(
         detail[0].find_element_by_xpath("div[contains(@class,'list-info-txt-sub')]").text)
     description = detail[0].find_element_by_xpath("div[contains(@class,'list-info-txt-main')]").text
     account_id = account.get_account_id()
     reference_number = detail[1].find_element_by_xpath("div[contains(@class,'list-info-txt-sub')]").text.replace(
         'Số tham chiếu: ', '')
     balance = float(
         detail[1].find_element_by_xpath("div[contains(@class,'list-info-txt-main')]").text.replace(',', '').replace(
             ' ', ''))
     transaction = Transaction(account_id, reference_number, trading_date, balance, description)
     print(reference_number)
     if transaction.save() == 1:
         self.total_transactions = self.total_transactions + 1
         self.email_transport.send_transaction_email(account, transaction)
    def save_transaction(self, account, detail):
        trading_date = self.convert_trading_date(detail[0].text)
        reference_number = detail[1].text
        description = detail[3].text
        account_id = account.get_account_id()

        if detail[4].text is not '':
            balance = float(detail[4].text.replace(',', '').replace(' ', ''))
        else:
            balance = float(detail[5].text.replace(',', '').replace(' ', ''))
        transaction = Transaction(account_id, reference_number, trading_date,
                                  balance, description)
        if transaction.save() == 1:
            self.total_transactions = self.total_transactions + 1
            self.email_transport.send_transaction_email(account, transaction)
示例#28
0
    def test_post_new_block(self):
        self.prepare_app()

        # prepare a valid transaction
        w = Wallet()
        w.create_keys()
        tx = Transaction(0, w.get_address(), 1)
        w.sign_transaction(tx)

        client = app.test_client()

        response = client.post("/block/new", data=tx.to_json())
        self.assertEqual(response.status_code, 201)

        b = Block.from_json(response.get_data())
        self.assertTrue(type(b) == Block)
示例#29
0
 def save_transaction(self, account, history):
     trading_date = self.convert_trading_date(history['transferDate'])
     trading_time = history['transferTime']
     description = history['remark']
     if description is None:
         description = 'None'
     account_id = account.get_account_id()
     balance = float(history['amount'])
     if history['dcSign'] == 'D':
         balance = -balance
     reference_number = self.code.generate_code(description +
                                                history['transferDate'])
     created_at = trading_date + ' ' + trading_time
     transaction = Transaction(account_id, reference_number, trading_date,
                               balance, description, created_at)
     if transaction.save() == 1:
         self.total_transactions = self.total_transactions + 1
         self.email_transport.send_transaction_email(account, transaction)
示例#30
0
    def test_post_block(self):
        p2p = ClientAPITest.DummyP2p()
        bc = BlockChain()
        p2p.bc = bc
        app.p2p = p2p

        # make some cash first
        w, cbtx = WalletHelper.generate_wallet_and_coinbase()
        cash_block = bc.new_block(cbtx)
        mine(cash_block)
        bc.discard_block(cash_block)

        txs = []
        for i in range(4):
            tx = Transaction(w.get_address(), i, 0.1)
            w.sign_transaction(tx)
            txs.append(tx)

        # mine current block
        cbtx = WalletHelper.generate_coinbase_with_unused_wallet()
        current_block = bc.new_block(cbtx)
        mine(current_block)
        # put current block in chain and create new block
        bc.discard_block(current_block)

        # create new block
        cbtx = WalletHelper.generate_coinbase_with_unused_wallet()
        b = bc.new_block(cbtx)
        for tx in txs:
            b.add_transaction(tx)

        client = app.test_client()

        # POST new UN-mined block (should fail and return 400 bad request)
        response = client.post("/block", data=b.to_json())
        self.assertEqual(response.status_code, 400)

        # mine new block
        mine(b)

        # POST new mined block (should work this time)
        response = client.post("/block", data=b.to_json())
        self.assertEqual(response.status_code, 201)