Example #1
0
    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)
Example #2
0
    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)
Example #3
0
 def create_test_transaction(self, timestamp=None):
     if timestamp == None:
         timestamp = ChainUtil.generate_timestamp()
     transaction = Transaction(
         None,
         TransactionInput(timestamp, self.amount, self.address,
                          self.signature),
         [TransactionOutput(self.amount, self.address)],
     )
     return transaction
Example #4
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())
Example #5
0
 def create_test_transaction(self,
                             timestamp=None,
                             amount=0,
                             address='myaddress',
                             signature='mysignature'):
     if timestamp == None:
         timestamp = ChainUtil.generate_timestamp()
     transaction = Transaction(
         None,
         TransactionInput(timestamp, amount, address, signature),
         [TransactionOutput(amount, address)],
     )
     return transaction
Example #6
0
 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)
Example #7
0
 def mine(self):
     # 1. Add reward for the miner
     # 2. Create/mine block from valid transactions
     # 3. Sync the chain with other p2p servers (TODO: add after finishing proof of concept)
     # 4. Clear the local pool
     # 5. Broadcast that pool is clear to other nodes via p2p
     height = len(self.block_chain.chain) + 1
     valid_transactions = self.transaction_pool.get_valid_transactions()
     reward_transaction = Transaction.create_reward_transaction(height, self.wallet)
     valid_transactions.append(reward_transaction)
     block = self.block_chain.append_block(valid_transactions)
     # TODO: Broadcast Sync Chain action across p2p nodes
     self.transaction_pool.clear()
     # TODO: Broadcast Clear Transaction Pool action across p2p nodes
     return block
Example #8
0
 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)
Example #9
0
 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())
Example #10
0
 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
Example #11
0
 def _test_generate_genesis_block(self):
     pb = Block(
         ChainUtil.generate_timestamp(), None,
         '0000000000000000000000000000000000000000000000000000000000000000',
         0, 3, [])
     address = ('000000000000000000000000000000000000000000000000000'
                '0000000000000556e757365642067656e6573697320626c6f63'
                '6b2061646472657373202d2031312f30332f323031382032333'
                'a3036204553540000000000')
     signature = '47656e6573697320626c6f636b2063726561746564206f6e2031312f30332f32303138'
     timestamp = 1541319432152
     transaction = Transaction(
         None,
         TransactionInput(timestamp, amount, address, signature),
         [TransactionOutput(amount, address)],
     )
     block = Block.mine(pb, [transaction])
Example #12
0
 def genesis(cls):
     # 0000ef80bfa3b57331b1200969d8044267ce1af1a4d2980308e2b6af4569ff33
     timestamp = 1541320453883
     nonce = 46645
     difficulty = 4
     prev_hash = '0000000000000000000000000000000000000000000000000000000000000000'
     address = ('00000000000000000000000000000000000000000000'
                '00000000000000000000556e757365642067656e6573'
                '697320626c6f636b2061646472657373202d2031312f'
                '30332f323031382032333a3036204553540000000000')
     signature = '47656e6573697320626c6f636b2063726561746564206f6e2031312f30332f32303138'
     amount = 0
     transaction = Transaction(
         '7f5f7b62dfe211e89b13685b35ad2541',
         TransactionInput(1541319432152, amount, address, signature),
         [TransactionOutput(amount, address)])
     data = [transaction]
     hash = Block.create_hash(timestamp, prev_hash, nonce, difficulty, data)
     return cls(timestamp, prev_hash, hash, nonce, difficulty, data)
Example #13
0
    def create_transaction(self, recipient_address, amount, transaction_pool,
                           block_chain):
        self.balance = self.calculate_balance(block_chain)

        if amount > self.balance:
            raise ValueError('Amount {} exceeds wallet balance of {}'.format(
                amount, self.balance))

        # ##########################################################################################
        # Optimization code
        # We make sure that multiple TransactionOutput objects are appended to existing transactions
        # ##########################################################################################
        transaction = transaction_pool.find_by_public_key(self.public_key_hex)

        if transaction:
            transaction.update(self, recipient_address, amount)
        else:
            transaction = Transaction.create_transaction(
                self, recipient_address, amount)
            transaction_pool.add(transaction)
        # ##########################################################################################

        return transaction
Example #14
0
 def from_database_format(cls, item):
     transactions = json.loads(item.data)
     return cls(
         item.timestamp, item.prev_hash, item.hash, item.nonce,
         item.difficulty,
         [Transaction.from_database_format(data) for data in transactions])