Exemplo n.º 1
0
 def broadcast_block(self, block):
     Peers.init(self.config, self.mongo, self.config.network)
     Peer.save_my_peer(self.config, self.mongo, self.config.network)
     print '\r\nCandidate submitted for index:', block.index
     print '\r\nTransactions:'
     for x in block.transactions:
         print x.transaction_signature 
     self.mongo.db.consensus.insert({'peer': 'me', 'index': block.index, 'id': block.signature, 'block': block.to_dict()})
     print '\r\nSent block to:'
     for peer in Peers.peers:
         if peer.is_me:
             continue
         try:
             block_dict = block.to_dict()
             block_dict['peer'] = Peers.my_peer
             requests.post(
                 'http://{peer}/newblock'.format(
                     peer=peer.host + ":" + str(peer.port)
                 ),
                 json=block_dict,
                 timeout=3,
                 headers={'Connection':'close'}
             )
             print peer.host + ":" + str(peer.port)
         except Exception as e:
             print e
             peer.report()
Exemplo n.º 2
0
    def refresh(self):
        Peers.init(self.config, self.mongo, self.config.network)
        block = BU.get_latest_block(self.config, self.mongo)
        if block:
            block = Block.from_dict(self.config, self.mongo, block)
            self.height = block.index + 1
        else:
            genesis_block = BlockFactory.get_genesis_block(self.config, self.mongo)
            genesis_block.save()
            self.mongo.db.consensus.insert({
                'block': genesis_block.to_dict(),
                'peer': 'me',
                'id': genesis_block.signature,
                'index': 0
                })
            block = Block.from_dict(self.config, self.mongo, BU.get_latest_block(self.config, self.mongo))
            self.height = block.index

        try:
            self.block_factory = BlockFactory(
                config=self.config,
                mongo=self.mongo,
                transactions=self.get_pending_transactions(),
                public_key=self.config.public_key,
                private_key=self.config.private_key,
                index=self.height,
                version=BU.get_version_for_height(self.height))
            
            self.set_target(int(self.block_factory.block.time))
            if not self.block_factory.block.special_min:
                self.set_target_from_last_non_special_min(block)
            self.block_factory.block.header = BlockFactory.generate_header(self.block_factory.block)
        except Exception as e:
            raise e
Exemplo n.º 3
0
    def run(cls, config, mongo, to, value):
        Peers.init(config, mongo, config.network)

        try:
            transaction = TransactionFactory(
                config,
                mongo,
                fee=0.01,
                public_key=config.public_key,
                private_key=config.private_key,
                outputs=[Output(to=to, value=value)])
        except NotEnoughMoneyException as e:
            print "not enough money yet"
            return
        except:
            raise
        try:
            transaction.transaction.verify()
        except:
            print 'transaction failed'
        TU.save(transaction.transaction)
        print 'Transaction generated successfully. Sending:', value, 'To:', to
        for peer in Peers.peers:
            try:
                socketIO = SocketIO(peer.host,
                                    peer.port,
                                    wait_for_connection=False)
                chat_namespace = socketIO.define(ChatNamespace, '/chat')
                chat_namespace.emit('newtransaction',
                                    transaction.transaction.to_dict())
                socketIO.disconnect()
                print 'Sent to:', peer.host, peer.port
            except Exception as e:
                print e
Exemplo n.º 4
0
 def search_network_for_new(self):
     Peers.init(self.config, self.mongo, self.config.network)
     for peer in Peers.peers:
         try:
             if self.debug:
                 print 'requesting %s from %s' % (self.latest_block.index + 1, peer.to_string()) 
             try:
                 result = requests.get('http://{peer}/get-blocks?start_index={start_index}&end_index={end_index}'.format(
                     peer=str(peer.to_string()),
                     start_index=int(self.latest_block.index) + 1,
                     end_index=int(self.latest_block.index) + 1000
                 ), timeout=1)
             except Exception as e:
                 raise e
             try:
                 blocks = json.loads(result.content)
             except ValueError:
                 continue
             for block in blocks:
                 block = Block.from_dict(self.config, self.mongo, block)
                 if block.index == (self.existing_blockchain.blocks[-1].index + 1):
                     self.insert_consensus_block(block, peer)
                     self.import_block({'peer': peer.to_string(), 'block': block.to_dict(), 'extra_blocks': blocks})
         except Exception as e:
             if self.debug:
                 print e
