def test_transaction_pool(self): pool = TransactionPool() wallet = Wallet(self.test_password, self.test_private_key_pem, self.test_public_key_pem, balance=TEST_WALLET_BALANCE) amount1 = 50 transaction1 = Transaction.create_transaction( wallet, self.test_recipient_address1, amount1) pool.add(transaction1) transaction2 = Transaction.create_transaction( wallet, self.test_recipient_address1, amount1) pool.add(transaction2) amount2 = 30 transaction3 = Transaction.create_transaction( wallet, self.test_recipient_address1, amount2) transaction3.transaction_id = transaction1.transaction_id # Set tx3 id to tx1 id pool.add(transaction3) self.assertTrue(len(pool.transactions) == 2) self.assertEqual( pool.transactions[transaction1.transaction_id].outputs[0].address, wallet.public_key_hex) self.assertEqual( pool.transactions[transaction1.transaction_id].outputs[0].amount, wallet.balance - amount2) self.assertEqual( pool.transactions[transaction1.transaction_id].outputs[1].address, self.test_recipient_address1) self.assertEqual( pool.transactions[transaction1.transaction_id].outputs[1].amount, amount2)
def test_valid_transactions(self): pool = TransactionPool() wallet = Wallet(self.test_password, self.test_private_key_pem, self.test_public_key_pem, balance=TEST_WALLET_BALANCE) amount1 = 50 transaction1 = Transaction.create_transaction( wallet, self.test_recipient_address1, amount1) pool.add(transaction1) transaction2 = Transaction.create_transaction( wallet, self.test_recipient_address1, amount1) pool.add(transaction2) transactions = pool.get_valid_transactions() self.assertTrue(len(transactions) == 2) # Let's corrupt balance transaction1.outputs[0].amount = 1000 transactions = pool.get_valid_transactions() self.assertTrue(len(transactions) == 1) # Let's corrupt signature transaction2.outputs[0].address = 'corrupted-address' transactions = pool.get_valid_transactions() self.assertTrue(len(transactions) == 0)
def test_transaction_verification(self): amount = 50 wallet = Wallet(self.test_password, self.test_private_key_pem, self.test_public_key_pem, balance=TEST_WALLET_BALANCE) transaction = Transaction.create_transaction( wallet, self.test_recipient_address1, amount) self.assertTrue(transaction.verify()) transaction.outputs[0].address = 'changed public key' self.assertFalse(transaction.verify())
def test_reward_transactions(self): miner_wallet = Wallet(self.test_password, self.test_private_key_pem, self.test_public_key_pem, balance=TEST_WALLET_BALANCE) transaction1 = Transaction.create_reward_transaction(1, miner_wallet) self.assertEqual(transaction1.outputs[0].address, miner_wallet.public_key_hex) self.assertEqual(transaction1.outputs[0].amount, MINING_REWARD) self.assertEqual(transaction1.input.address, REWARD_TRANSACTION_ADDRESS) self.assertEqual(transaction1.input.signature, REWARD_TRANSACTION_SIGNATURE)
def test_create_transaction(self): amount = 50 wallet = Wallet(self.test_password, self.test_private_key_pem, self.test_public_key_pem, balance=TEST_WALLET_BALANCE) transaction = Transaction.create_transaction( wallet, self.test_recipient_address1, amount) self.assertEqual(transaction.outputs[0].address, wallet.public_key_hex) self.assertEqual(transaction.outputs[0].amount, wallet.balance - amount) self.assertEqual(transaction.outputs[1].address, self.test_recipient_address1) self.assertEqual(transaction.outputs[1].amount, amount) self.assertEqual(transaction.input.amount, wallet.balance)
def test_transaction_update(self): amount1 = 50 wallet = Wallet(self.test_password, self.test_private_key_pem, self.test_public_key_pem, balance=TEST_WALLET_BALANCE) transaction = Transaction.create_transaction( wallet, self.test_recipient_address1, amount1) self.assertTrue(transaction.verify()) amount2 = 30 transaction.update(wallet, self.test_recipient_address2, amount2) self.assertTrue(transaction.verify()) self.assertEqual(transaction.outputs[0].amount, wallet.balance - (amount1 + amount2)) transaction.outputs[0].amount = 10000000 self.assertFalse(transaction.verify())
def load_miner(cls, session, wallet_name): manager = Manager(session) wallet = manager.load_wallet(wallet_name) if wallet: chain = [] for block in manager.load_blocks(): chain.append(Block.from_database_format(block)) transactions = [] for transaction in manager.load_transactions(): transactions.append(Transaction.from_database_format(transaction)) miner = cls( Wallet.from_database_format(wallet), BlockChain(chain=chain), TransactionPool(transactions=transactions) ) return miner return None
def test_multiple_miners(self): transaction_pool = TransactionPool() block_chain = BlockChain() wallet1 = Wallet.create_wallet(self.password, balance=TEST_WALLET_BALANCE) miner1 = Miner(wallet1, block_chain, transaction_pool) wallet2 = Wallet.create_wallet(self.password, balance=TEST_WALLET_BALANCE) miner2 = Miner(wallet2, block_chain, transaction_pool) # Send money from miner1 to miner2 amount1 = 20 wallet1.create_transaction(miner2.wallet.public_key_hex, amount1, transaction_pool, block_chain) # Send money from miner2 to miner1 amount2 = 30 wallet2.create_transaction(miner1.wallet.public_key_hex, amount2, transaction_pool, block_chain) # Mine new block (miner1) miner1.mine() # Pool should be clear and transactions should be included into the mined block self.assertTrue(len(transaction_pool.transactions) == 0) self.assertTrue(len(block_chain.chain) == 2) # Send money from miner2 to miner1 amount3 = 3 wallet2.create_transaction(miner1.wallet.public_key_hex, amount3, transaction_pool, block_chain) # Send money from miner1 to miner2 amount4 = 100 wallet1.create_transaction(miner2.wallet.public_key_hex, amount4, transaction_pool, block_chain) self.assertEqual( miner1.wallet.balance, TEST_WALLET_BALANCE - amount1 + amount2 + MINING_REWARD) self.assertEqual(miner2.wallet.balance, TEST_WALLET_BALANCE + amount1 - amount2) # Mine new block (miner2) miner2.mine() time.sleep(2) # Pool should be clear and transactions should be included into the mined block self.assertTrue(len(transaction_pool.transactions) == 0) self.assertTrue(len(block_chain.chain) == 3) amount5 = 1 wallet2.create_transaction(miner1.wallet.public_key_hex, amount5, transaction_pool, block_chain) amount6 = 1 wallet1.create_transaction(miner2.wallet.public_key_hex, amount6, transaction_pool, block_chain) self.assertEqual( miner2.wallet.balance, TEST_WALLET_BALANCE + amount1 - amount2 - amount3 + amount4 + MINING_REWARD) self.assertEqual( miner1.wallet.balance, TEST_WALLET_BALANCE - amount1 + amount2 + MINING_REWARD + amount3 - amount4)
def create_miner(cls, wallet_password, wallet_name=None, wallet_balance=0): wallet = Wallet.create_wallet(wallet_password, name=wallet_name, balance=wallet_balance) block_chain = BlockChain() transaction_pool = TransactionPool() miner = cls(wallet, block_chain, transaction_pool) return miner