예제 #1
0
 def get_shared_secrets_by_rid(cls, config, mongo, rid):
     from blockchainutils import BU
     shared_secrets = []
     dh_public_keys = []
     dh_private_keys = []
     txns = BU.get_transactions_by_rid(config,
                                       mongo,
                                       rid,
                                       config.bulletin_secret,
                                       rid=True)
     for txn in txns:
         if str(txn['public_key']) == str(
                 config.public_key
         ) and txn['relationship']['dh_private_key']:
             dh_private_keys.append(txn['relationship']['dh_private_key'])
     txns = BU.get_transactions_by_rid(config,
                                       mongo,
                                       rid,
                                       config.bulletin_secret,
                                       rid=True,
                                       raw=True)
     for txn in txns:
         if str(txn['public_key']) != str(
                 config.public_key) and txn['dh_public_key']:
             dh_public_keys.append(txn['dh_public_key'])
     for dh_public_key in dh_public_keys:
         for dh_private_key in dh_private_keys:
             shared_secrets.append(
                 scalarmult(dh_private_key.decode('hex'),
                            dh_public_key.decode('hex')))
     return shared_secrets
예제 #2
0
    def sync_bottom_up(self):
        #bottom up syncing

        self.latest_block = Block.from_dict(
            self.config, self.mongo,
            BU.get_latest_block(self.config, self.mongo))
        self.remove_pending_transactions_now_in_chain()
        self.remove_fastgraph_transactions_now_in_chain()

        latest_consensus = self.mongo.db.consensus.find_one(
            {'index': self.latest_block.index + 1})
        if latest_consensus:
            latest_consensus = Block.from_dict(self.config, self.mongo,
                                               latest_consensus['block'])
            print latest_consensus.index, "latest consensus_block"

            records = self.mongo.db.consensus.find({
                'index':
                self.latest_block.index + 1,
                'block.version':
                BU.get_version_for_height(self.latest_block.index + 1),
                'ignore': {
                    '$ne': True
                }
            })
            for record in sorted(records,
                                 key=lambda x: int(x['block']['target'], 16)):
                self.import_block(record)
                break
        else:
            self.log('up to date, height: ' + str(self.latest_block.index))
            return
예제 #3
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
예제 #4
0
    def get_origin_relationship(self, rid=None, bulletin_secret=None):
        for inp in self.inputs:
            inp = inp.id
            while 1:
                txn = BU.get_transaction_by_id(self.config, self.mongo, inp, give_block=False, include_fastgraph=True)
                if txn:
                    if 'rid' in txn and txn['rid'] and 'dh_public_key' in txn and txn['dh_public_key']:
                        if rid and txn['rid'] != rid:
                            continue
                        rids = [txn['rid']]
                        if 'requester_rid' in txn and txn['requester_rid']:
                            rids.append(txn['requester_rid'])
                        if 'requested_rid' in txn and txn['requested_rid']:
                            rids.append(txn['requested_rid'])
                        
                        # we need their public_key, not mine, so we get both transactions for the relationship
                        txn_for_rids = BU.get_transaction_by_rid(self.config, self.mongo, rids, bulletin_secret=bulletin_secret, raw=True, rid=True, theirs=True, public_key=self.public_key)

                        if txn_for_rids:
                            return txn_for_rids
                        else:
                            return False
                    else:
                        inp = txn['inputs'][0]['id']
                else:
                    txn = self.mongo.db.fastgraph_transactions.find_one({'id': inp})
                    if txn and 'inputs' in txn['txn'] and txn['txn']['inputs'] and 'id' in txn['txn']['inputs'][0]:
                        inp = txn['txn']['inputs'][0]['id']
                    else:
                        return False
