コード例 #1
0
ファイル: fastgraph.py プロジェクト: BadPirateX/yadacoin
    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')
コード例 #2
0
ファイル: block.py プロジェクト: icook/yadacoin
    def __init__(self,
                 config,
                 mongo,
                 transactions,
                 public_key,
                 private_key,
                 version,
                 index=None,
                 force_time=None):
        self.config = config
        self.mongo = mongo
        self.version = BU.get_version_for_height(index)
        if force_time:
            self.time = str(int(force_time))
        else:
            self.time = str(int(time.time()))
        blocks = BU.get_blocks(self.config, self.mongo)
        self.index = index
        if self.index == 0:
            self.prev_hash = ''
        else:
            self.prev_hash = BU.get_latest_block(self.config,
                                                 self.mongo)['hash']
        self.public_key = public_key
        self.private_key = private_key

        transaction_objs = []
        fee_sum = 0.0
        unspent_indexed = {}
        unspent_fastgraph_indexed = {}
        used_sigs = []
        for txn in transactions:
            try:
                if isinstance(txn, Transaction):
                    transaction_obj = txn
                else:
                    transaction_obj = Transaction.from_dict(
                        self.config, self.mongo, txn)

                if transaction_obj.transaction_signature in used_sigs:
                    print 'duplicate transaction found and removed'
                    continue

                used_sigs.append(transaction_obj.transaction_signature)
                transaction_obj.verify()

                if not isinstance(transaction_obj,
                                  FastGraph) and transaction_obj.rid:
                    for input_id in transaction_obj.inputs:
                        input_block = BU.get_transaction_by_id(self.config,
                                                               self.mongo,
                                                               input_id.id,
                                                               give_block=True)
                        if input_block['index'] > (BU.get_latest_block(
                                self.config, self.mongo)['index'] - 2016):
                            continue

            except:
                try:
                    if isinstance(txn, FastGraph):
                        transaction_obj = txn
                    else:
                        transaction_obj = FastGraph(**txn)

                    if transaction_obj.transaction.transaction_signature in used_sigs:
                        print 'duplicate transaction found and removed'
                        continue
                    used_sigs.append(
                        transaction_obj.transaction.transaction_signature)
                    if not transaction_obj.verify():
                        raise InvalidTransactionException(
                            "invalid transactions")
                    transaction_obj = transaction_obj.transaction
                except:
                    raise InvalidTransactionException("invalid transactions")

            address = str(
                P2PKHBitcoinAddress.from_pubkey(
                    transaction_obj.public_key.decode('hex')))
            #check double spend
            if address in unspent_indexed:
                unspent_ids = unspent_indexed[address]
            else:
                res = BU.get_wallet_unspent_transactions(
                    self.config, self.mongo, address)
                unspent_ids = [x['id'] for x in res]
                unspent_indexed[address] = unspent_ids

            if address in unspent_fastgraph_indexed:
                unspent_fastgraph_ids = unspent_fastgraph_indexed[address]
            else:
                res = BU.get_wallet_unspent_fastgraph_transactions(
                    self.config, self.mongo, address)
                unspent_fastgraph_ids = [x['id'] for x in res]
                unspent_fastgraph_indexed[address] = unspent_fastgraph_ids

            failed = False
            used_ids_in_this_txn = []

            for x in transaction_obj.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 not failed:
                transaction_objs.append(transaction_obj)
                fee_sum += float(transaction_obj.fee)
        block_reward = BU.get_block_reward(self.config, self.mongo)
        coinbase_txn_fctry = TransactionFactory(
            config,
            mongo,
            public_key=self.public_key,
            private_key=self.private_key,
            outputs=[
                Output(value=block_reward + float(fee_sum),
                       to=str(
                           P2PKHBitcoinAddress.from_pubkey(
                               self.public_key.decode('hex'))))
            ],
            coinbase=True)
        coinbase_txn = coinbase_txn_fctry.generate_transaction()
        transaction_objs.append(coinbase_txn)

        self.transactions = transaction_objs
        txn_hashes = self.get_transaction_hashes()
        self.set_merkle_root(txn_hashes)
        self.block = Block(self.config,
                           self.mongo,
                           version=self.version,
                           block_time=self.time,
                           block_index=self.index,
                           prev_hash=self.prev_hash,
                           transactions=self.transactions,
                           merkle_root=self.merkle_root,
                           public_key=self.public_key)
