def add_block(block_pair, recent_hashes, DB={}): """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. """ def median(mylist): if len(mylist) < 1: return 0 return sorted(mylist)[len(mylist) / 2] def block_check(block, DB): def log_(txt): pass #return tools.log(txt) def tx_check(txs): start = copy.deepcopy(txs) out = [] start_copy = [] invalid_because = [''] while start != start_copy: if start == []: return False # Block passes this test start_copy = copy.deepcopy(start) if transactions.tx_check[start[0]['type']](start[0], out, invalid_because, DB): out.append(start.pop()) else: tools.log('invalid tx: ' + str(invalid_because[0])) return True # Block is invalid tools.log('block invalid because it has no txs') return True # Block is invalid if 'error' in block: log_('error in block') return False length = tools.local_get('length') if type(block['length']) != type(1): log_('wrong length type') return False if int(block['length']) != int(length) + 1: log_('wrong longth') return False block_creator_address = tools.addr(block) mint_address = tools.addr( filter(lambda t: t['type'] == 'mint', block['txs'])[0]) if block_creator_address != mint_address: log_('bad mint') return False if block['root_hash'] != tools.db_root(): log_('bad root, have: ' + str(tools.db_root()) + ' need ' + str(block['root_hash'])) return False txs = filter(lambda x: x['type'] == 'mint', block['txs']) if len(txs) != 1: log_('wrong number of mint txs') return False txs = filter(lambda x: x['type'] == 'sign', block['txs']) txs = map(lambda x: len(x['jackpots']), txs) if sum(txs) < custom.signers * 2 / 3 and length > -1: log_('not enough signatures') return False if length >= 0: prev_block = tools.db_get(length) to_hash = { 'prev_hash': prev_block['block_hash'], 'txs': block['txs'] } if not block['block_hash'] == tools.det_hash(to_hash): log_('det hash error') return False #total money spent must be less than the total amount of money in signed deposits for this block. if tx_check(block['txs']): log_('tx check') return False return True if type(block_pair) == type([1, 2, 3]): block = block_pair[0] peer = block_pair[1] else: block = block_pair peer = False if 'block_hash' in block and block['block_hash'] in recent_hashes: #tools.log('we already have that block:' +str(block)) return 0 #tools.log('attempt to add block: ' +str(block)) if block_check(block, DB): #tools.log('add_block: ' + str(block)) tools.db_put(block['length'], block, DB) tools.local_put('height', block['height']) #take money from the creator tools.local_put('length', block['length']) orphans = tools.local_get('txs') orphans = filter(lambda t: t['type'] != 'mint', orphans) tools.local_put('txs', []) for tx in block['txs']: try: transactions.update[tx['type']](tx, DB, True) except Exception as exc: tools.log( 'blockchain broke while adding block. Current datafiles are probably corrupted, and should be deleted.' ) tools.log(exc) error() for tx in orphans: add_tx(tx, DB) peers = tools.local_get('peers') if peer != False and peers[peer]['blacklist'] > 0: peers[peer]['blacklist'] -= 1 tools.local_put( 'peers', peers ) #root hash written on the block is for the state before that block tools.local_put('balance_proofs' + str(block['length']), tools.db_proof(tools.local_get('address'))) return elif not peer == False: peers = tools.local_get('peers') if peer not in peers: peers[peer] = tools.empty_peer() peers[peer]['blacklist'] += 1
def add_block(block_pair, recent_hashes, DB={}): """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. """ def median(mylist): if len(mylist) < 1: return 0 return sorted(mylist)[len(mylist) / 2] def block_check(block, DB): def log_(txt): pass #return tools.log(txt) def tx_check(txs): start = copy.deepcopy(txs) out = [] start_copy = [] invalid_because = [''] while start != start_copy: if start == []: return False # Block passes this test start_copy = copy.deepcopy(start) if transactions.tx_check[start[0]['type']](start[0], out, invalid_because, DB): out.append(start.pop()) else: tools.log('invalid tx: '+str(invalid_because[0])) return True # Block is invalid tools.log('block invalid because it has no txs') return True # Block is invalid if 'error' in block: log_('error in block') return False length =tools.local_get('length') if type(block['length'])!=type(1): log_('wrong length type') return False if int(block['length']) != int(length) + 1: log_('wrong longth') return False block_creator_address=tools.addr(block) mint_address=tools.addr(filter(lambda t: t['type']=='mint', block['txs'])[0]) if block_creator_address!=mint_address: log_('bad mint') return False if block['root_hash']!=tools.db_root(): log_('bad root, have: '+str(tools.db_root())+' need ' +str(block['root_hash'])) return False txs=filter(lambda x: x['type']=='mint', block['txs']) if len(txs)!=1: log_('wrong number of mint txs') return False txs=filter(lambda x: x['type']=='sign', block['txs']) txs=map(lambda x: len(x['jackpots']), txs) if sum(txs)<custom.signers*2/3 and length>-1: log_('not enough signatures') return False if length >= 0: prev_block=tools.db_get(length) to_hash={'prev_hash':prev_block['block_hash'], 'txs':block['txs']} if not block['block_hash']==tools.det_hash(to_hash): log_('det hash error') return False #total money spent must be less than the total amount of money in signed deposits for this block. if tx_check(block['txs']): log_('tx check') return False return True if type(block_pair)==type([1,2,3]): block=block_pair[0] peer=block_pair[1] else: block=block_pair peer=False if 'block_hash' in block and block['block_hash'] in recent_hashes: #tools.log('we already have that block:' +str(block)) return 0 #tools.log('attempt to add block: ' +str(block)) if block_check(block, DB): #tools.log('add_block: ' + str(block)) tools.db_put(block['length'], block, DB) tools.local_put('height', block['height']) #take money from the creator tools.local_put('length', block['length']) orphans = tools.local_get('txs') orphans=filter(lambda t: t['type']!='mint', orphans) tools.local_put('txs', []) for tx in block['txs']: try: transactions.update[tx['type']](tx, DB, True) except Exception as exc: tools.log('blockchain broke while adding block. Current datafiles are probably corrupted, and should be deleted.') tools.log(exc) error() for tx in orphans: add_tx(tx, DB) peers=tools.local_get('peers') if peer!=False and peers[peer]['blacklist']>0: peers[peer]['blacklist']-=1 tools.local_put('peers', peers)#root hash written on the block is for the state before that block tools.local_put('balance_proofs'+str(block['length']),tools.db_proof(tools.local_get('address'))) return elif not peer==False: peers=tools.local_get('peers') if peer not in peers: peers[peer]=tools.empty_peer() peers[peer]['blacklist']+=1
def main(brainwallet, pubkey_flag=False): DB = custom.DB tools.log('custom.current_loc: ' + str(custom.current_loc)) print('starting full node') if not pubkey_flag: privkey = tools.det_hash(brainwallet) pubkey = tools.privtopub(privkey) else: pubkey = brainwallet a = tools.empty_peer() b = custom.peers #b[tools.getPublicIp()+':'+str(custom.port)]=a processes = [ { 'target': db.main, 'args': (DB['heart_queue'], custom.database_name, tools.log, custom.database_port), 'name': 'db' }, { 'target': auto_signer.mainloop, 'args': (), 'name': 'auto_signer' }, { 'target': reward_collector.doit, 'args': (), 'name': 'auto_signer' }, #{'target':tools.heart_monitor, # 'args':(DB['heart_queue'], ), # 'name':'heart_monitor'}, { 'target': blockchain.main, 'args': (DB, ), 'name': 'blockchain' }, { 'target': api.main, 'args': (DB, DB['heart_queue']), 'name': 'api' }, { 'target': peers_check.main, 'args': (b, DB), 'name': 'peers_check' }, { 'target': networking.serve_forever, 'args': (peer_recieve_func, custom.port, DB['heart_queue'], True), 'name': 'peer_recieve' } ] cmds = [] cmd = multiprocessing.Process(**processes[0]) cmd.start() cmds.append(cmd) tools.log('starting ' + cmd.name) time.sleep(4) b = tools.db_existence(0) #def empty_memoized(): return({'blockcount':-3000}) if not b: tools.local_put('length', -1) tools.local_put('height', -1) tools.local_put('memoized_votes', {}) tools.local_put('txs', []) tools.local_put('peers', {}) tools.local_put('targets', {}) tools.local_put('times', {}) tools.local_put('mine', False) tools.local_put('my_sign_txs', {}) #empty_memoized()) tools.local_put('secrets', {}) money = db.default_entry() money['amount'] += custom.all_money tools.db_put(custom.creator, money) tools.local_put('stop', False) tools.log('stop: ' + str(tools.local_get('stop'))) for process in processes[1:]: cmd = multiprocessing.Process(**process) cmd.start() cmds.append(cmd) tools.log('starting ' + cmd.name) if not pubkey_flag: tools.local_put('privkey', privkey) else: tools.local_put('privkey', 'Default') Address = tools.make_address([pubkey], 1) tools.local_put('address', Address) a = tools.db_proof(Address) tools.local_put('balance_proofs-1', a) tools.log('stop: ' + str(tools.local_get('stop'))) while not tools.local_get('stop'): time.sleep(0.5) tools.log('about to stop threads') DB['heart_queue'].put('stop') for p in [[custom.port, '127.0.0.1'], [custom.api_port, '127.0.0.1']]: networking.connect('stop', p[0], p[1]) cmds.reverse() for cmd in cmds[:-1]: cmd.join() tools.log('stopped a thread: ' + str(cmd)) time.sleep(2) networking.connect('stop', custom.database_port, '127.0.0.1') cmds[-1].join() tools.log('stopped a thread: ' + str(cmds[-1])) tools.log('all threads stopped') sys.exit(0)
def main(brainwallet, pubkey_flag=False): DB=custom.DB tools.log('custom.current_loc: ' +str(custom.current_loc)) print('starting full node') if not pubkey_flag: privkey=tools.det_hash(brainwallet) pubkey=tools.privtopub(privkey) else: pubkey=brainwallet a=tools.empty_peer() b=custom.peers #b[tools.getPublicIp()+':'+str(custom.port)]=a processes= [ {'target': db.main, 'args': (DB['heart_queue'], custom.database_name, tools.log, custom.database_port), 'name': 'db'}, {'target': auto_signer.mainloop, 'args': (), 'name': 'auto_signer'}, {'target': reward_collector.doit, 'args': (), 'name': 'auto_signer'}, #{'target':tools.heart_monitor, # 'args':(DB['heart_queue'], ), # 'name':'heart_monitor'}, {'target': blockchain.main, 'args': (DB,), 'name': 'blockchain'}, {'target': api.main, 'args': (DB, DB['heart_queue']), 'name': 'api'}, {'target': peers_check.main, 'args': (b, DB), 'name': 'peers_check'}, {'target': networking.serve_forever, 'args': (peer_recieve_func, custom.port, DB['heart_queue'], True), 'name': 'peer_recieve'} ] cmds=[] cmd=multiprocessing.Process(**processes[0]) cmd.start() cmds.append(cmd) tools.log('starting '+cmd.name) time.sleep(4) b=tools.db_existence(0) #def empty_memoized(): return({'blockcount':-3000}) if not b: tools.local_put('length', -1) tools.local_put('height', -1) tools.local_put('memoized_votes', {}) tools.local_put('txs', []) tools.local_put('peers', {}) tools.local_put('targets', {}) tools.local_put('times', {}) tools.local_put('mine', False) tools.local_put('my_sign_txs', {})#empty_memoized()) tools.local_put('secrets', {}) money=db.default_entry() money['amount']+=custom.all_money tools.db_put(custom.creator, money) tools.local_put('stop', False) tools.log('stop: ' +str(tools.local_get('stop'))) for process in processes[1:]: cmd=multiprocessing.Process(**process) cmd.start() cmds.append(cmd) tools.log('starting '+cmd.name) if not pubkey_flag: tools.local_put('privkey', privkey) else: tools.local_put('privkey', 'Default') Address=tools.make_address([pubkey], 1) tools.local_put('address', Address) a=tools.db_proof(Address) tools.local_put('balance_proofs-1', a) tools.log('stop: ' +str(tools.local_get('stop'))) while not tools.local_get('stop'): time.sleep(0.5) tools.log('about to stop threads') DB['heart_queue'].put('stop') for p in [[custom.port, '127.0.0.1'], [custom.api_port, '127.0.0.1']]: networking.connect('stop', p[0], p[1]) cmds.reverse() for cmd in cmds[:-1]: cmd.join() tools.log('stopped a thread: '+str(cmd)) time.sleep(2) networking.connect('stop', custom.database_port, '127.0.0.1') cmds[-1].join() tools.log('stopped a thread: '+str(cmds[-1])) tools.log('all threads stopped') sys.exit(0)