Beispiel #1
0
def ask_for_count(peer):
    peers=tools.local_get('peers')
    block_count = cmd(peer, {'type': 'blockCount'})
    if not isinstance(block_count, dict):
        return
    if 'error' in block_count.keys():
        return
    peers[peer]['length']=block_count['length']
    tools.local_put('peers', peers)
Beispiel #2
0
def ask_for_count(peer):
    peers = tools.local_get('peers')
    block_count = cmd(peer, {'type': 'blockCount'})
    if not isinstance(block_count, dict):
        return
    if 'error' in block_count.keys():
        return
    peers[peer]['length'] = block_count['length']
    tools.local_put('peers', peers)
Beispiel #3
0
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'] 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):
        #do not allow tx which fail to reference one of the 10 most recent blocks. do not allow tx which have an identical copy in the last 10 blocks.
        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
        if not transactions.tx_check[tx['type']](tx, txs, out, DB):
            out[0] += 'tx: ' + str(tx)
            return False
        return True

    #tools.log('attempt to add tx: ' +str(tx))
    T = tools.local_get('txs')
    if verify_tx(tx, T, out):
        T.append(tx)
        tools.local_put('txs', T)
        return ('added tx: ' + str(tx))
    else:
        return ('failed to add tx because: ' + out[0])
Beispiel #4
0
 def get_val(length):
     leng = str(length)
     if not leng in storage:            
         block=tools.db_get(leng)
         if block==db.default_entry():
             if leng==tools.local_get('length'):
                 tools.local_put('length', int(leng)-1)
                 block=tools.db_get(leng)
             else:
                 error()
         #try:
         storage[leng] = tools.db_get(leng)[key[:-1]]
         tools.db_put(key, storage)
     return storage[leng]
Beispiel #5
0
 def get_val(length):
     leng = str(length)
     if not leng in storage:
         block = tools.db_get(leng)
         if block == db.default_entry():
             if leng == tools.local_get('length'):
                 tools.local_put('length', int(leng) - 1)
                 block = tools.db_get(leng)
             else:
                 error()
         #try:
         storage[leng] = tools.db_get(leng)[key[:-1]]
         tools.db_put(key, storage)
     return storage[leng]
Beispiel #6
0
def create_sign_tx():
    on_block=tools.local_get('length')+1
    if on_block==0:
        time.sleep(1)
        return{'error':'not ready'}
    r=tools.det_random(on_block)
    jackpots=[]
    address=tools.local_get('address')
    l=max(-1, on_block-1-(custom.long_time*2-custom.medium_time))
    election_block=tools.db_get(l+1)
    proof=tools.local_get('balance_proofs'+str(l))
    if 'root_hash' not in election_block:
        return({'error':'database changed'})
    a=tools.db_verify(election_block['root_hash'], address, proof)
    if a==False:
        #tools.log('election block: ' +str(election_block))
        #tools.log('proof: ' +str(proof))
        return({'error':'not valid proof'})
    old_balance=a['amount']
    M=custom.all_money
    for j in range(custom.jackpot_nonces):
        if tools.winner(old_balance, M, r, address, j):
            jackpots.append(j)
    if len(jackpots)>0:
        tx={'on_block':on_block, 'jackpots':jackpots, 'type':'sign', 'amount':M/3000/3}
        tx['B']=old_balance
        tx['proof']=proof
        if proof=='empty':
            time.sleep(1)
            return {'error':'not ready'}
        secrets=tools.local_get('secrets')
        if str(on_block) in secrets:
            secret=secrets[str(on_block)]
        else:
            secret=tools.unpackage(tools.package({'salt':str(random.random())+str(random.random()), 'entropy':random.randint(0,1)}))
            secrets[str(on_block)]=secret
            tools.local_put('secrets', secrets)
        tx['secret_hash']=tools.det_hash(secret)
        if on_block>0:
            block=tools.db_get(on_block-1)
            if 'amount' in block and block['amount']==0:
                return({'error':'database changed'})
            #tools.log('on_block: ' +str(a))
            tx['prev']=block['block_hash']
    else:
        tx= {'error':'no jackpots'}
    return tx
