Пример #1
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,
        )
Пример #2
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)
Пример #3
0
class TestBlockchain(TestCase):
    def setUp(self):
        self.blockchain = Blockchain()
        for i in range(4):
            self.blockchain.add_block(
                [Transaction(Wallet(), "recipient_address", i).serialize()])

    def test_instance(self):
        self.assertEqual(Blockchain().genesis, Block.genesis())

    def test_get_previous_block(self):
        self.assertEqual(self.blockchain.previous_block,
                         self.blockchain.chain[-1])

    def test_add_block(self):
        self.assertEqual(len(self.blockchain.chain), 5)

        self.blockchain.add_block("SHUcoin")

        self.assertEqual(len(self.blockchain.chain), 6)
        self.assertEqual(self.blockchain.previous_block.data, "SHUcoin")

    def test_is_valid(self):
        Blockchain.is_valid(self.blockchain.chain)

    def test_is_valid_bad_genesis(self):
        self.blockchain.chain[0].data = "Invalid data"

        with self.assertRaises(GenesisError):
            Blockchain.is_valid(self.blockchain.chain)

    def test_replace(self):
        # Create a new blockchain, only has genesis
        blockchain = Blockchain()

        # Try replacing chain with longer chain
        blockchain.replace(self.blockchain.chain)

        # Assert that chain was replaced by longer one
        self.assertEqual(blockchain.chain, self.blockchain.chain)

    def test_replace_incoming_not_longer(self):
        # Create a new blockchain, only has genesis
        incoming = Blockchain()

        with self.assertRaisesRegex(
                ChainReplacementError,
                "Cannot replace. Incoming chain must be longer than local chain.",
        ):
            # Try replacing chain with shorter chain
            self.blockchain.replace(incoming.chain)

    def test_replace_incoming_not_valid(self):
        # Create a new blockchain, only has genesis
        blockchain = Blockchain()

        self.blockchain.chain[1].data = "Some bad data"

        with self.assertRaises(ChainReplacementError):
            # Try replacing chain with shorter chain
            blockchain.replace(self.blockchain.chain)

    def test_contains_valid_transactions(self):
        Blockchain.contains_valid_transactions(self.blockchain.chain)

    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)

    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)

    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)

    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)
Пример #4
0
        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)

if __name__ == "__main__":
    pass