def _remove_block_by_hash(block_hash):
        """
        Remove a block and restore it's transactions to the mempool.

        Parameters:
        block_hash  -- hash of block to remove
        """
        rs = RedisService()
        block_dal = BlockServiceDal()
        block = block_dal.find_by_hash(block_hash)

        # put all transaction types back into the mempool
        for transaction in block.transactions:
            TransactionService.add_to_mem_pool(transaction)
        for contract_transaction in block.contract_transactions:
            ContractTransactionService.add_to_mem_pool(contract_transaction)
        for pos_transaction in block.pos_transactions:
            PosTransactionService.add_to_mem_pool(pos_transaction)

        r = redis.StrictRedis()
        # remove from the sorted set of blocks
        r.zrem('blocks', block_hash)
        # remove from the set of blocks at it's height
        r.srem('block:' + str(block.height), block_hash)

        # delete the actual block
        rs.delete_by_key('block:' + block_hash)
def test_pos_author():
    expected = 'c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34'
    r = redis.Redis()
    r.flushdb()
    genesis_block = {
        "height": 0,
        "prev_block": "",
        "_hash": "036850bec30839508bf16badc1efc5c0a31eb82f8b23c524c7ea8cd3d0c8b81f",
        "terminated_contracts": [],
        "signed_contracts": [],
        "contracts": [],
        "pos_transactions": [{
            "from_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "82b2704e380f4bc55c214d44f4cdd698ec3ed5471882d0ae67d80462f13434f5",
            "amount": "100.00000000",
            "signature": "2b6f4ad89868f8a820f682fb580a20b3383e9889b50736a66c8ed441ac4ebb29b7f32d6efe929b05d66de7ac0e20d0ea471f7a1e482f505f2f0df3221d720ba4"
        }],
        "contract_transactions": [],
        "timestamp": 1520135639,
        "owner": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
        "transactions": [{
            "to_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "f54029850ab8ffc3d3f1b210bee0008f1b42aa45e267925f42b80ed9eedb1c20",
            "amount": "1.00000000",
            "from_addr": "",
            "signature": "36a0131c4087dae1d0909baf5ea1b35c9955db7e775646df40d35ad6469469b21439e08263ab7a2fa03f3285fb13ce1b80b399bb6f254694e3f36b9ed5fa6a98"
        }, {
            "to_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "ac32ce4867f65d575d95109b59e713f180541cd5c76ca93dad7cea210ebfa26c",
            "amount": "10.00000000",
            "from_addr": "",
            "signature": "83abc47ca9ad48e91b63d6d4bba28786abfc7345f29f02dbf1c90b4e66f91413cf9a081314095d4bf30d508b9781d035a5816f13ea0c1f1d6b6dd59665697b15"
        }, {
            "to_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "e1e65c22699599507d2621b84a39b02ca525e5d3881c583d4d96cffdf3ceced7",
            "amount": "100.00000000",
            "from_addr": "",
            "signature": "998d03e220b28ad99b2b6d7a00cc1a06443ceea8a3a96acc896c6d8953b44d78f58a6cfbf699d5b4ed35f062cb05674d2f10718ecf44d07a300a781c21734220"
        }, {
            "to_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "b3cf3fba2d1b5e3ca6fee0b5d22a1b81f038ffd9e825119f1a7226e3e10a61ee",
            "amount": "1000.00000000",
            "from_addr": "",
            "signature": "556474088e1f4c75f24cb72db8b0be78134d10d0323c40569207baef1172c43b96596573a446389d2330d781109b76da8725d2ef29876cdd4a198fafc9cbf50f"
        }],
        "signature": "3a3a88935574c820fa70a2408f594585d03988df1980f6c0129b84ee129c322c683de1a7f8be6087d468abbbeb32f2a49eb0ac0c64a9b8de57d43a480ebf4dfc"
    }
    block = Block.from_dict(genesis_block)
    dal_block_service = DalBlockService()
    dal_block_service.store_block(block)
    actual = POSService.get_next_block_author(block)
    print(actual)
    assert actual == expected
def test_store_same_hash():
    b = Block('block_service_test_1', '', '', 'LAST_BLOCK', 0, [], [], [], [],
              [], [])

    bs = BlockService()

    bs.store_block(b)

    new_b = bs.find_by_hash('block_service_test_1')

    assert b.get_sendable() != new_b.get_sendable()
    r = redis.Redis()
    r.flushdb()
