Ejemplo n.º 1
0
    def test_transaction_update_amount_exceeds_balance(self):
        sender_wallet = Wallet()
        transaction = Transaction(sender_wallet, "richard_west", 40)

        # Wallet starts with the default starting balance so ensure transaction amount exceeds that.
        with self.assertRaises(InsufficientFundsError):
            transaction.update(sender_wallet, "jing_wang", 99999)
Ejemplo n.º 2
0
    def test_invalid_reward_transaction_bad_amount(self):
        miner_wallet = Wallet()
        reward_transaction = Transaction.reward(miner_wallet)
        reward_transaction.output[miner_wallet.address] = 10000

        with self.assertRaises(MiningRewardError):
            Transaction.is_valid(reward_transaction)
Ejemplo n.º 3
0
    def test_calculate_balance(self):
        blockchain = Blockchain()
        wallet = Wallet()

        self.assertEqual(
            Wallet.calculate_balance(blockchain, wallet.address), STARTING_BALANCE
        )

        amount = 50
        transaction = Transaction(wallet, "recipient_address", amount)
        blockchain.add_block([transaction.serialize()])

        self.assertEqual(
            Wallet.calculate_balance(blockchain, wallet.address),
            STARTING_BALANCE - amount,
        )

        # Add some transactions where wallet receives an amount
        blockchain.add_block(
            [
                Transaction(Wallet(), wallet.address, 30).serialize(),
                Transaction(Wallet(), wallet.address, 75).serialize(),
            ]
        )

        self.assertEqual(
            Wallet.calculate_balance(blockchain, wallet.address),
            STARTING_BALANCE - amount + 30 + 75,
        )
def route_Wallet_Transact():
    transactionData = request.get_json()
    transaction = transactionPool.existingTransaction(wallet.address)
    if not transaction:
        transaction = Transaction(wallet, transactionData['pollID'],
                                  transactionData['option'])
        pubsub.broadcastTransaction(transaction)
    return jsonify(transaction.toJson())
Ejemplo n.º 5
0
 def test_contains_valid_transactions_duplicate_rewards(self):
     self.blockchain.add_block([
         Transaction.reward(Wallet()).serialize(),
         Transaction.reward(Wallet()).serialize(),
     ])
     # Block contains multiple reward transactions so we expect an exception
     with self.assertRaises(ContainsInvalidTransactionError):
         Blockchain.contains_valid_transactions(self.blockchain.chain)
Ejemplo n.º 6
0
    def test_is_valid_bad_output_values(self):
        sender_wallet = Wallet()  # A wallet starts with default value of 1000
        recipient_address = "recipient_address"
        transaction = Transaction(sender_wallet, recipient_address, 100)
        # Replicates a sender trying to inflate own balance
        transaction.output[sender_wallet] = 9999

        with self.assertRaises(TransactionValuesError):
            Transaction.is_valid(transaction)
Ejemplo n.º 7
0
    def test_is_valid_bad_signature(self):
        sender_wallet = Wallet()
        recipient_address = "recipient_address"

        transaction = Transaction(sender_wallet, recipient_address, 100)
        # Corrupt signature. Same transaction output, but signature is from a different wallet.
        transaction.input["signature"] = Wallet().sign(transaction.output)

        with self.assertRaises(TransactionSignatureError):
            Transaction.is_valid(transaction)
Ejemplo n.º 8
0
    def test_contains_valid_transactions_bad_transaction(self):
        bad_transaction = Transaction(Wallet(), "recipient", 1)
        # Use same transaction output but signed by wrong wallet
        bad_transaction.input["signature"] = Wallet().sign(
            bad_transaction.output)

        self.blockchain.add_block([bad_transaction.serialize()])

        with self.assertRaises(TransactionSignatureError):
            Blockchain.contains_valid_transactions(self.blockchain.chain)
Ejemplo n.º 9
0
    def test_reward(self):
        miner_wallet = Wallet()
        transaction = Transaction.reward(miner_wallet)

        self.assertEqual(transaction.input, MINING_REWARD_INPUT)
        self.assertEqual(transaction.output[miner_wallet.address],
                         MINING_REWARD)
