def mine_client(pubkey): def readable_time(mytime): return time.strftime("%D %H:%M", time.localtime(int(mytime))) print 'client miner started' executable = copy.deepcopy(custom.client_executable) executable.append(pubkey) miner_process = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) print executable tools.db_put('miner_id', miner_process.pid) while True: nextline = miner_process.stdout.readline() if miner_process.poll() is not None: break nextline = nextline.rstrip('\n') try: status = json.loads(nextline)[u'status'] tools.db_put('miner_status', status) tools.db_put('minestatustext', readable_time(time.time()) + ' ' + status + '\n' + tools.db_get('minestatustext')) except: pass # wait for process to actually finish returncode = miner_process.poll() tools.db_put('miner_id', -1) if returncode == 0: print 'Mining is done succesfully' else: print 'Mining is finished prematurely.' tools.db_put('mine', False)
def main_once(DB): DB['heart_queue'].put('peers check') pr = tools.db_get('peers_ranked') pr = sorted(pr, key=lambda r: r[2]) pr.reverse() time.sleep(0.05) if DB['suggested_blocks'].empty() and tools.db_get('length') > 3: time.sleep(10) i = 0 while not DB['suggested_blocks'].empty(): i += 1 time.sleep(0.1) if i % 100 == 0: DB['heart_queue'].put('peers check') DB['heart_queue'].put('peers check') i = exponential_random(3.0 / 4) % len(pr) t1 = time.time() r = peer_check(i, pr, DB) t2 = time.time() p = pr[i][0] pr = tools.db_get('peers_ranked') for peer in pr: if peer[0] == p: pr[i][1] *= 0.8 if r == 0: pr[i][1] += 0.2 * (t2 - t1) else: pr[i][1] += 0.2 * 30 tools.db_put('peers_ranked', pr) #BAD pr got edited in peer_check() DB['heart_queue'].put('peers check')
def main_once(DB): DB['heart_queue'].put('peers check') pr=tools.db_get('peers_ranked') pr=sorted(pr, key=lambda r: r[2]) pr.reverse() time.sleep(0.05) if DB['suggested_blocks'].empty() and tools.db_get('length')>3: time.sleep(10) i=0 while not DB['suggested_blocks'].empty(): i+=1 time.sleep(0.1) if i%100==0: DB['heart_queue'].put('peers check') DB['heart_queue'].put('peers check') i=exponential_random(3.0/4)%len(pr) t1=time.time() r=peer_check(i, pr, DB) t2=time.time() pr[i][1]*=0.8 if r==0: pr[i][1]+=0.2*(t2-t1) else: pr[i][1]+=0.2*30 tools.db_put('peers_ranked', pr) DB['heart_queue'].put('peers check')
def add_peer(peer, current_peers=0): if current_peers==0: current_peers=tools.db_get('peers_ranked') if peer not in map(lambda x: x[0][0], current_peers): tools.log('add peer') current_peers.append([peer, 5, '0', 0]) tools.db_put(current_peers, 'peers_ranked')
def main_once(peers, DB): #DB['peers_ranked']=sorted(DB['peers_ranked'], key=lambda r: r[1]) pr = tools.db_get('peers_ranked') pr = sorted(pr, key=lambda r: r[1]) if DB['suggested_blocks'].empty(): time.sleep(10) i = 0 while not DB['suggested_blocks'].empty(): i += 1 time.sleep(0.1) if i % 100 == 0: DB['heart_queue'].put('peers check') #tools.log('suggested_blocks emptied at : ' +str(time.time())) DB['heart_queue'].put('peers check') i = exponential_random(map(lambda x: x[1], pr)) t1 = time.time() r = peer_check(pr[i][0], DB) t2 = time.time() pr[i][1] *= 0.8 if r == 0: pr[i][1] += 0.2 * (t2 - t1) else: pr[i][1] += 0.2 * 30 tools.db_put('peers_ranked', pr) DB['heart_queue'].put('peers check')
def delete_block(DB): """ Removes the most recent block from the blockchain. """ length = tools.db_get('length') if length < 0: return try: ts = tools.db_get('times') ts.pop(str(length)) tools.db_put('times', ts) except: pass block = tools.db_get(length, DB) orphans = tools.db_get('txs') tools.db_put('txs', []) for tx in block['txs']: orphans.append(tx) tools.db_put('add_block', False) transactions.update[tx['type']](tx, DB, False) tools.db_delete(length, DB) length -= 1 tools.db_put('length', length) if length == -1: tools.db_put('diffLength', '0') else: block = tools.db_get(length, DB) for orphan in sorted(orphans, key=lambda x: x['count']): add_tx(orphan, DB)
def main_once(peers, DB): #DB['peers_ranked']=sorted(DB['peers_ranked'], key=lambda r: r[1]) pr=tools.db_get('peers_ranked') pr=sorted(pr, key=lambda r: r[1]) if DB['suggested_blocks'].empty(): time.sleep(10) i=0 while not DB['suggested_blocks'].empty(): i+=1 time.sleep(0.1) if i%100==0: DB['heart_queue'].put('peers check') #tools.log('suggested_blocks emptied at : ' +str(time.time())) DB['heart_queue'].put('peers check') i=exponential_random(map(lambda x: x[1], pr)) t1=time.time() r=peer_check(pr[i][0], DB) t2=time.time() pr[i][1]*=0.8 if r==0: pr[i][1]+=0.2*(t2-t1) else: pr[i][1]+=0.2*30 tools.db_put('peers_ranked', pr) DB['heart_queue'].put('peers check')
def peer_check(i, peers, DB): peer=peers[i][0] block_count = cmd(peer, {'type': 'blockCount'}) if not isinstance(block_count, dict): return if 'error' in block_count.keys(): return peers[i][2]=block_count['diffLength'] peers[i][3]=block_count['length'] length = tools.db_get('length') diffLength= tools.db_get('diffLength') size = max(len(diffLength), len(block_count['diffLength'])) us = tools.buffer_(diffLength, size) them = tools.buffer_(block_count['diffLength'], size) if them < us: give_block(peer, DB, block_count['length']) elif us == them: try: ask_for_txs(peer, DB) except Exception as exc: tools.log('ask for tx error') tools.log(exc) else: download_blocks(peer, DB, block_count, length) F=False my_peers=tools.db_get('peers_ranked') their_peers=cmd(peer, {'type':'peers'}) if type(my_peers)==list: for p in their_peers: if p not in my_peers: F=True my_peers.append(p) if F: tools.db_put('peers_ranked', my_peers)
def mine(DB, args): m = not (tools.db_get('mine')) tools.db_put('mine', m) if m: m = 'on' else: m = 'off' return ('miner is currently: ' + m)
def mine(DB, args): m=not(tools.db_get('mine')) tools.db_put('mine', m) if m: m='on' else: m='off' return('miner is currently: ' +m)
def jury_vote(tx, DB, add_block):#while votes exist, should not be able to send votecoins address=addr(tx) acc=tools.db_get(address, DB) if tx['decision_id'] not in acc['votes']: acc['votes'][tx['decision_id']]='unsure' tools.db_put(address, acc, DB) adjust_int(['count'], address, 1, DB, add_block) adjust_int(['amount'], address, -custom.jury_vote_fee, DB, add_block) adjust_string(['votes', tx['decision_id']], address, tx['old_vote'], tx['new_vote'], DB, add_block)
def mine(DB): if len(DB['args'])>0 and DB['args'][0]=='off': tools.db_put('mine', False) return('miner is now turned off') elif 'privkey' in DB: tools.db_put('mine', True) return ('miner on. (use "./truth_cli.py mine off" to turn off)') else: return('there is no private key with which to sign blocks. If you want to mine, you need to uncomment the "brain_wallet" line in custom.py')
def jury_vote(tx, DB): address=addr(tx) acc=tools.db_get(address, DB) if tx['decision_id'] not in acc['votes']: acc['votes'][tx['decision_id']]='unsure' tools.db_put(address, acc, DB) adjust_int(['count'], address, 1, DB) adjust_int(['amount'], address, -custom.jury_vote_fee, DB) adjust_string(['votes', tx['decision_id']], address, tx['old_vote'], tx['new_vote'], DB)
def add_tx(tx, DB={}): # Attempt to add a new transaction into the pool. #print('top of add_tx') out = [''] if type(tx) != type({'a': 1}): return False address = tools.make_address(tx['pubkeys'], len(tx['signatures'])) def verify_count(tx, txs): return tx['count'] != tools.count(address, DB) def type_check(tx, txs): if not tools.E_check(tx, 'type', [str, unicode]): out[0] += 'blockchain type' return False if tx['type'] == 'mint': return False if tx['type'] not in transactions.tx_check: out[0] += 'bad type' return False return True def too_big_block(tx, txs): return len( tools.package(txs + [tx])) > networking.MAX_MESSAGE_SIZE - 5000 def verify_tx(tx, txs, out): if not type_check(tx, txs): out[0] += 'type error' return False if tx in txs: out[0] += 'no duplicates' return False if verify_count(tx, txs): out[0] += 'count error' return False if too_big_block(tx, txs): out[0] += 'too many txs' return False try: if not transactions.tx_check[tx['type']](tx, txs, out, DB): out[0] += 'tx: ' + str(tx) return False except Exception as exc: out[0] += 'badly formatted tx caused error: ' + str(tx) return False return True #tools.log('attempt to add tx: ' +str(tx)) T = tools.db_get('txs') if verify_tx(tx, T, out): T.append(tx) tools.db_put('txs', T) return (tx) else: return ('failed to add tx because: ' + out[0])
def ask_for_count(peer): peers=tools.db_get('peers') block_count = cmd(peer, {'type': 'blockCount'}) if not isinstance(block_count, dict): return if 'error' in block_count.keys(): return peers[peer]['diffLength']=block_count['diffLength'] peers[peer]['length']=block_count['length'] tools.db_put('peers', peers)
def ask_for_count(peer): peers = tools.db_get('peers') block_count = cmd(peer, {'type': 'blockCount'}) if not isinstance(block_count, dict): return if 'error' in block_count.keys(): return peers[peer]['diffLength'] = block_count['diffLength'] peers[peer]['length'] = block_count['length'] tools.db_put('peers', peers)
def get_val(length): leng = str(length) if not leng in storage: block = tools.db_get(leng) if block == database.default_entry(): if leng == tools.db_get('length'): tools.db_put('length', int(leng) - 1) block = tools.db_get(leng) # try: storage[leng] = tools.db_get(leng)[key[:-1]] tools.db_put(key, storage) return storage[leng]
def add_tx(tx, DB={}): # Attempt to add a new transaction into the pool. #print('top of add_tx') out=[''] if type(tx) != type({'a':1}): return False address = tools.make_address(tx['pubkeys'], len(tx['signatures'])) def verify_count(tx, txs): return tx['count'] != tools.count(address, DB) def type_check(tx, txs): if not tools.E_check(tx, 'type', [str, unicode]): out[0]+='blockchain type' return False if tx['type'] == 'mint': return False if tx['type'] not in transactions.tx_check: out[0]+='bad type' return False return True def too_big_block(tx, txs): return len(tools.package(txs+[tx])) > networking.MAX_MESSAGE_SIZE - 5000 def verify_tx(tx, txs, out): if not type_check(tx, txs): out[0]+='type error' return False if tx in txs: out[0]+='no duplicates' return False if verify_count(tx, txs): out[0]+='count error' return False if too_big_block(tx, txs): out[0]+='too many txs' return False try: if not transactions.tx_check[tx['type']](tx, txs, out, DB): out[0]+= 'tx: ' + str(tx) return False except Exception as exc: out[0]+='badly formatted tx caused error: ' +str(tx) return False return True #tools.log('attempt to add tx: ' +str(tx)) T=tools.db_get('txs') if verify_tx(tx, T, out): T.append(tx) tools.db_put('txs', T) return(tx) else: return('failed to add tx because: '+out[0])
def main(peers, DB): # Check on the peers to see if they know about more blocks than we do. #DB['peers_ranked']=[] p = tools.db_get('peers_ranked') if type(p) != list: time.sleep(3) return main(peers, DB) for peer in peers: tools.add_peer(peer, p) tools.db_put('peers_ranked', p) try: while True: if tools.db_get('stop'): return if len(peers) > 0: main_once(DB) except Exception as exc: tools.log(exc)
def vote_on_decision(DB, args): if len(args)<3: return('not enough inputs') decision_id=args[1] answer=args[2] acc=tools.db_get(tools.db_get('address'), DB) value=[answer, str(random.random())+str(random.random())] answer_hash=tools.det_hash(value) m=tools.db_get('memoized_votes') m[answer_hash]=value tools.db_put('memoized_votes', m) #DB['memoized_votes'][answer_hash]=value old_vote='unsure' if decision_id in acc['votes']: #this is always False... old_vote=acc['votes'][decision_id] tx={'type':'jury_vote', 'vote_id':args[0], 'decision_id':decision_id, 'old_vote':old_vote, 'new_vote':answer_hash} return easy_add_transaction(tx, DB)
def main(peers, DB): # Check on the peers to see if they know about more blocks than we do. #DB['peers_ranked']=[] p=tools.db_get('peers_ranked') if type(p)!=list: time.sleep(3) return main(peers, DB) for peer in peers: add_peer(peer, p) tools.db_put('peers_ranked', p) try: while True: if tools.db_get('stop'): return if len(peers)>0: main_once(DB) except Exception as exc: tools.log(exc)
def main_once(): # put the peers check in heart queue. custom.queues['heart_queue'].put('peers check') # sort by rank in decreasing order peers = tools.db_get('peers_ranked') peers = sorted(peers, key=lambda r: r[2]) peers.reverse() time.sleep(0.05) if custom.queues['suggested_blocks'].empty(): time.sleep(2) i = 0 # wait while suggested blocks are not empty # they are needed to be taken care of while not custom.queues['suggested_blocks'].empty() and not tools.db_get( 'stop'): i += 1 time.sleep(0.1) if i % 100 == 0: custom.queues['heart_queue'].put('peers check') if tools.db_get('stop'): return custom.queues['heart_queue'].put('peers check') peer_id = exponential_random(3.0 / 4) % len(peers) t1 = time.time() r = peer_check(peer_id, peers, custom.queues) t2 = time.time() a_peer = peers[peer_id][0] peers = tools.db_get('peers_ranked') for peer in peers: if peer[0] == a_peer: peers[peer_id][1] *= 0.8 if r == 0: peers[peer_id][1] += 0.2 * (t2 - t1) else: peers[peer_id][1] += 0.2 * 30 tools.db_put('peers_ranked', peers) custom.queues['heart_queue'].put('peers check')
def mine(DB, args): if len(args)>0: if args[0]=='off': tools.db_put('mine', False) return('miner is now turned off') elif args[0]=='on': if tools.db_existence('privkey'): tools.db_put('mine', True) return ('miner on. (use "./truth_cli.py mine off" to turn off)') else: return('there is no private key with which to sign blocks. If you want to mine, you need to uncomment the "brain_wallet" line in custom.py') else: m=tools.db_get('mine') if m: m='on' else: m='off' return('miner is currently: ' +m)
def main_once(): # put the peers check in heart queue. custom.queues['heart_queue'].put('peers check') # sort by rank in decreasing order peers = tools.db_get('peers_ranked') peers = sorted(peers, key=lambda r: r[2]) peers.reverse() time.sleep(0.05) if custom.queues['suggested_blocks'].empty(): time.sleep(2) i = 0 # wait while suggested blocks are not empty # they are needed to be taken care of while not custom.queues['suggested_blocks'].empty() and not tools.db_get('stop'): i += 1 time.sleep(0.1) if i % 100 == 0: custom.queues['heart_queue'].put('peers check') if tools.db_get('stop'): return custom.queues['heart_queue'].put('peers check') peer_id = exponential_random(3.0 / 4) % len(peers) t1 = time.time() r = peer_check(peer_id, peers, custom.queues) t2 = time.time() a_peer = peers[peer_id][0] peers = tools.db_get('peers_ranked') for peer in peers: if peer[0] == a_peer: peers[peer_id][1] *= 0.8 if r == 0: peers[peer_id][1] += 0.2 * (t2 - t1) else: peers[peer_id][1] += 0.2 * 30 tools.db_put('peers_ranked', peers) custom.queues['heart_queue'].put('peers check')
def mine(DB, args): if len(args) > 0: if args[0] == 'off': tools.db_put('mine', False) return ('miner is now turned off') elif args[0] == 'on': if tools.db_existence('privkey'): tools.db_put('mine', True) return ( 'miner on. (use "./truth_cli.py mine off" to turn off)') else: return ( 'there is no private key with which to sign blocks. If you want to mine, you need to uncomment the "brain_wallet" line in custom.py' ) else: m = tools.db_get('mine') if m: m = 'on' else: m = 'off' return ('miner is currently: ' + m)
def peer_check(i, peers, DB): peer = peers[i][0] block_count = cmd(peer, {'type': 'blockCount'}) #tools.log('block count: ' +str(block_count)) if not isinstance(block_count, dict): return if 'error' in block_count.keys(): return peers[i][2] = block_count['diffLength'] peers[i][3] = block_count['length'] tools.db_put('peers_ranked', peers) length = tools.db_get('length') diffLength = tools.db_get('diffLength') size = max(len(diffLength), len(block_count['diffLength'])) us = tools.buffer_(diffLength, size) them = tools.buffer_(block_count['diffLength'], size) if them < us: give_block(peer, DB, block_count['length']) elif us == them: try: ask_for_txs(peer, DB) except Exception as exc: tools.log('ask for tx error') tools.log(exc) else: download_blocks(peer, DB, block_count, length) F = False my_peers = tools.db_get('peers_ranked') their_peers = cmd(peer, {'type': 'peers'}) if type(their_peers) == list: for p in their_peers: if p not in my_peers: F = True my_peers.append(p) for p in my_peers: if p not in their_peers: cmd(peer, {'type': 'recieve_peer', 'peer': p}) if F: tools.db_put('peers_ranked', my_peers)
def mine_client(pubkey): def readable_time(mytime): return time.strftime("%D %H:%M", time.localtime(int(mytime))) print 'client miner started' executable = copy.deepcopy(custom.client_executable) executable.append(pubkey) miner_process = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) print executable tools.db_put('miner_id', miner_process.pid) while True: nextline = miner_process.stdout.readline() if miner_process.poll() is not None: break nextline = nextline.rstrip('\n') try: status = json.loads(nextline)[u'status'] tools.db_put('miner_status', status) tools.db_put( 'minestatustext', readable_time(time.time()) + ' ' + status + '\n' + tools.db_get('minestatustext')) except: pass # wait for process to actually finish returncode = miner_process.poll() tools.db_put('miner_id', -1) if returncode == 0: print 'Mining is done succesfully' else: print 'Mining is finished prematurely.' tools.db_put('mine', False)
def vote_on_decision(DB, args): if len(args) < 3: return ('not enough inputs') decision_id = args[1] answer = args[2] acc = tools.db_get(tools.db_get('address'), DB) value = [answer, str(random.random()) + str(random.random())] answer_hash = tools.det_hash(value) m = tools.db_get('memoized_votes') m[answer_hash] = value tools.db_put('memoized_votes', m) #DB['memoized_votes'][answer_hash]=value old_vote = 'unsure' if decision_id in acc['votes']: #this is always False... old_vote = acc['votes'][decision_id] tx = { 'type': 'jury_vote', 'vote_id': args[0], 'decision_id': decision_id, 'old_vote': old_vote, 'new_vote': answer_hash } return easy_add_transaction(tx, DB)
def main_once(DB): pr = tools.db_get('peers') keys = filter(lambda x: pr[x]['blacklist'] < 500, pr.keys()) keys = sorted(keys, key=lambda r: pr[r]['lag']) if len(keys) < 1: time.sleep(0.5) return time.sleep(0.05) while not DB['suggested_blocks'].empty(): time.sleep(0.1) if tools.db_get('stop'): return 0 i = exponential_random(9.0 / 10) % len(keys) t1 = time.time() r = peer_check(keys[i], DB) t2 = time.time() a = 0.5 pr = tools.db_get('peers') #this has been changed, we need to reload. pr[keys[i]]['lag'] *= (1 - a) if r == 0: a *= (t2 - t1) else: a *= 60 pr[keys[i]]['lag'] += a tools.db_put('peers', pr)
def main_once(DB): pr=tools.db_get('peers') keys=filter(lambda x: pr[x]['blacklist']<500 , pr.keys()) keys=sorted(keys, key=lambda r: pr[r]['lag']) if len(keys)<1: time.sleep(0.5) return time.sleep(0.05) while not DB['suggested_blocks'].empty(): time.sleep(0.1) if tools.db_get('stop'): return 0 i=exponential_random(9.0/10)%len(keys) t1=time.time() r=peer_check(keys[i], DB) t2=time.time() a=0.5 pr=tools.db_get('peers')#this has been changed, we need to reload. pr[keys[i]]['lag']*=(1-a) if r==0: a*=(t2-t1) else: a*=60 pr[keys[i]]['lag']+=a tools.db_put('peers', pr)
def main(peers, DB): # Check on the peers to see if they know about more blocks than we do. #DB['peers_ranked']=[] for peer in peers: p=tools.db_get('peers_ranked') p.append([peer, 5]) tools.db_put('peers_ranked', p) try: while True: if tools.db_get('stop'): return if len(peers)>0: main_once(peers, DB) while not DB['reward_peers_queue'].empty(): q=DB['reward_peers_queue'].get() p=q['peer'] d=q['do'] pr=tools.db_get('peers_ranked') i=0 j='empty' for p in pr: if p[0]==peer: j=i i+=1 if j!='empty': if d=='reward': #listen more to people who give us good blocks. pr[j][1]*=0.1 elif d=='punish': #listen less to people who give us bad blocks. pr[j][1]*=0.8 pr[j][1]+=0.2*60 tools.db_put('peers_ranked', pr) else: #maybe this peer should be added to our list of peers? pass except: tools.log('main peers check: ' +str(sys.exc_info()))
def main(peers, DB): # Check on the peers to see if they know about more blocks than we do. #DB['peers_ranked']=[] for peer in peers: p = tools.db_get('peers_ranked') p.append([peer, 5]) tools.db_put('peers_ranked', p) try: while True: if tools.db_get('stop'): return if len(peers) > 0: main_once(peers, DB) while not DB['reward_peers_queue'].empty(): q = DB['reward_peers_queue'].get() p = q['peer'] d = q['do'] pr = tools.db_get('peers_ranked') i = 0 j = 'empty' for p in pr: if p[0] == peer: j = i i += 1 if j != 'empty': if d == 'reward': #listen more to people who give us good blocks. pr[j][1] *= 0.1 elif d == 'punish': #listen less to people who give us bad blocks. pr[j][1] *= 0.8 pr[j][1] += 0.2 * 60 tools.db_put('peers_ranked', pr) else: #maybe this peer should be added to our list of peers? pass except: tools.log('main peers check: ' + str(sys.exc_info()))
def mine_server(pubkey): print 'server miner started' executable = custom.server_executable miner_process = subprocess.Popen(executable, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) tools.db_put('miner_id', miner_process.pid) while True: nextline = miner_process.stdout.readline() if miner_process.poll() != None: break sys.stdout.write(nextline) sys.stdout.flush() nextline = nextline.rstrip('\n') if nextline != '': insert_block(pubkey, nextline) # wait for process to actually finish tools.db_put('miner_id', -1) print 'Mining is ended' tools.db_put('mine', False)
def mine(args): m = not (tools.db_get('mine')) if m: if custom.server_executable != '' or custom.client_executable != '': m = 'on' tools.db_put('mine', True) return 'Started miner.' else: m = 'off' tools.db_put('mine', False) return 'Miner is missing.' elif not m: m = 'off' tools.db_put('mine', False) kill(int(tools.db_get('miner_id'))) return 'Stopped the miner' return 'miner is currently: ' + str(m)
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 symmetric_put(id_, dic, DB, add_block): if add_block: tools.db_put(id_, dic, DB) else: tools.db_delete(id_, DB)
def adjust(pubkey, DB, f):#location shouldn't be here. acc = tools.db_get(pubkey, DB) f(acc) tools.db_put(pubkey, acc, DB)
def add_tx(tx): # Attempt to add a new transaction into the pool. out = [''] # check tx variable's type if type(tx) != type({'a': 1}): return False # make address from pubkeys and signatures of transaction address = tools.make_address(tx['pubkeys'], len(tx['signatures'])) def verify_count(tx, txs): return tx['count'] != tools.count(address) def type_check(tx, txs): if not tools.E_check(tx, 'type', [str, unicode]): out[0] += 'Blockchain type' return False # mint type cannot be added to database if tx['type'] == 'mint': return False # type is not recognized if tx['type'] not in transactions.tx_check: out[0] += 'Bad type' return False return True def too_big_block(tx, txs): return len(tools.package(txs + [tx])) > networking.MAX_MESSAGE_SIZE - 5000 def verify_tx(tx, txs, out): # check if the type of transaction lets you add the transaction back to database if not type_check(tx, txs): out[0] += 'Type error\n' return False if tx in txs: out[0] += 'No duplicates\n' return False # is this transaction possible with this count if verify_count(tx, txs): out[0] += 'Count error\n' return False # this block cannot be sent over network if too_big_block(tx, txs): out[0] += 'Too many txs\n' return False # run the last tx_check test from transactions module if not transactions.tx_check[tx['type']](tx, txs, out): out[0] += 'Transaction was not verified!\n' return False return True txs_from_db = tools.db_get('txs') if verify_tx(tx, txs_from_db, out): txs_from_db.append(tx) tools.db_put('txs', txs_from_db) return ('Added transaction with %d amount to %s' % (tx['amount'], tx['to'])) else: return ('Failed to add tx because: \n' + out[0])
def add_block(block_pair): """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): def log_(txt): pass # return tools.log(txt) def check_txs(txs): start = copy.deepcopy(txs) out = [] start_copy = [] # until starting copy of transactions are empty while start != start_copy: if start == []: return False # Block passes this test start_copy = copy.deepcopy(start) # if transaction is valid, then add the transaction to the out list if transactions.tx_check[start[-1]['type']](start[-1], out, ['']): out.append(start.pop()) else: return True # Block is invalid return True # Block is invalid # if block is not a dict, return false if not isinstance(block, dict): return False # block contains error if 'error' in block: return False # E_check function is responsible for checking the block(dict) if it has a length attribute which is int if not tools.E_check(block, 'length', [int]): log_('no length') return False # get the length of blockchain length = tools.db_get('length') # check length if it is integer, yeah yeah we have done that so what? if type(block['length']) != type(1): log_('wrong length type') return False # check length condition. It must be one bigger than our current blockchain length, or we would be missing something if int(block['length']) != int(length) + 1: log_('wrong longth') return False # checking if prevHash was actually the previous block's hash if length >= 0: if tools.det_hash(tools.db_get(length)) != block['prevHash']: log_('det hash error') return False # --------------------- START OF THE NEW PROOF-OF-WORK CHECK--------------------------------- # Returns a dictionary with auth_sign and halfHash of block. # Authority must sign the block with its pubkey. This way, we are going to know which authority signed the block half_way = tools.make_half_way(block) if not half_way.get('auth_pubkey') in tools.db_get('authorities'): print 'no auth pubkey' return False if not tools.verify(half_way.get('halfHash'), half_way.get('auth_sign'), half_way.get('auth_pubkey')): print 'no verify' return False # --------------------- END OF THE NEW PROOF-OF-WORK CHECK----------------------------------- # recent_blockthings returns a map with get_val function and range starting from 100 early blocks to most recent block # then earliest is the median of sorted blocks earliest = median(recent_blockthings('times', custom.mmm)) # time has to be present in block if 'time' not in block: log_('no time') return False # it is late to check this block if block['time'] > time.time() + 60 * 6: log_('too late') return False # block does not seem to be created at correct time if block['time'] < earliest: log_('too early') return False # check the transactions in the block # this function returns True on negative situation, because f**k the logic! # please someone fix this. I left it for now to show how a joken source this project is! if check_txs(block['txs']): log_('tx check') return False return True # This is where the add_block logic begins # if the block_pair is an array if type(block_pair) == type([1, 2, 3]): # block is actually the first element block = block_pair[0] # peer is the second element peer = block_pair[1] else: block = block_pair peer = False # block_check takes two inputs : block and current DB # it runs many tests on block including transactions and other things if block_check(block): # update the database with new block tools.db_put(block['length'], block) tools.db_put('length', block['length']) orphans = tools.db_get('txs') tools.db_put('txs', []) for tx in block['txs']: # update the database with this new transaction. transactions.update[tx['type']](tx, True) # add all orphan transactions back to database for tx in orphans: add_tx(tx)
def stop_(DB, args): tools.db_put('stop', True) return('turning off all threads')
def add_block(block_pair, 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 tx_check(txs): start = copy.deepcopy(txs) out = [] start_copy = [] while start != start_copy: if start == []: return False # Block passes this test start_copy = copy.deepcopy(start) if transactions.tx_check[start[-1]['type']](start[-1], out, DB): out.append(start.pop()) else: return True # Block is invalid return True # Block is invalid if not isinstance(block, dict): return False if 'error' in block: return False if 'length' not in block: return False length = DB['length'] if int(block['length']) != int(length) + 1: return False if block['diffLength'] != hexSum(DB['diffLength'], hexInvert(block['target'])): return False if length >= 0: if tools.det_hash(tools.db_get(length, DB)) != block['prevHash']: return False a = copy.deepcopy(block) a.pop('nonce') if u'target' not in block.keys(): return False half_way = {u'nonce': block['nonce'], u'halfHash': tools.det_hash(a)} if tools.det_hash(half_way) > block['target']: return False if block['target'] != target(DB, block['length']): return False earliest = median(recent_blockthings('time', DB, custom.mmm)) if 'time' not in block: return False if block['time'] > time.time(): return False if block['time'] < earliest: return False if tx_check(block['txs']): 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 #tools.log('attempt to add block: ' +str(block)) if block_check(block, DB): #tools.log('add_block: ' + str(block)) i = 0 j = 'empty' if peer != False: for p in DB['peers_ranked']: if p[0] == peer: j = i i += 1 if j != 'empty': DB['peers_ranked'][j][ 1] *= 0.1 #listen more to people who have newer blocks. else: #maybe this peer should be added to our list of peers? pass tools.db_put(block['length'], block, DB) DB['length'] = block['length'] DB['diffLength'] = block['diffLength'] orphans = copy.deepcopy(DB['txs']) DB['txs'] = [] for tx in block['txs']: DB['add_block'] = True transactions.update[tx['type']](tx, DB) for tx in orphans: add_tx(tx, DB)
def symmetric_put(id_, dic, DB): if DB['add_block']: tools.db_put(id_, dic, DB) else: tools.db_delete(id_, DB)
def initialize_to_zero_helper(loc, address, DB): acc=tools.db_get(address, DB) if loc[1] not in acc[loc[0]]: acc[loc[0]][loc[1]]=0 tools.db_put(address , acc, DB)
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 add_block(block_pair, 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 = [] while start != start_copy: if start == []: return False # Block passes this test start_copy = copy.deepcopy(start) if transactions.tx_check[start[-1]['type']](start[-1], out, [''], DB): out.append(start.pop()) else: return True # Block is invalid return True # Block is invalid if not isinstance(block, dict): return False if 'error' in block: return False if not tools.E_check(block, 'length', [int]): log_('no length') return False length = tools.db_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 if block['diffLength'] != hexSum(tools.db_get('diffLength'), hexInvert(block['target'])): log_('diflength error') return False if length >= 0: if tools.det_hash(tools.db_get(length, DB)) != block['prevHash']: log_('det hash error') return False if u'target' not in block.keys(): log_('target error') return False half_way = tools.make_half_way(block) if tools.det_hash(half_way) > block['target']: log_('det hash error 2') return False if block['target'] != target.target(block['length']): log_('block: ' + str(block)) log_('target: ' + str(target.target(block['length']))) log_('wrong target') return False earliest = median(recent_blockthings('times', custom.mmm)) if 'time' not in block: log_('no time') return False if block['time'] > time.time() + 60 * 6: log_('too late') return False if block['time'] < earliest: log_('too early') return False 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 #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.db_put('length', block['length']) tools.db_put('diffLength', block['diffLength']) orphans = tools.db_get('txs') tools.db_put('txs', []) for tx in block['txs']: transactions.update[tx['type']](tx, DB, True) for tx in orphans: add_tx(tx, DB)
def main(brainwallet, pubkey_flag=False): DB=custom.DB tools.log('custom.current_loc: ' +str(custom.current_loc)) print('starting truthcoin') if not pubkey_flag: privkey=tools.det_hash(brainwallet) pubkey=tools.privtopub(privkey) else: pubkey=brainwallet a=tools.empty_peer() a['port']=custom.port b=custom.peers my_ip=tools.getPublicIp() b[my_ip+':'+str(custom.port)]=a processes= [ {'target': blockchain.main, 'args': (DB,), 'name': 'blockchain'}, {'target': truthcoin_api.main, 'args': (DB, DB['heart_queue']), 'name': 'truthcoin_api'}, {'target': peers_check.main, 'args': (b, DB), 'name': 'peers_check'}, {'target': miner.main, 'args': (pubkey, DB), 'name': 'miner'}, {'target': networking.serve_forever, 'args': (peer_recieve_func, custom.port, DB['heart_queue'], True), 'name': 'peer_recieve'} ] cmds=[database.DatabaseProcess( DB['heart_queue'], custom.database_name, tools.log, custom.database_port)] try: cmds[0].start() except Exception as exc: tools.log(exc) tools.log('starting ' + cmds[0].name) time.sleep(4) tools.db_put('test', 'TEST') tools.db_get('test') tools.db_put('test', 'undefined') b=tools.db_existence(0) if not b: tools.db_put('ip', my_ip) tools.db_put('length', -1) tools.db_put('memoized_votes', {}) tools.db_put('txs', []) tools.db_put('peers', {}) tools.db_put('targets', {}) tools.db_put('times', {}) tools.db_put('mine', False) tools.db_put('diffLength', '0') tools.db_put('stop', False) tools.log('stop: ' +str(tools.db_get('stop'))) for process in processes: cmd=multiprocessing.Process(**process) cmd.start() cmds.append(cmd) tools.log('starting '+cmd.name) if not pubkey_flag: tools.db_put('privkey', privkey) else: tools.db_put('privkey', 'Default') tools.db_put('address', tools.make_address([pubkey], 1)) tools.log('stop: ' +str(tools.db_get('stop'))) while not tools.db_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 add_block(block_pair, 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 = [] error_msg=[''] while True: if start == []: return False # Block passes this test if transactions.tx_check[start[-1]['type']](start[-1], out, error_msg, DB): out.append(start.pop()) else: log_('bad block: ' +str(txs)) log_('error message: ' +str(error_msg)) return True # Block is invalid if not isinstance(block, dict): return False if 'error' in block: return False if not tools.E_check(block, 'length', [int]): log_('no length') return False length =tools.db_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 if block['diffLength'] != hexSum(tools.db_get('diffLength'), hexInvert(block['target'])): log_('diflength error') return False if length >= 0: if tools.det_hash(tools.db_get(length, DB)) != block['prevHash']: log_('det hash error') return False if u'target' not in block.keys(): log_('target error') return False half_way=tools.make_half_way(block) if tools.det_hash(half_way) > block['target']: log_('det hash error 2') return False if block['target'] != target.target(block['length']): log_('block: ' +str(block)) log_('target: ' +str(target.target(block['length']))) log_('wrong target') return False earliest = median(recent_blockthings('times', custom.mmm)) if 'time' not in block: log_('no time') return False if block['time'] > time.time()+60*6: log_('too late') return False if block['time'] < earliest: log_('too early') return False 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 #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.db_put('length', block['length']) tools.db_put('diffLength', block['diffLength']) orphans = tools.db_get('txs') tools.db_put('txs', []) for tx in block['txs']: transactions.update[tx['type']](tx, DB, True) for tx in orphans: add_tx(tx, DB)
def stop_(args): tools.db_put('stop', True) kill(int(tools.db_get('miner_id'))) return 'turning off all threads'