Пример #1
0
 def make_block(self, prev_block, txs, pubkey):
     """
     After mempool changes at 0.011c version, make block must select valid transactions.
     Mempool is mixed and not all transactions may be valid at the same time.
     Miner creates a block by adding transactions that are valid together.
     :param prev_block:
     :param txs:
     :param pubkey:
     :return:
     """
     leng = int(prev_block['length']) + 1
     target_ = self.blockchain.target(leng)
     diffLength = tools.hex_sum(prev_block['diffLength'],
                                tools.hex_invert(target_))
     txs = self.statedb.get_valid_txs_for_next_block(txs, leng)
     txs = [self.make_mint(pubkey)] + txs
     out = {
         'version': custom.version,
         'txs': txs,
         'length': leng,
         'time': time.time(),
         'diffLength': diffLength,
         'target': target_,
         'prevHash': tools.det_hash(prev_block)
     }
     return out
Пример #2
0
 def genesis(self, pubkey):
     target_ = self.blockchain.target(0)
     out = {
         'version': custom.version,
         'length': 0,
         'time': time.time(),
         'target': target_,
         'diffLength': tools.hex_invert(target_),
         'txs': [self.make_mint(pubkey)]
     }
     return out
Пример #3
0
 def make_block(self, prev_block, txs, pubkey):
     leng = int(prev_block['length']) + 1
     target_ = self.blockchain.target(leng)
     diffLength = tools.hex_sum(prev_block['diffLength'],
                                tools.hex_invert(target_))
     out = {
         'version': custom.version,
         'txs': txs + [self.make_mint(pubkey)],
         'length': leng,
         'time': time.time(),
         'diffLength': diffLength,
         'target': target_,
         'prevHash': tools.det_hash(prev_block)
     }
     return out
Пример #4
0
        def estimate_target():
            """
            We are actually interested in the average number of hashes required to
            mine a block. number of hashes required is inversely proportional
            to target. So we average over inverse-targets, and inverse the final
            answer. """
            def sumTargets(l):
                if len(l) < 1:
                    return 0
                while len(l) > 1:
                    l = [tools.hex_sum(l[0], l[1])] + l[2:]
                return l[0]

            targets = self.recent_blockthings('targets', custom.history_length)
            w = weights(len(targets))  # should be rat instead of float
            tw = sum(w)
            targets = list(map(tools.hex_invert, targets))

            weighted_targets = [
                targetTimesFloat(targets[i], w[i] / tw)
                for i in range(len(targets))
            ]
            return tools.hex_invert(sumTargets(weighted_targets))
Пример #5
0
    def add_block(self, block):
        """Attempts adding a new block to the blockchain.
         Median is good for weeding out liars, so long as the liars don't have 51%
         hashpower. """

        length = self.db.get('length')

        if int(block['length']) < int(length) + 1:
            return 1
        elif int(block['length']) > int(length) + 1:
            return 2

        if (length >= 0 and block['diffLength'] != tools.hex_sum(self.db.get('diffLength'), tools.hex_invert(block['target']))) \
                or (length < 0 and block['diffLength'] != tools.hex_invert(block['target'])):
            tools.log(block['diffLength'])
            tools.log(
                tools.hex_sum(self.db.get('diffLength'),
                              tools.hex_invert(block['target'])))
            tools.log(block['length'])
            tools.log('difflength is wrong')
            return 3

        if length >= 0 and tools.det_hash(
                self.db.get(length)) != block['prevHash']:
            tools.log('prevhash different')
            return 3

        nonce_and_hash = tools.hash_without_nonce(block)
        if tools.det_hash(nonce_and_hash) > block['target']:
            tools.log('hash value does not match the target')
            return 3

        if block['target'] != self.target(block['length']):
            tools.log('block: ' + str(block))
            tools.log('target: ' + str(self.target(block['length'])))
            tools.log('wrong target')
            return 3

        recent_time_values = self.recent_blockthings(
            'times', custom.median_block_time_limit, self.db.get('length'))
        median_block = tools.median(recent_time_values)
        if block['time'] < median_block:
            tools.log('Received block is generated earlier than median.')
            return 3

        if not self.account.update_accounts_with_block(
                block, add_flag=True, simulate=True):
            tools.log('Received block failed transactions check.')
            return 3

        self.db.put(block['length'], block)
        self.db.put('length', block['length'])
        self.db.put('diffLength', block['diffLength'])

        orphans = self.tx_pool_pop_all()

        self.account.update_accounts_with_block(block, add_flag=True)

        for orphan in sorted(orphans, key=lambda x: x['count']):
            self.add_tx(orphan)

        return 0
    def add_block(self, block):
        """Attempts adding a new block to the blockchain.
         Median is good for weeding out liars, so long as the liars don't have 51%
         hashpower. """

        length = self.db.get('length')
        block_at_length = self.get_block(length)

        if int(block['length']) < int(length) + 1:
            return 1
        elif int(block['length']) > int(length) + 1:
            return 2

        tools.echo('add block: ' + str(block['length']))

        if (length >= 0 and block['diffLength'] != tools.hex_sum(block_at_length['diffLength'],
                                                                 tools.hex_invert(block['target']))) \
                or (length < 0 and block['diffLength'] != tools.hex_invert(block['target'])):
            tools.log(block['diffLength'])
            tools.log(
                tools.hex_sum(self.db.get('diffLength'),
                              tools.hex_invert(block['target'])))
            tools.log(block['length'])
            tools.log('difflength is wrong')
            return 3

        if length >= 0 and tools.det_hash(
                block_at_length) != block['prevHash']:
            tools.log('prevhash different')
            return 3

        nonce_and_hash = tools.hash_without_nonce(block)
        if tools.det_hash(nonce_and_hash) > block['target']:
            tools.log('hash value does not match the target')
            return 3

        if block['target'] != self.target(block['length']):
            tools.log('block: ' + str(block))
            tools.log('target: ' + str(self.target(block['length'])))
            tools.log('wrong target')
            return 3
        """
        recent_time_values = self.recent_blockthings('times', custom.median_block_time_limit)
        median_block = tools.median(recent_time_values)
        if block['time'] < median_block:
            tools.log('Received block is generated earlier than median.')
            return 3
        """

        # Check that block includes exactly one mint transaction
        if 'txs' not in block:
            tools.log(
                'Received block does not include txs. At least a coinbase tx must be present'
            )
            return 3

        # Sum of all mint type transactions must be one
        mint_present = sum(
            [0 if tx['type'] != 'mint' else 1 for tx in block['txs']])
        if mint_present != 1:
            tools.log('Received block includes wrong amount of mint txs')
            return 3

        for tx in block['txs']:
            if not BlockchainService.tx_integrity_check(tx).getFlag():
                tools.log('Received block failed special txs check.')
                return 3

        if not self.statedb.update_database_with_block(block):
            return 3

        self.put_block(block['length'], block)
        self.db.put('length', block['length'])
        self.db.put('diffLength', block['diffLength'])

        orphans = self.tx_pool_pop_all()

        for orphan in sorted(orphans,
                             key=lambda x: x['count'] if 'count' in x else -1):
            self.tx_queue.put(orphan)

        tools.techo('add block: ' + str(block['length']))
        return 0