예제 #5
0
    def verify(self):
        super(FastGraph, self).verify()
        result = self.mongo.db.fastgraph_transactions.find_one({
            'txn.hash': self.hash
        })
        
        if not self.signatures:
            raise InvalidFastGraphTransactionException('no signatures were provided')

        xaddress = str(P2PKHBitcoinAddress.from_pubkey(self.public_key.decode('hex')))
        unspent = [x['id'] for x in BU.get_wallet_unspent_transactions(self.config, self.mongo, xaddress)]
        unspent_fastgraph = [x['id'] for x in BU.get_wallet_unspent_fastgraph_transactions(self.config, self.mongo, xaddress)]
        inputs = [x.id for x in self.inputs]
        if len(set(inputs) & set(unspent)) != len(inputs) and len(set(inputs) & set(unspent_fastgraph)) != len(inputs):
            raise InvalidFastGraphTransactionException('Input not found in unspent')

        txn_for_rids = self.get_origin_relationship()
        if not txn_for_rids:
            raise InvalidFastGraphTransactionException('no origin transactions found')
        public_key = txn_for_rids['public_key']

        for signature in self.signatures:
            signature.passed = False
            signed = verify_signature(
                base64.b64decode(signature.signature),
                self.hash,
                public_key.decode('hex')
            )
            if signed:
                signature.passed = True

            """
            # This is for a later fork to include a wider consensus area for a larger spending group
            else:
                mutual_friends = [x for x in BU.get_transactions_by_rid(self.config, self.mongo, self.rid, self.config.bulletin_secret, raw=True, rid=True, lt_block_height=highest_height)]
                for mutual_friend in mutual_friends:
                    mutual_friend = Transaction.from_dict(self.config, self.mongo, mutual_friend)
                    if isinstance(mutual_friend.relationship, Relationship) and signature.bulletin_secret == mutual_friend.relationship.their_bulletin_secret:
                        other_mutual_friend = mutual_friend
                for mutual_friend in mutual_friends:
                    mutual_friend = Transaction.from_dict(self.config, self.mongo, mutual_friend)
                    if mutual_friend.public_key != self.config.public_key:
                        identity = verify_signature(
                            base64.b64decode(other_mutual_friend.relationship.their_bulletin_secret),
                            other_mutual_friend.relationship.their_username,
                            mutual_friend.public_key.decode('hex')
                        )
                        signed = verify_signature(
                            base64.b64decode(signature.signature),
                            self.hash,
                            mutual_friend.public_key.decode('hex')
                        )
                        if identity and signed:
                            signature.passed = True
            """
        for signature in self.signatures:
            if not signature.passed:
                raise InvalidFastGraphTransactionException('not all signatures verified')
예제 #6
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
예제 #7
0
 def get_lookup_rids(self):
     lookup_rids = [
         self.rid,
     ]
     lookup_rids.extend(
         [x['rid'] for x in BU.get_friend_requests(self.rid)])
     lookup_rids.extend(
         [x['rid'] for x in BU.get_sent_friend_requests(self.rid)])
     return list(set(lookup_rids))
예제 #8
0
파일: block.py 프로젝트: icook/yadacoin
    def verify(self):
        getcontext().prec = 8
        if int(self.version) != int(BU.get_version_for_height(self.index)):
            raise BaseException("Wrong version for block height", self.version,
                                BU.get_version_for_height(self.index))
        try:
            txns = self.get_transaction_hashes()
            self.set_merkle_root(txns)
            if self.verify_merkle_root != self.merkle_root:
                raise BaseException("Invalid block")
        except:
            raise

        try:
            header = BlockFactory.generate_header(self)
            hashtest = BlockFactory.generate_hash_from_header(
                header, str(self.nonce))
            if self.hash != hashtest:
                raise BaseException('Invalid block')
        except:
            raise

        address = P2PKHBitcoinAddress.from_pubkey(
            self.public_key.decode('hex'))
        try:
            result = verify_signature(base64.b64decode(self.signature),
                                      self.hash, self.public_key.decode('hex'))
            if not result:
                raise Exception("block signature is invalid")
        except:
            try:
                result = VerifyMessage(address,
                                       BitcoinMessage(self.hash, magic=''),
                                       self.signature)
                if not result:
                    raise
            except:
                raise BaseException("block signature is invalid")

        # verify reward
        coinbase_sum = 0
        for txn in self.transactions:
            if txn.coinbase:
                for output in txn.outputs:
                    coinbase_sum += float(output.value)

        fee_sum = 0.0
        for txn in self.transactions:
            if not txn.coinbase:
                fee_sum += float(txn.fee)
        reward = BU.get_block_reward(self.config, self.mongo, self)

        if Decimal(str(fee_sum)[:10]) != (Decimal(str(coinbase_sum)[:10]) -
                                          Decimal(str(reward)[:10])):
            raise BaseException(
                "Coinbase output total does not equal block reward + transaction fees",
                fee_sum, (coinbase_sum - reward))