Exemplo n.º 5
0
    def refresh(self):
        Peers.init(self.config, self.mongo, self.config.network)
        if self.config.network == 'mainnet':
            max_block_time = 600
        elif self.config.network == 'testnet':
            max_block_time = 10
        block = BU.get_latest_block(self.config, self.mongo)
        if block:
            block = Block.from_dict(self.config, self.mongo, block)
            self.height = block.index + 1
        else:
            genesis_block = BlockFactory.get_genesis_block(
                self.config, self.mongo)
            genesis_block.save()
            self.mongo.db.consensus.insert({
                'block': genesis_block.to_dict(),
                'peer': 'me',
                'id': genesis_block.signature,
                'index': 0
            })
            block = Block.from_dict(
                self.config, self.mongo,
                BU.get_latest_block(self.config, self.mongo))
            self.height = block.index

        try:
            if self.height > 0:
                last_time = block.time
            special_min = False
            max_target = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
            if self.height > 0:
                time_elapsed_since_last_block = int(
                    time.time()) - int(last_time)

                # special min case
                if time_elapsed_since_last_block > max_block_time:
                    target = max_target
                    special_min = True
            self.target = BlockFactory.get_target(
                self.config, self.mongo, self.height, last_time, block,
                Blockchain(self.config, self.mongo,
                           [x
                            for x in BU.get_blocks(self.config, self.mongo)]))

            self.block_factory = BlockFactory(
                config=self.config,
                mongo=self.mongo,
                transactions=self.get_pending_transactions(),
                public_key=self.config.public_key,
                private_key=self.config.private_key,
                index=self.height,
                version=BU.get_version_for_height(self.height))
            self.block_factory.block.special_min = special_min
            self.block_factory.block.target = self.target
            self.block_factory.header = BlockFactory.generate_header(
                self.block_factory.block)
        except Exception as e:
            raise
Exemplo n.º 6
0
 def broadcast(self):
     Peers.init(self.config, self.mongo, self.config.network)
     for peer in Peers.peers:
         try:
             socketIO = SocketIO(peer.host, peer.port, wait_for_connection=False)
             chat_namespace = socketIO.define(ChatNamespace, '/chat')
             chat_namespace.emit('new-fastgraph-transaction', self.to_dict())
             socketIO.wait(seconds=1)
             chat_namespace.disconnect()
         except Exception as e:
             print e
             pass
Exemplo n.º 7
0
 def broadcast_block(self, block):
     Peers.init(self.config, self.mongo, self.config.network)
     dup_test = self.mongo.db.consensus.find_one({
         'peer':
         'me',
         'index':
         block.index,
         'block.version':
         BU.get_version_for_height(block.index)
     })
     if not dup_test:
         print '\r\nCandidate submitted for index:', block.index
         print '\r\nTransactions:'
         for x in block.transactions:
             print x.transaction_signature
         self.mongo.db.consensus.insert({
             'peer': 'me',
             'index': block.index,
             'id': block.signature,
             'block': block.to_dict()
         })
         print '\r\nSent block to:'
         for peer in Peers.peers:
             if peer.is_me:
                 continue
             try:
                 block_dict = block.to_dict()
                 block_dict['peer'] = Peers.my_peer
                 requests.post('http://{peer}/newblock'.format(
                     peer=peer.host + ":" + str(peer.port)),
                               json=block_dict,
                               timeout=3,
                               headers={'Connection': 'close'})
                 print peer.host + ":" + str(peer.port)
             except Exception as e:
                 print e
                 try:
                     print 'reporting bad peer'
                     if self.config.network == 'mainnet':
                         url = 'https://yadacoin.io/peers'
                     elif self.config.network == 'testnet':
                         url = 'http://yadacoin.io:8888/peers'
                     requests.post(url,
                                   json={
                                       'host': peer.host,
                                       'port': str(peer.port),
                                       'failed': True
                                   },
                                   timeout=3,
                                   headers={'Connection': 'close'})
                 except:
                     print 'failed to report bad peer'
                     pass
