Exemplo n.º 1
0
  def start_payment_loop(self):
    coin = Bank.get().get_acoins(1)
    if not coin:
      log_msg("No ACoins left!")
      return
    coin = coin[0]
    #generate ACoin request
    request = BankMessages.make_acoin_request(Bank.get(), Bank.get().currentACoinInterval, 1)
    #make the message:
    bankMsg = Basic.write_byte(1)
    bankMsg += coin.write_binary() + request.msg
    key = EncryptedDatagram.ClientSymKey(Bank.get().PUBLIC_KEY)
    bankMsg = Basic.write_byte(1) + key.encrypt(Basic.write_byte(3) + bankMsg)
    payment = UDPPayment.UDPPayment(Bank.get(), bankMsg)
    paymentDeferred = payment.get_deferred()
    def success(result, request=request):
      log_msg("success")
      self.payments += 1
#      self.start_payment_loop()
      #validate the ACoin
      code, sig = Basic.read_byte(result)
      coin = BankMessages.parse_acoin_response(Bank.get(), sig, request, False)
      if not coin:
        log_msg("Invalid ACoin sent for payment!")
      else:
        Bank.get().on_earned_coin(coin)
    paymentDeferred.addCallback(success)
    def failure(error):
      self.start_payment_loop()
      log_ex(error, "Failure during test?")
      self.failures += 1
    paymentDeferred.addErrback(failure)
Exemplo n.º 2
0
 def stringReceived(self, encryptedMsg):
   self.responseReceived = True
   self.transport.loseConnection()
   blob = self.factory.bank.decrypt_message(encryptedMsg)
   log_msg("ACoin REQUEST response received.", 4)
   responseCode, blob = Basic.read_byte(blob)
   #we had enough credits in our account
   if responseCode == 0:
     (newBalance, number), coins = Basic.read_message('!II', blob)
     #update the balance
     self.factory.bank.on_new_balance_from_bank(newBalance)
     acoinStrFormat = "%ss" % (Globals.ACOIN_KEY_BYTES)
     format = '!' + (acoinStrFormat * number)
     sigs = list(struct.unpack(format, coins))
     while len(self.factory.requests) > 0:
       request = self.factory.requests.pop(0)
       sig = sigs.pop(0)
       coin = BankMessages.parse_acoin_response(self.factory.bank, sig, request, ProgramState.DEBUG)
       if coin:
         self.factory.bank.add_acoin(coin)
       else:
         log_msg("Got an invalid ACoin from the bank!?", 3)
   #the bank could not check out the coins because our account doesn't have enough credits!
   else:
     (newBalance,), blob = Basic.read_message('!I', blob)
     self.factory.bank.on_new_balance_from_bank(newBalance)
Exemplo n.º 3
0
    def success(result, request=request):
      log_msg("success")
      self.payments += 1
#      self.start_payment_loop()
      #validate the ACoin
      code, sig = Basic.read_byte(result)
      coin = BankMessages.parse_acoin_response(Bank.get(), sig, request, False)
      if not coin:
        log_msg("Invalid ACoin sent for payment!")
      else:
        Bank.get().on_earned_coin(coin)
Exemplo n.º 4
0
 def generate_payment_request_message(self):
   """Create a payment request object, store it for later, increase ID, and create the message associated with it
   @returns: str (message for payment request)"""
   #REFACTOR
   cost = self.torApp.get_relay().get_cost()
   interval = self.bank.currentACoinInterval
   #generate ACoin request
   request = BankMessages.make_acoin_request(self.bank, interval, cost)
   request.id = self.currentRequestId
   self.requests[request.id] = request
   self.currentRequestId += 1
   return Basic.write_long(request.id) + request.msg + Globals.PRIVATE_KEY.sign(request.msg)
Exemplo n.º 5
0
 def success(result, request=request):
     log_msg("success")
     self.payments += 1
     #      self.start_payment_loop()
     #validate the ACoin
     code, sig = Basic.read_byte(result)
     coin = BankMessages.parse_acoin_response(Bank.get(), sig, request,
                                              False)
     if not coin:
         log_msg("Invalid ACoin sent for payment!")
     else:
         Bank.get().on_earned_coin(coin)