Ejemplo n.º 10
0
    def test_transaction(self):
        sender_wallet = Wallet()
        recipient = "richard_west"
        amount = 100
        transaction = Transaction(sender_wallet, recipient, amount)

        # Assert that transaction output contains the correct recipient amount
        self.assertEqual(transaction.output[recipient], amount)

        # Assert that transaction output contains the correct new/remaining balance of senders wallet
        self.assertEqual(transaction.output[sender_wallet.address],
                         sender_wallet.balance - amount)

        # Assert a timestamp exists in the transaction input
        self.assertIn("timestamp", transaction.input)

        # Assert correct values in the transaction input
        self.assertEqual(transaction.input["amount"], sender_wallet.balance)
        self.assertEqual(transaction.input["address"], sender_wallet.address)
        self.assertEqual(transaction.input["public_key"],
                         sender_wallet.public_key)

        # Verify the signature to ensure correctness
        self.assertTrue(
            Wallet.verify(
                transaction.input["public_key"],
                transaction.output,
                transaction.input["signature"],
            ))
Ejemplo n.º 11
0
    def test_contains_valid_transactions_duplicate_transaction(self):
        transaction = Transaction(Wallet(), "recipient", 1).serialize()

        self.blockchain.add_block([transaction, transaction])

        with self.assertRaises(ContainsInvalidTransactionError):
            Blockchain.contains_valid_transactions(self.blockchain.chain)
Ejemplo n.º 12
0
def transaction():
    data = request.get_json()

    # Check to see if a transaction already exists in the pool for this nodes wallet.
    # If it does, no need to create a new transaction, just update the existing one.
    # This will also be broadcast to all nodes and replace the exiting transaction.
    transaction = transaction_pool.get_transaction_for_address(wallet.address)

    if transaction:
        transaction.update(wallet, data["recipient_address"], data["amount"])
    else:
        transaction = Transaction(wallet, data["recipient_address"], data["amount"])

    pubsub.broadcast_transaction(transaction)

    return jsonify(transaction.serialize())
Ejemplo n.º 13
0
    def test_contains_valid_transactions_bad_historic_balance(self):
        wallet = Wallet()
        bad_transaction = Transaction(wallet, "recipient", 1)

        # Tamper with transaction, giving wallet a high amount
        bad_transaction.output[wallet.address] = 1000

        # Ensure input amount and transaction amount are still correct so validation doesn't fail at that point
        bad_transaction.input["amount"] = 1001

        # Re-sign
        wallet.sign(bad_transaction.output)

        self.blockchain.add_block([bad_transaction.serialize()])

        with self.assertRaises(ContainsInvalidTransactionError):
            Blockchain.contains_valid_transactions(self.blockchain.chain)
Ejemplo n.º 14
0
    def test_add_transaction(self):
        transaction_pool = TransactionPool()
        transaction = Transaction(Wallet(), "recipient_address", 10)

        transaction_pool.add_transaction(transaction)

        self.assertIn(transaction.id, transaction_pool.transactions)
        self.assertEqual(transaction_pool.transactions[transaction.id],
                         transaction)
Ejemplo n.º 15
0
def mine():
    # When a block is mined, add the serialized transactions from the transaction pool as it's data.
    transaction_data = transaction_pool.get_serialized_transactions()
    transaction_data.append(Transaction.reward(wallet).serialize())

    transaction_data = [BlockHelper.order_dict(dict) for dict in transaction_data]

    blockchain.add_block(transaction_data)

    block = blockchain.previous_block

    pubsub.broadcast_block(block)

    transaction_pool.clear_transactions(blockchain)

    return jsonify(block.serialize())
Ejemplo n.º 16
0
    def test_clear_transaction(self):
        transaction_pool = TransactionPool()

        transaction1 = Transaction(Wallet(), "recipient_address", 1)
        transaction2 = Transaction(Wallet(), "recipient_address", 2)

        transaction_pool.add_transaction(transaction1)
        transaction_pool.add_transaction(transaction2)

        blockchain = Blockchain()
        blockchain.add_block(
            [transaction1.serialize(),
             transaction2.serialize()])

        self.assertIn(transaction1.id, transaction_pool.transactions)
        self.assertIn(transaction2.id, transaction_pool.transactions)

        transaction_pool.clear_transactions(blockchain)

        self.assertNotIn(transaction1.id, transaction_pool.transactions)
        self.assertNotIn(transaction2.id, transaction_pool.transactions)