Exemplo n.º 8
0
 def do_payout(self):
     network = getattr(self.config, 'network', None)
     if network:
         Peers.init(self.config, self.mongo, network)
     else:
         Peers.init(self.config, self.mongo)
     # first check which blocks we won.
     # then determine if we have already paid out
     # they must be 6 blocks deep
     latest_block = Block.from_dict(self.config, self.mongo, BU.get_latest_block(self.config, self.mongo))
     won_blocks = self.mongo.db.blocks.find({'transactions.outputs.to': self.config.address}).sort([('index', 1)])
     for won_block in won_blocks:
         won_block = Block.from_dict(self.config, self.mongo, won_block)
         if (won_block.index + 6) <= latest_block.index:
             self.do_payout_for_block(won_block)
Exemplo n.º 9
0
    def run(cls, config, mongo, to, value):
        Peers.init(config, mongo, config.network)

        try:
            transaction = TransactionFactory(config,
                                             mongo,
                                             block_height=BU.get_latest_block(
                                                 config, mongo)['index'],
                                             fee=0.01,
                                             public_key=config.public_key,
                                             private_key=config.private_key,
                                             outputs=[{
                                                 'to': to,
                                                 'value': value
                                             }])
        except NotEnoughMoneyException as e:
            print "not enough money yet"
            return
        except:
            raise
        try:
            transaction.transaction.verify()
        except:
            print 'transaction failed'
        TU.save(config, mongo, transaction.transaction)
        print 'Transaction generated successfully. Sending:', value, 'To:', to
        for peer in Peers.peers:
            try:
                with SocketIO(peer.host,
                              peer.port,
                              ChatNamespace,
                              wait_for_connection=False) as socketIO:
                    chat_namespace = socketIO.define(ChatNamespace, '/chat')
                    chat_namespace.emit('newtransaction',
                                        transaction.transaction.to_dict())
                    socketIO.disconnect()
                    print 'Sent to:', peer.host, peer.port
            except Exception as e:
                print e