Beispiel #7
0
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'] 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):
        #do not allow tx which fail to reference one of the 10 most recent blocks. do not allow tx which have an identical copy in the last 10 blocks.
        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
        if not transactions.tx_check[tx['type']](tx, txs, out, DB):
            out[0]+= 'tx: ' + str(tx)
            return False
        return True
    #tools.log('attempt to add tx: ' +str(tx))
    T=tools.local_get('txs')
    if verify_tx(tx, T, out):
        T.append(tx)
        tools.local_put('txs', T)
        return('added tx: ' +str(tx))
    else:
        return('failed to add tx because: '+out[0])
Beispiel #8
0
def main_once(DB):
    pr=tools.local_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.local_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.local_get('peers')
    pr[keys[i]]['lag']*=(1-a)
    if r==0: a*=(t2-t1)
    else:
        a*=60
    pr[keys[i]]['lag']+=a
    tools.local_put('peers', pr)
Beispiel #9
0
def main_once(DB):
    pr = tools.local_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.local_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.local_get('peers')
    pr[keys[i]]['lag'] *= (1 - a)
    if r == 0: a *= (t2 - t1)
    else:
        a *= 60
    pr[keys[i]]['lag'] += a
    tools.local_put('peers', pr)
Beispiel #10
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)
Beispiel #11
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
Beispiel #12
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)
Beispiel #13
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
Beispiel #14
0
def stop_(DB, args):
    tools.local_put('stop', True)
    return ('turning off all threads')
Beispiel #15
0
def stop_(DB, args): 
    tools.local_put('stop', True)
    return('turning off all threads')
Beispiel #16
0
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 repeat_check(tx, txs):
        l=tools.local_get('length')
        if l<=1: return True
        h=tx['recent_hash']
        r=range(l-10, l)
        r=filter(lambda l: l>0, r)
        recent_blocks=map(lambda x:tools.db_get(x), r)
        recent_hashes=map(lambda x: x['block_hash'], recent_blocks)
        if h not in recent_hashes:
            tools.log('have : ' +str(h))
            tools.log('need: ' +str(recent_hashes))
            tools.log('recent hash error')
            return False
        recent_txs=[]
        for block in recent_blocks:
            recent_txs+=block['txs']
        def f(d):
            d=copy.deepcopy(d)
            d.pop('signatures')
            return tools.det_hash(d)
        if f(tx) in map(f, recent_txs):
            tools.log('no repeated tx')
            return False
        return True
    def type_check(tx, txs):
        if not tools.E_check(tx, 'type', [str, unicode]):
            out[0]+='blockchain type'
            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):
        #do not allow tx which fail to reference one of the 10 most recent blocks. do not allow tx which have an identical copy in the last 10 blocks.
        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
        if not tools.fee_check(tx, txs, DB):
            out[0]+='not enough money: ' +str(tx)
            return False
        if not tools.signature_check(tx):
            out[0]+='bad signature: ' +str(tx)
            return False
        if not transactions.tx_check[tx['type']](tx, txs, out, DB):
            out[0]+= 'tx: ' + str(tx)
            return False
        return True
    #tools.log('attempt to add tx: ' +str(tx))
    T=tools.local_get('txs')
    try:
        if verify_tx(tx, T, out):
            T.append(tx)
            tools.local_put('txs', T)
            return('added tx: ' +str(tx))
        else:
            return('failed to add tx because: '+out[0])
    except Exception as exc:
        tools.log(exc)
        return('failed to add tx because an error occured while adding tx')
