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_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)
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)
PORT = ROOT_PORT # For convenience, it is easier to pass the 'peer' option when running the file from the command line. This may need to change in future. if ( os.environ.get("PEER") == "1" or os.environ.get("PEER") == "True" or "peer" in sys.argv ): PORT = random.randint(5001, 6000) result = requests.get("http://localhost:{}/blockchain".format(ROOT_PORT)) result_blockchain = Blockchain.deserialize(result.json()) try: # 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(),