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
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
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
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))
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