예제 #9
0
    def run(cls, config, mongo):
        used_inputs = []
        new_inputs = []
        for x in mongo.site_db.faucet.find({'active': True}):
            balance = BU.get_wallet_balance(config, mongo, x['address'])
            if balance >= 25:
                mongo.site_db.faucet.update({'_id': x['_id']}, {
                    'active': False,
                    'address': x['address']
                })

                continue
            last_id_in_blockchain = x.get('last_id')
            if last_id_in_blockchain and not mongo.db.blocks.find({
                    'transactions.id':
                    last_id_in_blockchain
            }).count():

                continue

            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=[Output(to=x['address'], value=5)])
            except NotEnoughMoneyException as e:
                print "not enough money yet"
                return
            except Exception as e:
                print x
            try:
                transaction.transaction.verify()
            except:
                mongo.site_db.failed_faucet_transactions.insert(
                    transaction.transaction.to_dict())
                print 'faucet transaction failed'
            TU.save(config, mongo, transaction.transaction)
            x['last_id'] = transaction.transaction.transaction_signature
            mongo.site_db.faucet.update({'_id': x['_id']}, x)
            print 'saved. sending...', x['address']
            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()
                except Exception as e:
                    print e
예제 #10
0
 def __init__(self, config, mongo, debug=False):
     self.debug = debug
     self.config = config
     self.mongo = mongo
     latest_block = BU.get_latest_block(self.config, self.mongo)
     if latest_block:
         self.latest_block = Block.from_dict(self.config, self.mongo, latest_block)
     else:
         self.insert_genesis()
     
     self.existing_blockchain = Blockchain(self.config, self.mongo, BU.get_blocks(self.config, self.mongo))
예제 #11
0
    def with_private_key(self):
        all_relationships = [x for x in BU.get_transactions() if x['rid']]
        self.rid_usernames = dict(
            (x['rid'], x['relationship']['their_username'])
            for x in all_relationships)

        rids = [x['rid'] for x in all_relationships]
        self.rid_transactions = BU.get_transactions_by_rid(rids,
                                                           rid=True,
                                                           raw=True,
                                                           returnheight=True)
예제 #12
0
    def get_request_rids_for_rid(self):
        lookup_rids = {}
        for x in BU.get_friend_requests(self.rid):
            if x['rid'] not in lookup_rids:
                lookup_rids[x['rid']] = []
            lookup_rids[x['rid']].append(x['requester_rid'])

        for x in BU.get_sent_friend_requests(self.rid):
            if x['rid'] not in lookup_rids:
                lookup_rids[x['rid']] = []
            lookup_rids[x['rid']].append(x['requested_rid'])

        return lookup_rids
예제 #13
0
 def get_next_consensus_block_from_local(self, block):
     #table cleanup
     new_block = self.mongo.db.consensus.find_one({
         'block.prevHash': block.hash,
         'block.index': (block.index + 1),
         'block.version': BU.get_version_for_height((block.index + 1))
     })
     if new_block:
         new_block = Block.from_dict(self.config, self.mongo, new_block['block'])
         if int(new_block.version) == BU.get_version_for_height(new_block.index):
             return new_block
         else:
             return None
     return None