Beispiel #4
0
    def get_pos_pool(current_block):
      block_service_dal = BlockServiceDal()
      pos_transactions_before_block = block_service_dal.get_all_pos_transaction(current_block._hash)

      balances = {}
      # balances of all pos'ers
      for key, pos_transaction in pos_transactions_before_block.items():
          # update address current balance
          balances[pos_transaction.from_addr] = pos_transaction.amount + balances.get(pos_transaction.from_addr, 0)
          if balances[pos_transaction.from_addr] == 0:
            balances.pop(pos_transaction.from_addr, None)

      return balances
    def get_transaction_balances():
        block_service_dal = BlockServiceDal()
        last_block_hash = BlockService.get_last_block_hash()
        transactions_before_block = block_service_dal.get_all_transaction_up_to_block(
            last_block_hash)

        balances = {}
        # update balances using all transaction from the past
        for key, transaction in transactions_before_block:
            balances[transaction.from_addr] = balances.get(
                transaction.from_addr, 0) - transaction.amount
            balances[transaction.to_addr] = balances.get(
                transaction.to_addr, 0) + transaction.amount
        return balances
    def get_last_block_hash():
        """
        Gets the highest block's hash.

        Returns:
        string  -- hash of the highest block
        """
        block_dal = BlockServiceDal()
        max_height = block_dal.get_max_block_height()
        latest_blocks = block_dal.find_by_height(max_height)
        if len(latest_blocks) != 0:
            return latest_blocks[0]._hash
        else:
            return ''
 def validate_incoming_block(block):
     block_dal = BlockServiceDal()
     objects = block_dal.get_all_objects_up_to_block(block)
     balances = BlockService.get_all_balances(objects)
     for key in balances.keys():
         balance = balances[key]
         if key != '':
             if type(balance) is tuple:
                 if balance[0] < 0 or balance[1] < 0:
                     return False
             else:
                 if balance < 0:
                     print('insufficient funds on {}'.format(key))
                     return False
     return True
    def verify_transactions(new_block):
        block_service_dal = BlockServiceDal()
        transactions_before_block = block_service_dal.get_all_transaction_up_to_block(
            new_block.prev_block)

        duplicate_transaction = False
        signatures_valid = True
        hashes_valid = True
        # balance for each from_addr in new block
        balances = {}
        for block_transaction in new_block.transactions:
            # update address current balance
            balances[block_transaction.
                     from_addr] = block_transaction.amount + balances.get(
                         block_transaction.from_addr, 0)
            # check that the transaction isnt used in earlier block
            if block_transaction._hash not in transactions_before_block:
                duplicate_transaction = True
                # TODO add logger
            # signature validation
            if new_block.prev_block and not block_transaction.valid_signature(
            ):
                signatures_valid = False
            if not block_transaction.valid_hash():
                hashes_valid = False

        # update balances using all transaction from the past
        for key, transaction in transactions_before_block:
            if transaction.from_addr in balances:
                balances[transaction.from_addr] -= transaction.amount
            if transaction.to_addr in balances:
                balances[transaction.to_addr] += transaction.amount
        # not genesis block
        all_balance_positive = True
        if new_block.prev_block:
            # make sure each balance > 0
            for key, balance in balances:
                if balance < 0:
                    all_balance_positive = False
                    # TODO add logger
                    break
        return duplicate_transaction and all_balance_positive
    def remove_stale_blocks():
        """
        Removes stale, unused blocks.
        Blocks are removed if starting from the newest block, they do not appear when following the chain of previous blocks.
        ie.

        []<-[]<-[]<-[]<-[]<-[]<-[]<-[]<-[]<-[]
                    ^---[]<-[]<-[]<-[]<-[]

        In the above scenario, the bottom chain would be removed, moving all of those transactions back to the mempool.
        """
        block_dal = BlockServiceDal()
        current_height = block_dal.get_max_block_height()
        highest_blocks = block_dal.find_by_height(current_height)

        # if there is only 1 block at the greatest height, we can prune old blocks
        if len(highest_blocks) == 1:
            # get all block hashes
            all_block_hashes = block_dal.get_all_block_hashes()
            correct_block_hashes = set()
            block = highest_blocks[0]
            # add current highest block to the set of correct blocks
            correct_block_hashes.add(block._hash)
            # TODO while there is still a previous block
            while block.prev_block != 'GENESIS_BLOCK':
                block = block_dal.find_by_hash(block.prev_block)
                # add to list of correct blocks
                correct_block_hashes.add(block._hash)

            print("correct_block_hashes len: " +
                  str(len(correct_block_hashes)))
            print("\t" + str(correct_block_hashes))
            # get the difference between the two sets of blocks
            to_remove = set(all_block_hashes) - correct_block_hashes
            print("to_remove: " + str(to_remove))
            # remove each of the blocks
            for block_hash in to_remove:
                print("Removing block: " + block_hash)
                BlockService._remove_block_by_hash(block_hash)