Ejemplo n.º 17
0
    def test_transaction_update(self):
        sender_wallet = Wallet()
        first_recipient_address = "richard_west"
        first_recipient_amount = 25

        second_recipient_address = "jing_wang"
        second_recipient_amount = 25

        transaction = Transaction(sender_wallet, first_recipient_address,
                                  first_recipient_amount)

        # Update transaction
        transaction.update(sender_wallet, second_recipient_address,
                           second_recipient_amount)

        # Assert that transaction output contains the correct first recipient amount
        self.assertEqual(transaction.output[first_recipient_address],
                         first_recipient_amount)

        # Assert that transaction output contains the correct second recipients amount
        self.assertEqual(transaction.output[second_recipient_address],
                         second_recipient_amount)

        # Assert that transaction output contains the correct new/remaining balance of senders wallet
        self.assertEqual(
            transaction.output[sender_wallet.address],
            sender_wallet.balance - first_recipient_amount -
            second_recipient_amount,
        )

        # Verify the signature to ensure correctness. This will have been resigned.
        self.assertTrue(
            Wallet.verify(
                transaction.input["public_key"],
                transaction.output,
                transaction.input["signature"],
            ))

        # Test sending an additional amount to the same recipient
        first_recipient_additional_amount = 25
        transaction.update(sender_wallet, first_recipient_address,
                           first_recipient_additional_amount)

        # Assert that transaction output contains the correct first recipient amount
        self.assertEqual(
            transaction.output[first_recipient_address],
            first_recipient_amount + first_recipient_additional_amount,
        )

        # Assert that transaction output contains the correct new/remaining balance of senders wallet
        self.assertEqual(
            transaction.output[sender_wallet.address],
            sender_wallet.balance - first_recipient_amount -
            second_recipient_amount - first_recipient_additional_amount,
        )

        # Verify the signature to ensure correctness. This will have been resigned.
        self.assertTrue(
            Wallet.verify(
                transaction.input["public_key"],
                transaction.output,
                transaction.input["signature"],
            ))
Ejemplo n.º 18
0
 def setUp(self):
     self.blockchain = Blockchain()
     for i in range(4):
         self.blockchain.add_block(
             [Transaction(Wallet(), "recipient_address", i).serialize()])
Ejemplo n.º 19
0
 def test_is_valid_reward_transaction(self):
     reward_transaction = Transaction.reward(Wallet())
     Transaction.is_valid(reward_transaction)
Ejemplo n.º 20
0
    def test_invalid_reward_transaction_extra_recipient(self):
        reward_transaction = Transaction.reward(Wallet())
        reward_transaction.output["recipient_address"] = 50

        with self.assertRaises(MiningRewardError):
            Transaction.is_valid(reward_transaction)
Ejemplo n.º 21
0
 def test_transaction_amount_exceeds_balance(self):
     # Wallet starts with the default starting balance so ensure transaction amount exceeds that.
     with self.assertRaises(InsufficientFundsError):
         Transaction(Wallet(), "richard_west", 99999)
Ejemplo n.º 22
0
        # Synchronize with the blockchain
        blockchain.replace(result_blockchain.chain)
        print("Successfully synchronized the node.")
    except ChainReplacementError as e:
        print("Error synchronizing the node - {}".format(e.message))

if (
    os.environ.get("SEED") == "1"
    or os.environ.get("SEED") == "True"
    or "seed" in sys.argv
):
    for i in range(10):
        blockchain.add_block(
            [
                Transaction(
                    Wallet(), Wallet().address, random.randint(2, 50)
                ).serialize(),
                Transaction(
                    Wallet(), Wallet().address, random.randint(2, 50)
                ).serialize(),
            ]
        )

    for i in range(3):
        transaction_pool.add_transaction(
            Transaction(Wallet(), Wallet().address, random.randint(2, 50))
        )


app.run(port=PORT)
Ejemplo n.º 23
0
 def test_is_valid(self):
     Transaction.is_valid(Transaction(Wallet(), "recipient_address", 100))