예제 #14
0
    def do_money(self):
        my_address = str(P2PKHBitcoinAddress.from_pubkey(self.public_key.decode('hex')))
        input_txns = BU.get_wallet_unspent_transactions(self.config, self.mongo, my_address)
        miner_transactions = self.mongo.db.miner_transactions.find()
        mtxn_ids = []
        for mtxn in miner_transactions:
            for mtxninput in mtxn['inputs']:
                mtxn_ids.append(mtxninput['id'])

        inputs = self.inputs or [Input.from_dict(input_txn) for input_txn in input_txns if input_txn['id'] not in mtxn_ids]

        input_sum = 0
        if self.coinbase:
            self.inputs = []
        else:
            if inputs:
                needed_inputs = []
                done = False
                for y in inputs:
                    print y.id
                    txn = BU.get_transaction_by_id(self.config, self.mongo, y.id, instance=True)
                    for txn_output in txn.outputs:
                        if txn_output.to == my_address:
                            input_sum += txn_output.value
                            needed_inputs.append(y)
                            if input_sum >= (sum([x.value for x in self.outputs])+self.fee):
                                done = True
                                break
                    if done == True:
                        break

                if not done:
                    raise NotEnoughMoneyException('not enough money')
                self.inputs = needed_inputs
            else:
                self.inputs = []

            remainder = input_sum-(sum([x.value for x in self.outputs])+self.fee)

            found = False
            for x in self.outputs:
                if my_address == x.to:
                    found = True
                    x.value += remainder
            if not found:
                return_change_output = Output(
                    to=my_address,
                    value=remainder
                )
                self.outputs.append(return_change_output)
예제 #15
0
 def get_previous_consensus_block_from_local(self, block, peer):
     #table cleanup
     new_block = self.mongo.db.consensus.find_one({
         'block.hash': block.prev_hash,
         'block.index': (block.index - 1),
         'block.version': BU.get_version_for_height((block.index - 1)),
         'ignore': {'$ne': True}
     })
     if new_block:
         new_block = Block.from_dict(self.config, self.mongo, new_block['block'])
         if int(new_block.version) == BU.get_version_for_height(new_block.index):
             return new_block
         else:
             return None
     return None
예제 #16
0
파일: block.py 프로젝트: icook/yadacoin
 def save(self):
     self.verify()
     for txn in self.transactions:
         if txn.inputs:
             address = str(
                 P2PKHBitcoinAddress.from_pubkey(
                     txn.public_key.decode('hex')))
             unspent = BU.get_wallet_unspent_transactions(
                 self.config, self.mongo, address,
                 [x.id for x in txn.inputs])
             unspent_ids = [x['id'] for x in unspent]
             failed = False
             used_ids_in_this_txn = []
             for x in txn.inputs:
                 if x.id not in unspent_ids:
                     failed = True
                 if x.id in used_ids_in_this_txn:
                     failed = True
                 used_ids_in_this_txn.append(x.id)
             if failed:
                 raise BaseException('double spend',
                                     [x.id for x in txn.inputs])
     res = self.mongo.db.blocks.find({"index": (int(self.index) - 1)})
     if res.count() and res[0]['hash'] == self.prev_hash or self.index == 0:
         self.mongo.db.blocks.insert(self.to_dict())
     else:
         print "CRITICAL: block rejected..."
예제 #17
0
    def get_posts(self):
        if self.wallet_mode:
            self.posts = []
            return

        my_bulletin_secret = Config.get_bulletin_secret()
        posts = []
        blocked = [
            x['username'] for x in Mongo.db.blocked_users.find(
                {'bulletin_secret': self.bulletin_secret})
        ]
        flagged = [
            x['id'] for x in Mongo.db.flagged_content.find(
                {'bulletin_secret': self.bulletin_secret})
        ]
        for x in BU.get_posts(self.rid):
            rids = sorted(
                [str(my_bulletin_secret),
                 str(x.get('bulletin_secret'))],
                key=str.lower)
            rid = hashlib.sha256(str(rids[0]) +
                                 str(rids[1])).digest().encode('hex')
            res = Mongo.site_db.usernames.find({'rid': rid}, {'_id': 0})
            if res.count():
                x['username'] = res[0]['username']
                if x['username'] not in blocked and x['id'] not in flagged:
                    posts.append(x)
        self.posts = posts