def test_get_store_block():
    test_time = int(time.time())
    t1 = Transaction('transaction_test_1', '', 'matt', 'will', 45, 0,
                     test_time)
    t2 = Transaction('transaction_test_2', '', 'matt', 'denys', 7, 0,
                     test_time)
    t3 = Transaction('transaction_test_3', '', 'denys', 'steven', 33, 0,
                     test_time)
    t4 = Transaction('transaction_test_4', '', 'steven', 'naween', 5040, 0,
                     test_time)
    t5 = Transaction('transaction_test_5', '', 'will', 'naween', 22, 0,
                     test_time)
    t6 = Transaction('transaction_test_6', '', 'naween', 'matt', 588, 0,
                     test_time)
    b = Block('block_service_test_1', '', '', 'LAST_BLOCK', 0,
              [t1, t2, t3, t4, t5, t6], [], [], [], [], [], test_time)
    bs = BlockService()

    bs.store_block(b)

    new_b = bs.find_by_hash('block_service_test_1')
    b_send = b.get_sendable()
    new_send = new_b.get_sendable()
    assert b_send == new_send
 def get_max_height():
     """
     Method Comment
     """
     block_service_dal = BlockServiceDal()
     return block_service_dal.get_max_block_height()
    def get_all_balances(objects=None):
        if objects == None:
            block_dal = BlockServiceDal()
            last_block_hash = BlockService.get_last_block_hash()
            block = block_dal.find_by_hash(last_block_hash)
            objects = block_dal.get_all_objects_up_to_block(block)

        balances = {}

        print('------------TRANSACTION PAYOUT------------')
        # Transactions
        transaction_dict = objects.get('transactions', {})
        for transaction_hash in transaction_dict:
            transaction = transaction_dict.get(transaction_hash)
            balances[transaction.from_addr] = balances.get(
                transaction.from_addr, 0) - transaction.amount
            balances[transaction.to_addr] = balances.get(
                transaction.to_addr, 0) + transaction.amount

        print('------------POS TRANSACTION PAYOUT------------')
        # Proof of Stake Transactions
        pos_transaction_dict = objects.get('pos_transactions', {})
        for pos_transaction_hash in pos_transaction_dict:
            pos_transaction = pos_transaction_dict.get(pos_transaction_hash)
            balances[pos_transaction.from_addr] = balances.get(
                pos_transaction.from_addr, 0) - pos_transaction.amount

        print('------------SIGNED CONTRACT PAYOUT------------')

        # Signed Contracts
        signed_contract_dict = objects.get('signed_contracts', {})
        for signed_contract_hash in signed_contract_dict:
            signed_contract = signed_contract_dict[signed_contract_hash]
            balances[signed_contract.from_addr] = balances.get(
                signed_contract.from_addr, 0) - signed_contract.amount
            print('sc|| from:\t' + signed_contract.from_addr + ": balance:" +
                  str(balances[signed_contract.from_addr]))
            balances[signed_contract._hash] = (
                balances.get(signed_contract._hash,
                             (0, 0))[0] + signed_contract.amount, 0)
            print('sc|| parent:\t' + signed_contract._hash + ": balance:" +
                  str(balances[signed_contract._hash]))

        print('------------CONTRACT TRANSACTION PAYOUT------------')
        # Contract Transactions
        contract_transaction_dict = objects.get('contract_transactions', {})

        temp_contracts = {}

        for key, contract_transaction in contract_transaction_dict.items():
            temp_contracts[contract_transaction.
                           signed_contract_addr] = temp_contracts.get(
                               contract_transaction.signed_contract_addr,
                               list())
            temp_contracts[contract_transaction.signed_contract_addr].append(
                contract_transaction)

        unspent_cts = {}
        for signed_contract_addr in temp_contracts.keys():
            # sort by signed_contract_addr first, then to_symbol, then from_symbol, then price
            contract_transactions = sorted(
                temp_contracts[signed_contract_addr],
                key=lambda ct: (ct.signed_contract_addr, ct.timestamp))
            print('owner:' + signed_contract_addr + "  len=" +
                  str(len(contract_transactions)))
            for contract_transaction in contract_transactions:
                if contract_transaction.from_symbol == 'TPS':
                    # remove from balance
                    print('\tFROM TPS| amount: ' +
                          str(contract_transaction.amount) + ' @ ' +
                          str(contract_transaction.price) + ' ct hash:' +
                          contract_transaction._hash)

                    balances[contract_transaction.signed_contract_addr] = (
                        balances.get(contract_transaction.signed_contract_addr,
                                     (0, 0))[0] - contract_transaction.amount,
                        balances.get(
                            contract_transaction.signed_contract_addr)[1] +
                        contract_transaction.amount)

                    print('\t\t' + contract_transaction.signed_contract_addr +
                          ": balance:" + str(balances[
                              contract_transaction.signed_contract_addr]))

                    unspent_cts[signed_contract_addr] = unspent_cts.get(
                        signed_contract_addr, list())
                    unspent_cts[signed_contract_addr].append(
                        contract_transaction)
                elif contract_transaction.to_symbol == 'TPS':
                    print('\tTO TPS| amount: ' +
                          str(contract_transaction.amount) + ' @ ' +
                          str(contract_transaction.price) + ' ct hash:' +
                          contract_transaction._hash)

                    # sort by price first
                    unspent_cts[signed_contract_addr].sort(
                        key=lambda ct: ct.price)
                    amount_remaining = contract_transaction.amount
                    # iterate through copy of unspent_cts, removing as they are used up
                    for unspent_ct in unspent_cts[signed_contract_addr]:
                        # if took place before current contract transaction
                        if amount_remaining == 0:
                            break
                        if unspent_ct.timestamp <= contract_transaction.timestamp and unspent_ct.amount != 0:
                            if amount_remaining - unspent_ct.amount == 0:
                                print('\t\t->B:S')
                                # sell contract is used up, buy contract is used up
                                amount_remaining -= unspent_ct.amount
                                profit = contract_transaction.price / unspent_ct.price * unspent_ct.amount
                                print('\t\t' +
                                      str(contract_transaction.price) + "/" +
                                      str(unspent_ct.price) + "*" +
                                      str(unspent_ct.amount) + "=" +
                                      str(profit))
                                balances[
                                    contract_transaction.
                                    signed_contract_addr] = (
                                        balances[contract_transaction.
                                                 signed_contract_addr][0] +
                                        profit,
                                        balances[contract_transaction.
                                                 signed_contract_addr][1] -
                                        unspent_ct.amount)
                                print(
                                    '\t\t' +
                                    contract_transaction.signed_contract_addr +
                                    ' amount: ' + str(
                                        balances.get(contract_transaction.
                                                     signed_contract_addr)) +
                                    ' (added: ' + str(profit) + ")")
                                unspent_ct.amount = 0
                                break
                            elif amount_remaining - unspent_ct.amount > 0:
                                print('\t\t->B')
                                # sell contract is not used up, buy contract is used up
                                profit = contract_transaction.price / unspent_ct.price * unspent_ct.amount
                                print('\t\t' +
                                      str(contract_transaction.price) + "/" +
                                      str(unspent_ct.price) + "*" +
                                      str(unspent_ct.amount) + "=" +
                                      str(profit))
                                balances[
                                    contract_transaction.
                                    signed_contract_addr] = (
                                        balances[contract_transaction.
                                                 signed_contract_addr][0] +
                                        profit,
                                        balances[contract_transaction.
                                                 signed_contract_addr][1] -
                                        unspent_ct.amount)
                                print(
                                    '\t\t' +
                                    contract_transaction.signed_contract_addr +
                                    ' amount: ' + str(
                                        balances.get(contract_transaction.
                                                     signed_contract_addr)) +
                                    ' (added: ' + str(profit) + ")")
                                amount_remaining -= unspent_ct.amount
                                unspent_ct.amount = 0
                                continue
                            elif amount_remaining - unspent_ct.amount < 0:
                                print('\t\t->S')
                                # sell contract is used up, buy contract is not
                                profit = contract_transaction.price / unspent_ct.price * amount_remaining
                                print('\t\t' +
                                      str(contract_transaction.price) + "/" +
                                      str(unspent_ct.price) + "*" +
                                      str(amount_remaining) + "=" +
                                      str(profit))
                                balances[
                                    contract_transaction.
                                    signed_contract_addr] = (
                                        balances[contract_transaction.
                                                 signed_contract_addr][0] +
                                        profit,
                                        balances[contract_transaction.
                                                 signed_contract_addr][1] -
                                        amount_remaining)
                                print(
                                    '\t\t' +
                                    contract_transaction.signed_contract_addr +
                                    ' amount: ' + str(
                                        balances.get(contract_transaction.
                                                     signed_contract_addr)) +
                                    ' (added: ' + str(profit) + ")")
                                unspent_ct.amount -= amount_remaining
                                amount_remaining = 0
                                break

        # Terminated Contracts

        print('------------TERMINATED CONTRACT PAYOUT------------')
        term_contract_dict = objects.get('terminated_contracts', {})

        for signed_contract_addr in term_contract_dict.keys():
            print(signed_contract_addr + "||unspent cts len: " +
                  str(len(unspent_cts.get(signed_contract_addr, []))))
            terminated_contract = term_contract_dict.get(signed_contract_addr)

            for unspent_ct in unspent_cts.get(signed_contract_addr, []):
                print('\thash:' + unspent_ct._hash + ' -> amount:' +
                      str(unspent_ct.amount))
                if unspent_ct.timestamp <= terminated_contract.timestamp and unspent_ct.amount != 0:
                    profit = terminated_contract.price / unspent_ct.price * unspent_ct.amount
                    print('\t\t' + str(terminated_contract.price) + "/" +
                          str(unspent_ct.price) + "*" +
                          str(unspent_ct.amount) + "=" + str(profit))

                    balances[signed_contract_addr] = (
                        balances[signed_contract_addr][0] + profit,
                        balances[signed_contract_addr][1] - unspent_ct.amount)
                    unspent_ct.amount = 0
                    print('\t\t' + signed_contract_addr + ' amount: ' +
                          str(balances.get(signed_contract_addr)) +
                          ' (added: ' + str(profit) + ")")
            signed_contract = signed_contract_dict.get(signed_contract_addr,
                                                       None)
            if signed_contract != None:
                base_amount = signed_contract.amount
                final_amount = balances[signed_contract_addr][0]
                profit = final_amount - base_amount
                print('----TOTAL PROFIT:' + str(profit))
                from_addr_profit = 0
                contract_owner_profit = 0
                if profit > 0:
                    # if profit was made, split profit among both accounts
                    # contract owner gets the profit at the specified rate
                    contract_owner_profit = profit * signed_contract.rate
                    # account that signed gets remaining profit
                    from_addr_profit = profit - contract_owner_profit
                else:
                    # if no profit was made, from_addr gets all of the money remaining
                    contract_owner_profit = 0
                    from_addr_profit = final_amount

                balances[signed_contract.parent_owner] = balances.get(
                    signed_contract.parent_owner, 0) + contract_owner_profit
                print('-----' + signed_contract.parent_owner + ' amount: ' +
                      str(balances.get(signed_contract.parent_owner)) +
                      ' (added: ' + str(contract_owner_profit) + ")")
                balances[signed_contract.from_addr] = balances.get(
                    signed_contract.from_addr, 0) + from_addr_profit
                print('-----' + signed_contract.from_addr + ' amount: ' +
                      str(balances.get(signed_contract.from_addr)) +
                      ' (added: ' + str(from_addr_profit) + ")")
                balances[signed_contract._hash] = (0, 0)

        # Contracts
        contract_dict = objects.get('contracts', {})

        # Owners
        # print('------------MINER PAYOUT------------')
        owners = objects.get('owners', [])
        for owner in owners:
            balances[owner] = balances.get(owner, 0) + 10
            # print('owner: ' + owner + ' amount: ' + str(balances[owner]) + ' (added: 10)')

        return balances
 def add_block_to_chain(block):
     """
     Method Comment
     """
     block_service_dal = BlockServiceDal()
     return block_service_dal.store_block(block)
