Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
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)
Exemplo n.º 4
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)