예제 #18
0
 def get_latest_consensus_block(self):
     latests = self.get_latest_consensus_blocks()
     for latest in latests:
         if int(latest['block']['version']) == BU.get_version_for_height(
                 latest['block']['index']):
             return Block.from_dict(self.config, self.mongo,
                                    latest['block'])
예제 #19
0
파일: graph.py 프로젝트: icook/yadacoin
    def get_posts(self):
        if self.wallet_mode:
            self.posts = []
            return

        my_bulletin_secret = self.config.bulletin_secret
        posts = []
        blocked = [
            x['username'] for x in self.mongo.db.blocked_users.find(
                {'bulletin_secret': self.bulletin_secret})
        ]
        flagged = [
            x['id'] for x in self.mongo.db.flagged_content.find(
                {'bulletin_secret': self.bulletin_secret})
        ]
        for x in BU.get_posts(self.config, self.mongo, self.rid):
            rids = sorted(
                [str(my_bulletin_secret),
                 str(x.get('bulletin_secret'))],
                key=str.lower)
            rid = hashlib.sha256(str(rids[0]) +
                                 str(rids[1])).digest().encode('hex')
            if rid in self.rid_usernames:
                x['username'] = self.rid_usernames[rid]
                if x['username'] not in blocked and x['id'] not in flagged:
                    posts.append(x)
        self.posts = posts
예제 #20
0
 def get_previous_consensus_block_from_remote(self, block, peer):
     retry = 0
     while True:
         try:
             url = 'http://' + peer.to_string(
             ) + '/get-block?hash=' + block.prev_hash
             print 'getting block', url
             res = requests.get(url,
                                timeout=1,
                                headers={'Connection': 'close'})
         except:
             if retry == 50:
                 raise BadPeerException()
             else:
                 retry += 1
                 continue
         try:
             print 'response code: ', res.status_code
             new_block = Block.from_dict(self.config, self.mongo,
                                         json.loads(res.content))
             if int(new_block.version) == BU.get_version_for_height(
                     new_block.index):
                 return new_block
             else:
                 return None
         except:
             return None
예제 #21
0
 def get_latest_consensus_blocks(self):
     for x in self.mongo.db.consensus.find({}, {
             '_id': 0
     }).sort([('index', -1)]):
         if BU.get_version_for_height(x['block']['index']) == int(
                 x['block']['version']):
             yield x
예제 #22
0
    def get_input_hashes(self):
        from fastgraph import FastGraph
        input_hashes = []
        for x in self.inputs:
            txn = BU.get_transaction_by_id(self.config,
                                           self.mongo,
                                           x.id,
                                           instance=True,
                                           include_fastgraph=isinstance(
                                               self, FastGraph))
            if txn:
                input_hashes.append(str(txn.transaction_signature))
            else:
                found = False
                if self.extra_blocks:
                    for block in self.extra_blocks:
                        for xtxn in block.transactions:
                            if xtxn.transaction_signature == x.id:
                                input_hashes.append(
                                    str(xtxn.transaction_signature))
                                found = True
                                break
                        if found:
                            break
                if not found:
                    raise MissingInputTransactionException(
                        "This transaction is not in the blockchain.")

        return ''.join(sorted(input_hashes, key=lambda v: v.lower()))
예제 #23
0
    def get_input_hashes(self):
        input_hashes = []
        for x in self.inputs:
            txn = BU.get_transaction_by_id(self.config, self.mongo, x.id, instance=True)
            input_hashes.append(str(txn.transaction_signature))

        return ''.join(sorted(input_hashes, key=str.lower))