def test_pos_author_two_blocks():
    expected = '23f48768a8e871db2ed721a1e0d250ce41a1fe49765e01e798db0816b781169115e01d3a702934276fa4536bb59527ba0cd7c2fd9eb9e3c13785750c4a9c31d0'
    r = redis.Redis()
    r.flushdb()
    genesis_block = {
        "height": 0,
        "prev_block": "",
        "_hash": "036850bec30839508bf16badc1efc5c0a31eb82f8b23c524c7ea8cd3d0c8b81f",
        "terminated_contracts": [],
        "signed_contracts": [],
        "contracts": [],
        "pos_transactions": [{
            "from_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "82b2704e380f4bc55c214d44f4cdd698ec3ed5471882d0ae67d80462f13434f5",
            "amount": "100.00000000",
            "signature": "2b6f4ad89868f8a820f682fb580a20b3383e9889b50736a66c8ed441ac4ebb29b7f32d6efe929b05d66de7ac0e20d0ea471f7a1e482f505f2f0df3221d720ba4"
        }],
        "contract_transactions": [],
        "timestamp": 1520135639,
        "owner": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
        "transactions": [{
            "to_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "f54029850ab8ffc3d3f1b210bee0008f1b42aa45e267925f42b80ed9eedb1c20",
            "amount": "1.00000000",
            "from_addr": "",
            "signature": "36a0131c4087dae1d0909baf5ea1b35c9955db7e775646df40d35ad6469469b21439e08263ab7a2fa03f3285fb13ce1b80b399bb6f254694e3f36b9ed5fa6a98"
        }, {
            "to_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "ac32ce4867f65d575d95109b59e713f180541cd5c76ca93dad7cea210ebfa26c",
            "amount": "10.00000000",
            "from_addr": "",
            "signature": "83abc47ca9ad48e91b63d6d4bba28786abfc7345f29f02dbf1c90b4e66f91413cf9a081314095d4bf30d508b9781d035a5816f13ea0c1f1d6b6dd59665697b15"
        }, {
            "to_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "e1e65c22699599507d2621b84a39b02ca525e5d3881c583d4d96cffdf3ceced7",
            "amount": "100.00000000",
            "from_addr": "",
            "signature": "998d03e220b28ad99b2b6d7a00cc1a06443ceea8a3a96acc896c6d8953b44d78f58a6cfbf699d5b4ed35f062cb05674d2f10718ecf44d07a300a781c21734220"
        }, {
            "to_addr": "c8fdd9558e4e36d3549c449986c587aa16be67439ed70b8bf1f7e47e8586572f4c821059e4077a94d3e31f1cfa8bccc5c2acf86e955d30ef93633bcabcdc9f34",
            "timestamp": 1520135639,
            "_hash": "b3cf3fba2d1b5e3ca6fee0b5d22a1b81f038ffd9e825119f1a7226e3e10a61ee",
            "amount": "1000.00000000",
            "from_addr": "",
            "signature": "556474088e1f4c75f24cb72db8b0be78134d10d0323c40569207baef1172c43b96596573a446389d2330d781109b76da8725d2ef29876cdd4a198fafc9cbf50f"
        }],
        "signature": "3a3a88935574c820fa70a2408f594585d03988df1980f6c0129b84ee129c322c683de1a7f8be6087d468abbbeb32f2a49eb0ac0c64a9b8de57d43a480ebf4dfc"
    }

    second_block = {
        '_hash': '1048eb4638a45b140a51e7a6d92e972010878d9f05be6fe5c0d20d17b4c26e7a',
        'height': 1,
        'contract_transactions': [],
        'transactions': [{
            'amount': '1.00000000',
            'to_addr': '23f48768a8e871db2ed721a1e0d250ce41a1fe49765e01e798db0816b781169115e01d3a702934276fa4536bb59527ba0cd7c2fd9eb9e3c13785750c4a9c31d0',
            'timestamp': 1520135639,
            '_hash': '188b1e41db5661c87777d7ea3d96cbe0b8858df2cd9c020abb4a424f91c22087',
            'from_addr': '',
            'signature': 'c3d5bdf941cf4a4a95483174e085da38cc4f7decb59cf07ce3ac80623de7e842f46b1d7f6880c358fe4b0ead324ba5af4176743bfd390daf34f79a6ed5e51de8'
        }, {
            'amount': '10.00000000',
            'to_addr': '23f48768a8e871db2ed721a1e0d250ce41a1fe49765e01e798db0816b781169115e01d3a702934276fa4536bb59527ba0cd7c2fd9eb9e3c13785750c4a9c31d0',
            'timestamp': 1520135639,
            '_hash': '004186e14438ea30c3d6ee69dfdc4b66d589e6d5d85c751bfae1220ecdbe8954',
            'from_addr': '',
            'signature': '8d02e40b4923aa1e9869ab48c8de423a510f966e6edb3def1013cf243fe9b7c6ab9c77fa485a02ff03fc769f9e1c36f9085210058d729ed4d71194d7e6c98335'
        }, {
            'amount': '100.00000000',
            'to_addr': '23f48768a8e871db2ed721a1e0d250ce41a1fe49765e01e798db0816b781169115e01d3a702934276fa4536bb59527ba0cd7c2fd9eb9e3c13785750c4a9c31d0',
            'timestamp': 1520135639,
            '_hash': '9463a74fa3e79a5a7f0dee4c8b0d06cdf5624dc529b2d1915cdffabfcdece8ff',
            'from_addr': '',
            'signature': '26962120d2621f61ce4281169d97a06fc508d0246e9779dc3d50a04382f469389166b040d54fab4f00b45fa4ef9ff69296709b1165afb1e695ff893124325e47'
        }, {
            'amount': '1000.00000000',
            'to_addr': '23f48768a8e871db2ed721a1e0d250ce41a1fe49765e01e798db0816b781169115e01d3a702934276fa4536bb59527ba0cd7c2fd9eb9e3c13785750c4a9c31d0',
            'timestamp': 1520135639,
            '_hash': '79ba95186cf2068aa7868057661e315856e44d43a7b3e1fdebfdd9cf7e9679d1',
            'from_addr': '',
            'signature': '5b8dfb857bbee98edc869948bcd90b361d2a9ac48704981cd4a4697ae090b22bf3389b2a0d17ed198f7c9aaa98baa68db5d869279a5065c6ebb44dcb628d06f7'
        }],
        'timestamp': 1520135642,
        'terminated_contracts': [],
        'signed_contracts': [],
        'contracts': [],
        'prev_block': '036850bec30839508bf16badc1efc5c0a31eb82f8b23c524c7ea8cd3d0c8b81f',
        'signature': '829ac7859ca675ea410a781cf30b39fd7864daeda054c50893001da164d04cfacab103dc57cb9d39e545b8533dbd8d54954c3399c01bc356c06801e48242d531',
        'owner': '23f48768a8e871db2ed721a1e0d250ce41a1fe49765e01e798db0816b781169115e01d3a702934276fa4536bb59527ba0cd7c2fd9eb9e3c13785750c4a9c31d0',
        'pos_transactions': [{
            '_hash': '1d1d4247b7611a28e66b114a14445e894dfb7086accb8d02f6f1ac06ff15e049',
            'amount': '100.00000000',
            'from_addr': '23f48768a8e871db2ed721a1e0d250ce41a1fe49765e01e798db0816b781169115e01d3a702934276fa4536bb59527ba0cd7c2fd9eb9e3c13785750c4a9c31d0',
            'signature': 'b7e348c8ebe6e483279a22d1426d31122f14a4ea46b27b9fa85d2cd91b533abc463cafd85ddf524f3677daabf888a146f91721cac26a17568a768a3c18956a15',
            'timestamp': 1520135639
        }]
    }
    dal_block_service = DalBlockService()

    block = Block.from_dict(genesis_block)
    dal_block_service.store_block(block)

    block = Block.from_dict(second_block)
    dal_block_service.store_block(block)

    actual = POSService.get_next_block_author(block)
    assert actual == expected