コード例 #3
0
ファイル: miningpool.py プロジェクト: icook/yadacoin
    def get_pending_transactions(self):
        transaction_objs = []
        unspent_indexed = {}
        unspent_fastgraph_indexed = {}
        used_sigs = []
        for txn in self.combine_transaction_lists():
            try:
                if isinstance(txn, FastGraph) and hasattr(txn, 'signatures'):
                    transaction_obj = txn
                elif isinstance(txn, Transaction):
                    transaction_obj = txn
                elif isinstance(txn, dict) and 'signatures' in txn:
                    transaction_obj = FastGraph.from_dict(
                        self.config, self.mongo, txn)
                elif isinstance(txn, dict):
                    transaction_obj = Transaction.from_dict(
                        self.config, self.mongo, txn)
                else:
                    print 'transaction unrecognizable, skipping'
                    continue

                if transaction_obj.transaction_signature in used_sigs:
                    print 'duplicate transaction found and removed'
                    continue
                used_sigs.append(transaction_obj.transaction_signature)

                transaction_obj.verify()

                if not isinstance(transaction_obj,
                                  FastGraph) and transaction_obj.rid:
                    for input_id in transaction_obj.inputs:
                        input_block = BU.get_transaction_by_id(self.config,
                                                               self.mongo,
                                                               input_id.id,
                                                               give_block=True)
                        if input_block['index'] > (BU.get_latest_block(
                                self.config, self.mongo)['index'] - 2016):
                            continue

                #check double spend
                address = str(
                    P2PKHBitcoinAddress.from_pubkey(
                        transaction_obj.public_key.decode('hex')))
                if address in unspent_indexed:
                    unspent_ids = unspent_indexed[address]
                else:
                    needed_value = sum([
                        float(x.value) for x in transaction_obj.outputs
                    ]) + float(transaction_obj.fee)
                    res = BU.get_wallet_unspent_transactions(
                        self.config,
                        self.mongo,
                        address,
                        needed_value=needed_value)
                    unspent_ids = [x['id'] for x in res]
                    unspent_indexed[address] = unspent_ids

                if address in unspent_fastgraph_indexed:
                    unspent_fastgraph_ids = unspent_fastgraph_indexed[address]
                else:
                    res = BU.get_wallet_unspent_fastgraph_transactions(
                        self.config, self.mongo, address)
                    unspent_fastgraph_ids = [x['id'] for x in res]
                    unspent_fastgraph_indexed[address] = unspent_fastgraph_ids

                failed1 = False
                failed2 = False
                used_ids_in_this_txn = []

                for x in transaction_obj.inputs:
                    if x.id not in unspent_ids:
                        failed1 = True
                    if x.id in used_ids_in_this_txn:
                        failed2 = True
                    used_ids_in_this_txn.append(x.id)
                if failed1:
                    self.mongo.db.miner_transactions.remove(
                        {'id': transaction_obj.transaction_signature})
                    print 'transaction removed: input presumably spent already, not in unspent outputs', transaction_obj.transaction_signature
                    self.mongo.db.failed_transactions.insert({
                        'reason':
                        'input presumably spent already',
                        'txn':
                        transaction_obj.to_dict()
                    })
                elif failed2:
                    self.mongo.db.miner_transactions.remove(
                        {'id': transaction_obj.transaction_signature})
                    print 'transaction removed: using an input used by another transaction in this block', transaction_obj.transaction_signature
                    self.mongo.db.failed_transactions.insert({
                        'reason':
                        'using an input used by another transaction in this block',
                        'txn':
                        transaction_obj.to_dict()
                    })
                else:
                    transaction_objs.append(transaction_obj)
            except MissingInputTransactionException as e:
                #print 'missing this input transaction, will try again later'
                pass
            except InvalidTransactionSignatureException as e:
                print 'InvalidTransactionSignatureException: transaction removed'
                self.mongo.db.miner_transactions.remove(
                    {'id': transaction_obj.transaction_signature})
                self.mongo.db.failed_transactions.insert({
                    'reason':
                    'InvalidTransactionSignatureException',
                    'txn':
                    transaction_obj.to_dict()
                })
            except InvalidTransactionException as e:
                print 'InvalidTransactionException: transaction removed'
                self.mongo.db.miner_transactions.remove(
                    {'id': transaction_obj.transaction_signature})
                self.mongo.db.failed_transactions.insert({
                    'reason':
                    'InvalidTransactionException',
                    'txn':
                    transaction_obj.to_dict()
                })
            except Exception as e:
                print e
                #print 'rejected transaction', txn['id']
                pass
            except BaseException as e:
                print e
                #print 'rejected transaction', txn['id']
                pass
        return transaction_objs