예제 #24
0
 def nonce_generator(self):
     latest_block_index = BU.get_latest_block(self.config,
                                              self.mongo)['index']
     while 1:
         next_latest_block_index = BU.get_latest_block(
             self.config, self.mongo)['index']
         if latest_block_index < next_latest_block_index:
             latest_block_index = next_latest_block_index
             start_nonce = 0
             self.refresh()
         else:
             try:
                 start_nonce += 1000000
             except:
                 start_nonce = 0
         self.index = latest_block_index
         yield [start_nonce, start_nonce + 1000000]
예제 #25
0
 def get_consensus_blocks_by_index(self, index):
     return self.mongo.db.consensus.find(
         {
             'index': index,
             'block.prevHash': {
                 '$ne': ''
             },
             'block.version': BU.get_version_for_height(index)
         }, {'_id': 0})
예제 #26
0
 def verify(self):
     txn = BU.get_transaction_by_id(self.config,
                                    self.mongo,
                                    self.id,
                                    instance=True)
     result = verify_signature(base64.b64decode(self.signature), self.id,
                               txn.public_key.decode('hex'))
     if not result:
         raise Exception('Invalid external input')
예제 #27
0
    def get_input_hashes(self):
        input_hashes = []
        for x in self.inputs:
            txn = BU.get_transaction_by_id(self.config, self.mongo, x.id, instance=True)
            if not txn:
                raise MissingInputTransactionException("This transaction is not in the blockchain.")
            input_hashes.append(str(txn.transaction_signature))

        return ''.join(sorted(input_hashes, key=lambda v: v.lower()))
예제 #28
0
    def sync_bottom_up(self):
        #bottom up syncing
        last_latest = self.latest_block
        self.latest_block = Block.from_dict(self.config, self.mongo, BU.get_latest_block(self.config, self.mongo))
        if self.latest_block.index > last_latest.index:
            print 'Block height: %s | time: %s' % (self.latest_block.index, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        self.remove_pending_transactions_now_in_chain()
        self.remove_fastgraph_transactions_now_in_chain()

        latest_consensus = self.mongo.db.consensus.find_one({
            'index': self.latest_block.index + 1,
            'block.version': BU.get_version_for_height(self.latest_block.index + 1),
            'ignore': {'$ne': True}
        })
        if latest_consensus:
            latest_consensus = Block.from_dict(self.config, self.mongo, latest_consensus['block'])
            if self.debug:
                print latest_consensus.index, "latest consensus_block"

            records = self.mongo.db.consensus.find({
                'index': self.latest_block.index + 1,
                'block.version': BU.get_version_for_height(self.latest_block.index + 1),
                'ignore': {'$ne': True}
            })
            for record in sorted(records, key=lambda x: int(x['block']['target'], 16)):
                result = self.import_block(record)

            last_latest = self.latest_block
            self.latest_block = Block.from_dict(self.config, self.mongo, BU.get_latest_block(self.config, self.mongo))
            if self.latest_block.index > last_latest.index:
                print 'Block height: %s | time: %s' % (self.latest_block.index, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
            latest_consensus_now = self.mongo.db.consensus.find_one({
                'index': self.latest_block.index + 1,
                'block.version': BU.get_version_for_height(self.latest_block.index + 1),
                'ignore': {'$ne': True}
            })

            if latest_consensus_now and latest_consensus.index == latest_consensus_now['index']:
                self.search_network_for_new()
                return True
        else:
            self.search_network_for_new()
            return True
예제 #29
0
 def __init__(self, config, mongo):
     self.config = config
     self.mongo = mongo
     latest_block = BU.get_latest_block(self.config, self.mongo)
     if latest_block:
         self.latest_block = Block.from_dict(self.config, self.mongo,
                                             latest_block)
     else:
         self.insert_genesis()
     blocks = self.mongo.db.blocks.find({})
     self.existing_blockchain = Blockchain(self.config, self.mongo, blocks)
예제 #30
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