Exemplo n.º 6
0
 def __init__(self, bank, value, number):
   BankMessages.BankConnectionFactory.__init__(self, bank)
   #: the value for each ACoin to have, individually
   self.value = value
   #:  a list of all ACoinRequests
   self.requests = []
   #: how many coins to request
   self.number = number
   interval = self.bank.currentACoinInterval
   for i in range(0, number):
     #store the values for later:
     self.requests.append(BankMessages.make_acoin_request(self.bank, interval, value))
Exemplo n.º 7
0
 def generate_payment_request_message(self):
     """Create a payment request object, store it for later, increase ID, and create the message associated with it
 @returns: str (message for payment request)"""
     #REFACTOR
     cost = self.torApp.get_relay().get_cost()
     interval = self.bank.currentACoinInterval
     #generate ACoin request
     request = BankMessages.make_acoin_request(self.bank, interval, cost)
     request.id = self.currentRequestId
     self.requests[request.id] = request
     self.currentRequestId += 1
     return Basic.write_long(
         request.id) + request.msg + Globals.PRIVATE_KEY.sign(request.msg)
Exemplo n.º 8
0
    def start_payment_loop(self):
        coin = Bank.get().get_acoins(1)
        if not coin:
            log_msg("No ACoins left!")
            return
        coin = coin[0]
        #generate ACoin request
        request = BankMessages.make_acoin_request(
            Bank.get(),
            Bank.get().currentACoinInterval, 1)
        #make the message:
        bankMsg = Basic.write_byte(1)
        bankMsg += coin.write_binary() + request.msg
        key = EncryptedDatagram.ClientSymKey(Bank.get().PUBLIC_KEY)
        bankMsg = Basic.write_byte(1) + key.encrypt(
            Basic.write_byte(3) + bankMsg)
        payment = UDPPayment.UDPPayment(Bank.get(), bankMsg)
        paymentDeferred = payment.get_deferred()

        def success(result, request=request):
            log_msg("success")
            self.payments += 1
            #      self.start_payment_loop()
            #validate the ACoin
            code, sig = Basic.read_byte(result)
            coin = BankMessages.parse_acoin_response(Bank.get(), sig, request,
                                                     False)
            if not coin:
                log_msg("Invalid ACoin sent for payment!")
            else:
                Bank.get().on_earned_coin(coin)

        paymentDeferred.addCallback(success)

        def failure(error):
            self.start_payment_loop()
            log_ex(error, "Failure during test?")
            self.failures += 1

        paymentDeferred.addErrback(failure)
Exemplo n.º 9
0
    def handle_payment(self, msg):
        """Unpack, process, and respond to a payment message.
    @param msg:  the payment message from the origin.
    @type  msg:  str"""
        #if there are any failures, log them, and close the circuit:
        try:
            #read the PAR protocol version:
            version, msg = Basic.read_byte(msg)
            assert version == 1, "currently only accept PAR version 1"
            readTokens, msg = Basic.read_int(msg)
            writeTokens, msg = Basic.read_int(msg)
            #read their request ID too
            theirId, msg = Basic.read_long(msg)
            #read the number of coins:
            numCoins, msg = Basic.read_byte(msg)
            #read each coin:
            creditsEarned = 0
            requests = []
            for i in range(0, numCoins):
                #what type of coin is this?
                coinType, msg = Basic.read_byte(msg)
                #we only accept acoins for now:
                assert coinType == PaymentStream.COIN_TYPES[
                    'A'], "bad coin type"
                #get the matching request:
                requestId, msg = Basic.read_long(msg)
                requests.append(requestId)
            assert len(msg) % numCoins == 0, "bad payment message length"
            coinLen = len(msg) / numCoins
            for requestId in requests:
                #if this is not true, there wont even be another part to the response
                assert Basic.read_byte(msg)[0] == ord(
                    '0'), "bad leading byte in payment message"
                blob, msg = msg[:coinLen], msg[coinLen:]
                request = self.requests[requestId]
                del self.requests[requestId]
                code, sig = Basic.read_byte(blob)
                #validate the ACoin
                coin = BankMessages.parse_acoin_response(
                    self.bank, sig, request)
                if not coin:
                    raise Exception("Invalid ACoin sent for payment!")
                #success!
                creditsEarned += coin.get_expected_value()
                coin.originCircuit = self
                self.bank.on_earned_coin(coin)
            receiptMessageDeferred = self.send_receipt_message(
                theirId, numCoins)
            if not receiptMessageDeferred:
                return
            #check that they paid enough:
            requestedTokens = readTokens + writeTokens
            paidTokens = creditsEarned * Globals.CELLS_PER_PAYMENT
            if paidTokens < requestedTokens:
                raise Exception("Relays asked for %s, but only paid for %s" %
                                (requestedTokens, paidTokens))
            #inform Tor that we got a payment message:
            addTokensDeferred = self.add_tokens(readTokens, writeTokens)
            if not addTokensDeferred:
                return

            def response(result):
                if result:
                    read, write = result
                    log_msg(
                        "%s paid us %s for exit stream, now %d / %d" %
                        (Basic.clean(self.baseCircuit.prevHexId[:4]),
                         creditsEarned, read, write), 3, "par")

            addTokensDeferred.addCallback(response)
        except Exception, error:
            log_ex(error, "Got bad PAR message")
            self.close()