Beispiel #17
0
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 repeat_check(tx, txs):
        l = tools.local_get('length')
        if l <= 1: return True
        h = tx['recent_hash']
        r = range(l - 10, l)
        r = filter(lambda l: l > 0, r)
        recent_blocks = map(lambda x: tools.db_get(x), r)
        recent_hashes = map(lambda x: x['block_hash'], recent_blocks)
        if h not in recent_hashes:
            tools.log('have : ' + str(h))
            tools.log('need: ' + str(recent_hashes))
            tools.log('recent hash error')
            return False
        recent_txs = []
        for block in recent_blocks:
            recent_txs += block['txs']

        def f(d):
            d = copy.deepcopy(d)
            d.pop('signatures')
            return tools.det_hash(d)

        if f(tx) in map(f, recent_txs):
            tools.log('no repeated tx')
            return False
        return True

    def type_check(tx, txs):
        if not tools.E_check(tx, 'type', [str, unicode]):
            out[0] += 'blockchain type'
            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):
        #do not allow tx which fail to reference one of the 10 most recent blocks. do not allow tx which have an identical copy in the last 10 blocks.
        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
        if not tools.fee_check(tx, txs, DB):
            out[0] += 'not enough money: ' + str(tx)
            return False
        if not tools.signature_check(tx):
            out[0] += 'bad signature: ' + str(tx)
            return False
        if not transactions.tx_check[tx['type']](tx, txs, out, DB):
            out[0] += 'tx: ' + str(tx)
            return False
        return True

    #tools.log('attempt to add tx: ' +str(tx))
    T = tools.local_get('txs')
    try:
        if verify_tx(tx, T, out):
            T.append(tx)
            tools.local_put('txs', T)
            return ('added tx: ' + str(tx))
        else:
            return ('failed to add tx because: ' + out[0])
    except Exception as exc:
        tools.log(exc)
        return ('failed to add tx because an error occured while adding tx')
Beispiel #18
0
def delete_block(DB):
    """ Removes the most recent block from the blockchain. """
    length=tools.local_get('length')
    if length < 0:
        return
    try:
        ts=tools.local_get('targets')
        ts.pop(str(length))
        tools.local_put('targets', ts)
    except:
        pass
    try:
        ts=tools.local_get('times')
        ts.pop(str(length))
        tools.local_put('times', ts)
    except:
        pass
    block = tools.db_get(length, DB)
    orphans = tools.local_get('txs')
    orphans=filter(lambda t: t['type']!='mint', orphans)
    tools.local_put('txs', [])
    for tx in block['txs']:
        orphans.append(tx)
        tools.local_put('add_block', False)
        transactions.update[tx['type']](tx, DB, False)
    tools.db_delete(length, DB)
    length-=1
    tools.local_put('length', length)
    if length>=0:
        block=tools.db_get(length)
        tools.local_put('height', filter(lambda t: t['type']=='mint', block['txs'])[0]['height'])
    else:
        tools.local_put('height', -1)
    for orphan in orphans:
        add_tx(orphan, DB)
Beispiel #19
0
def delete_block(DB):
    """ Removes the most recent block from the blockchain. """
    length = tools.local_get('length')
    if length < 0:
        return
    try:
        ts = tools.local_get('targets')
        ts.pop(str(length))
        tools.local_put('targets', ts)
    except:
        pass
    try:
        ts = tools.local_get('times')
        ts.pop(str(length))
        tools.local_put('times', ts)
    except:
        pass
    block = tools.db_get(length, DB)
    orphans = tools.local_get('txs')
    orphans = filter(lambda t: t['type'] != 'mint', orphans)
    tools.local_put('txs', [])
    for tx in block['txs']:
        orphans.append(tx)
        tools.local_put('add_block', False)
        transactions.update[tx['type']](tx, DB, False)
    tools.db_delete(length, DB)
    length -= 1
    tools.local_put('length', length)
    if length >= 0:
        block = tools.db_get(length)
        tools.local_put(
            'height',
            filter(lambda t: t['type'] == 'mint', block['txs'])[0]['height'])
    else:
        tools.local_put('height', -1)
    for orphan in orphans:
        add_tx(orphan, DB)
Beispiel #20
0
def stop_(DB, args):
    tools.local_put("stop", True)
    return "turning off all threads"