Exemplo n.º 10
0
    def retrace(self, block, peer):
        if self.debug:
            self.log("retracing...")
        blocks = []
        blocks.append(block)
        while 1:
            if self.debug:
                self.log(block.hash)
                self.log(block.index)
            # get the previous block from either the consensus collection in mongo
            # or attempt to get the block from the remote peer
            previous_consensus_block = self.get_previous_consensus_block_from_local(block, peer)
            if previous_consensus_block:
                    block = previous_consensus_block
                    blocks.append(block)
            else:
                if peer.is_me:
                    self.mongo.db.consensus.update({'peer': peer.to_string(), 'index': {'$gte': block.index}}, {'$set': {'ignore': True}}, multi=True)
                    return
                try:
                    previous_consensus_block = self.get_previous_consensus_block_from_remote(block, peer)
                except BadPeerException as e:
                    self.mongo.db.consensus.update({'peer': peer.to_string(), 'index': {'$gte': block.index}}, {'$set': {'ignore': True}}, multi=True)
                except:
                    pass
                if previous_consensus_block and previous_consensus_block.index + 1 == block.index:
                    block = previous_consensus_block
                    blocks.append(block)
                    try:
                        self.insert_consensus_block(block, peer)
                    except Exception as e:
                        if self.debug:
                            print e # we should do something here to keep it from looping on this failed block
                else:
                    # identify missing and prune
                    # if the pruned chain is still longer, we'll take it
                    if previous_consensus_block:
                        block = previous_consensus_block
                        blocks = [block]
                    else:
                        return
            if self.debug:
                print 'attempting sync at', block.prev_hash
            # if they do have it, query our consensus collection for prevHash of that block, repeat 1 and 2 until index 1
            if self.existing_blockchain.blocks[block.index - 1].hash == block.prev_hash:
                prev_blocks_check = self.existing_blockchain.blocks[block.index - 1]
                if self.debug:
                    print prev_blocks_check.hash, prev_blocks_check.index
                blocks = sorted(blocks, key=lambda x: x.index)
                block_for_next = blocks[-1]
                while 1:
                    next_block = self.get_next_consensus_block_from_local(block_for_next)
                    if next_block:
                        blocks.append(next_block)
                        block_for_next = next_block
                    else:
                        break

                Peers.init(self.config, self.mongo, self.config.network)

                for peer in Peers.peers:
                    while 1:
                        try:
                            if self.debug:
                                print 'requesting %s from %s' % (block_for_next.index + 1, peer.to_string()) 
                            result = requests.get('http://{peer}/get-blocks?start_index={start_index}&end_index={end_index}'.format(
                                peer=peer.to_string(),
                                start_index=block_for_next.index + 1,
                                end_index=block_for_next.index + 100
                            ), timeout=1)
                            remote_blocks = [Block.from_dict(self.config, self.mongo, x) for x in json.loads(result.content)]
                            break_out = False
                            for remote_block in remote_blocks:
                                if remote_block.prev_hash == block_for_next.hash:
                                    blocks.append(remote_block)
                                    block_for_next = remote_block
                                else:
                                    break_out = True
                                    break
                            if break_out:
                                break
                        except Exception as e:
                            if self.debug:
                                print e
                            break

                # if we have it in our blockchain, then we've hit the fork point
                # now we have to loop through the current block array and build a blockchain
                # then we compare the block height and difficulty of the two chains
                # replace our current chain if necessary by removing them from the database
                # then looping though our new chain, inserting the new blocks
                def subchain_gen(existing_blocks, addon_blocks, gen_block):
                    for x in existing_blocks[:addon_blocks[0].index]:
                        if x.index < gen_block.index:
                            yield x
                    for x in addon_blocks:
                        yield x

                # If the block height is equal, we throw out the inbound chain, it muse be greater
                # If the block height is lower, we throw it out
                # if the block height is heigher, we compare the difficulty of the entire chain

                existing_difficulty = self.get_difficulty(self.existing_blockchain.blocks)

                inbound_difficulty = self.get_difficulty(subchain_gen(self.existing_blockchain.blocks, blocks, block))

                if (blocks[-1].index >= self.existing_blockchain.blocks[-1].index
                    and inbound_difficulty >= existing_difficulty):
                    for block in blocks:
                        try:
                            if block.index == 0:
                                continue
                            self.integrate_block_with_existing_chain(block)
                            if self.debug:
                                print 'inserted ', block.index
                        except ForkException as e:
                            back_one_block = block
                            while 1:
                                back_one_block = self.mongo.db.consensus.find_one({'block.hash': back_one_block.prev_hash})
                                if back_one_block:
                                    back_one_block = Block.from_dict(self.config, self.mongo, back_one_block['block'])
                                    try:
                                        result = self.integrate_block_with_existing_chain(back_one_block)
                                        if result:
                                            self.integrate_block_with_existing_chain(block)
                                            break
                                    except ForkException as e:
                                        pass
                                else:
                                    return
                        except AboveTargetException as e:
                            return
                        except IndexError as e:
                            return
                    if self.debug:
                        print "Replaced chain with incoming"
                    return
                else:
                    if not peer.is_me:
                        if self.debug:
                            print (
                                "Incoming chain lost", 
                                inbound_difficulty, 
                                existing_difficulty, 
                                blocks[-1].index, 
                                self.existing_blockchain.blocks[-1].index
                            )
                        for block in blocks:
                            self.mongo.db.consensus.update({'block.hash': block.hash}, {'$set': {'ignore': True}}, multi=True)
                    return
            # lets go down the hash path to see where prevHash is in our blockchain, hopefully before the genesis block
            # we need some way of making sure we have all previous blocks until we hit a block with prevHash in our main blockchain
            #there is no else, we just loop again
            # if we get to index 1 and prev hash doesn't match the genesis, throw out the chain and black list the peer
            # if we get a fork point, prevHash is found in our consensus or genesis, then we compare the current
            # blockchain against the proposed chain. 
            if block.index == 0:
                if self.debug:
                    print "zero index reached"
                return
        if self.debug:
            print "doesn't follow any known chain" # throwing out the block for now
        return