Exemplo n.º 10
0
 def handle_payment(self, msg):
   """Unpack, process, and respond to a payment message.
   @param msg:  the payment message from the origin.
   @type  msg:  str"""
   #if there are any failures, log them, and close the circuit:
   try:
     #read the PAR protocol version:
     version, msg = Basic.read_byte(msg)
     assert version == 1, "currently only accept PAR version 1"
     readTokens, msg = Basic.read_int(msg)
     writeTokens, msg = Basic.read_int(msg)
     #read their request ID too
     theirId, msg = Basic.read_long(msg)
     #read the number of coins:
     numCoins, msg = Basic.read_byte(msg)
     #read each coin:
     creditsEarned = 0
     requests = []
     for i in range(0, numCoins):
       #what type of coin is this?
       coinType, msg = Basic.read_byte(msg)
       #we only accept acoins for now:
       assert coinType == PaymentStream.COIN_TYPES['A'], "bad coin type"
       #get the matching request:
       requestId, msg = Basic.read_long(msg)
       requests.append(requestId)
     assert len(msg) % numCoins == 0, "bad payment message length"
     coinLen = len(msg) / numCoins
     for requestId in requests:
       #if this is not true, there wont even be another part to the response
       assert Basic.read_byte(msg)[0] == ord('0'), "bad leading byte in payment message"
       blob, msg = msg[:coinLen], msg[coinLen:]
       request = self.requests[requestId]
       del self.requests[requestId]
       code, sig = Basic.read_byte(blob)
       #validate the ACoin
       coin = BankMessages.parse_acoin_response(self.bank, sig, request)
       if not coin:
         raise Exception("Invalid ACoin sent for payment!")
       #success!
       creditsEarned += coin.get_expected_value()
       coin.originCircuit = self
       self.bank.on_earned_coin(coin)
     receiptMessageDeferred = self.send_receipt_message(theirId, numCoins)
     if not receiptMessageDeferred:
       return
     #check that they paid enough:
     requestedTokens = readTokens + writeTokens
     paidTokens = creditsEarned * Globals.CELLS_PER_PAYMENT
     if paidTokens < requestedTokens:
       raise Exception("Relays asked for %s, but only paid for %s" % (requestedTokens, paidTokens))
     #inform Tor that we got a payment message:
     addTokensDeferred = self.add_tokens(readTokens, writeTokens)
     if not addTokensDeferred:
       return
     def response(result):
       if result:
         read, write = result
         log_msg("%s paid us %s for exit stream, now %d / %d" % (Basic.clean(self.baseCircuit.prevHexId[:4]), creditsEarned, read, write), 3, "par")
     addTokensDeferred.addCallback(response)
   except Exception, error:
     log_ex(error, "Got bad PAR message")
     self.close()