Пример #1
0
	def msg_haveRoute(self, msg):
		#Special case for payee->payer transmission of this message type:
		if msg.ID == messages.payerLocalID:
			return self.payerLink.haveRouteIncoming(msg)

		#TODO: check sanity (and data type) of startTime, endTime

		ret = []

		if msg.isPayerSide:
			tx = self.findTransaction(
				transactionID=msg.transactionID, payeeID=msg.ID, isPayerSide=True)
			payer = self.__getLinkObject(tx.payerID)
			payee = self.__getLinkObject(tx.payeeID)
			ret += payee.haveRouteIncoming(msg)
			msg.ID = tx.payerID
			msg.endTime += self.settings.timeoutIncrement
			ret += payer.haveRouteOutgoing(msg)
		else:
			tx = self.findTransaction(
				transactionID=msg.transactionID, payerID=msg.ID, isPayerSide=False)
			payer = self.__getLinkObject(tx.payerID)
			payee = self.__getLinkObject(tx.payeeID)
			ret += payer.haveRouteIncoming(msg)
			msg.ID = tx.payeeID
			msg.endTime -= self.settings.timeoutIncrement
			ret += payee.haveRouteOutgoing(msg)
			#TODO: compare startTime, endTime with MakeRoute values

		tx.state = transaction.Transaction.states.haveRoute

		#Lock time-out:
		#TODO: configurable time-out value?
		ret.append(messages.TimeoutMessage(timestamp=time.time()+5.0, message=\
			messages.NodeStateTimeout_Lock(
				transactionID=msg.transactionID, isPayerSide=msg.isPayerSide,
				payerID=tx.payerID
				)))

		#Clean up route time-out:
		ret.append(messages.FilterTimeouts(function = lambda message: not (
			isinstance(message, messages.NodeStateTimeout_Route)
			and
			message.transactionID == msg.transactionID
			and
			message.isPayerSide == msg.isPayerSide
			and
			message.payerID == tx.payerID
			)))

		return ret
Пример #2
0
    def requestCommitOutgoing(self, msg):
        if self.state != self.states.locked:
            raise Exception(
             "requestCommitOutgoing should not be called in state %s" % \
              self.state
             )
        self.state = self.states.receivedRequestCommit
        self.token = msg.token  #TODO: maybe check?

        return \
        [
        messages.TimeoutMessage(timestamp=time.time()+1.0, message=\
         self.getTimeoutMessage()  #Add time-out to go to commit
        )
        ]
Пример #3
0
	def msg_makePayer(self, msg):
		if not (self.payerLink is None):
			raise Exception("There already is a payment in progress")
		self.payerLink = payerlink.PayerLink(
			payeeLinkID=msg.payeeLinkID,
			routingContext=msg.routingContext)

		self.connections[messages.payerLocalID] = \
			persistentconnection.PersistentConnection(
				host=msg.host,
				port=msg.port,
				connectMessage=messages.Pay(ID=msg.payeeLinkID)
				)

		#Returned messages:
		return [
			messages.TimeoutMessage(timestamp=time.time()+5.0, message=\
				self.payerLink.getTimeoutMessage()  #Add time-out for payer
			)
			]
Пример #4
0
	def lockOutgoing(self, msg):
		routeID = self.__makeRouteID(msg.transactionID, msg.isPayerSide)
		c, ci = self.__findChannelWithRoute(routeID)
		c.lockOutgoing(routeID)

		commitTimeout = c.getOutgoingCommitTimeout(routeID)

		#TODO: add payload
		msg = copy.deepcopy(msg)
		msg.ID = self.remoteID
		msg.channelIndex = ci
		return \
		[
			messages.OutboundMessage(localID=self.localID, message=msg),
			messages.TimeoutMessage(
				timestamp=commitTimeout,
				message=messages.LinkTimeout_Commit(
					transactionID=msg.transactionID,
					isPayerSide=msg.isPayerSide,
					ID=self.localID
					))
		]
Пример #5
0
	def msg_haveNoRoute(self, msg):
		log.log('Processing HaveNoRoute message')
		try:
			if msg.isPayerSide:
				tx = self.findTransaction(
					transactionID=msg.transactionID, payeeID=msg.ID, isPayerSide=True)
			else:
				tx = self.findTransaction(
					transactionID=msg.transactionID, payerID=msg.ID, isPayerSide=False)
		except TransactionNotFound:
			log.log('  HaveNoRoute failed: transaction %s does not (or no longer) exist (ignored)' % \
				msg.transactionID.encode('hex'))
			return []

		payer = self.__getLinkObject(tx.payerID)
		payee = self.__getLinkObject(tx.payeeID)

		ret = []

		if tx.isPayerSide:
			ret += payee.haveNoRouteIncoming(msg)
		else:
			ret += payer.haveNoRouteIncoming(msg)

		#Clean up old route and lock time-out:
		oldPayerID = tx.payerID #keep reference to innermost object
		ret.append(messages.FilterTimeouts(function = lambda message: not (
			isinstance(message, (messages.NodeStateTimeout_Route, messages.NodeStateTimeout_Lock))
			and
			message.transactionID == msg.transactionID
			and
			message.isPayerSide == msg.isPayerSide
			and
			message.payerID == oldPayerID
			)))

		#Try to find another route
		nextRoute = tx.tryNextRoute()
		if nextRoute is None:
			log.log('  No remaining route found')

			if tx.isPayerSide:
				ret += payer.haveNoRouteOutgoing(msg.transactionID, isPayerSide=True)
			else:
				ret += payee.haveNoRouteOutgoing(msg.transactionID, isPayerSide=False)

			#Clean up cancelled transaction:
			self.transactions.remove(tx)

			return ret

		log.log('  Forwarding MakeRoute to the next route')

		ret += self.__getLinkObject(nextRoute).makeRouteOutgoing(
			messages.MakeRoute(
				amount         = tx.amount,
				transactionID  = msg.transactionID,
				startTime      = tx.startTime,
				endTime        = tx.endTime,
				meetingPointID = tx.meetingPointID,
				ID             = nextRoute,
				isPayerSide    = tx.isPayerSide
				))

		#route time-out:
		#TODO: configurable time-out value?
		ret.append(messages.TimeoutMessage(timestamp=time.time()+5.0, message=\
			messages.NodeStateTimeout_Route(
				transactionID=msg.transactionID, isPayerSide=msg.isPayerSide,
				payerID=tx.payerID
				)))

		return ret
Пример #6
0
	def msg_makeRoute(self, msg):
		log.log('Processing MakeRoute message')

		sourceLink = self.__getLinkObject(msg.ID)
		ret = sourceLink.makeRouteIncoming(msg)

		payerID, payeeID = \
		{
		True: (msg.ID, None),
		False: (None, msg.ID)
		}[msg.isPayerSide]

		#Possible routes we can take
		if msg.routingContext is None:
			#Order is important: try meeting points first
			possibleLinks = self.meetingPoints.keys() + self.links.keys()
		else:
			possibleLinks = [msg.routingContext]

		def tryRemove(ID):
			try:
				possibleLinks.remove(ID)
			except ValueError:
				pass #it's OK if the source link wasn't present already
			
		#Remove the source link:
		tryRemove(msg.ID)

		#Remove source link and possible routes of earlier instances of
		#this route:
		#for these, the route should be made by the earlier instance.
		#Allowing them to be selected by later instances would allow
		#infinite routing loops.
		#Note: generally, this will remove ALL routes, if earlier instances of
		#the same route exist. The only situation where this is not the case
		#is when an earlier instance was restricted in its routing choices,
		#and, theoretically, when a new route was created in-between.
		earlierTransactions = self.findMultipleTransactions(
			transactionID=msg.transactionID, isPayerSide=msg.isPayerSide)
		for earlierTx in earlierTransactions:
			earlierSourceLinkID = earlierTx.payerID if msg.isPayerSide else earlierTx.payeeID
			tryRemove(earlierSourceLinkID)

			for ID in earlierTx.initialLinkIDs:
				tryRemove(ID)

		#Increment end time on the payee side:
		#On the payer side, this will be done in haveRoute.
		if not msg.isPayerSide:
			#TODO: check sanity (and data type) of startTime, endTime
			msg.endTime += self.settings.timeoutIncrement

		#Create new transaction
		newTx = transaction.Transaction(
			state=transaction.Transaction.states.makingRoute,
			isPayerSide=msg.isPayerSide,
			payeeID=payeeID,
			payerID=payerID,

			initialLinkIDs=possibleLinks[:],
			remainingLinkIDs=possibleLinks[:],

			meetingPointID=msg.meetingPointID,
			amount=msg.amount,

			transactionID=msg.transactionID,
			startTime=msg.startTime,
			endTime=msg.endTime
			)
		self.transactions.append(newTx)

		nextRoute = newTx.tryNextRoute()
		if nextRoute is None:
			log.log('  No route found')
			#Delete the tx we just created:
			self.transactions.remove(newTx)
			#Send back haveNoRoute:
			ret += sourceLink.haveNoRouteOutgoing(
				msg.transactionID, msg.isPayerSide)
			return ret

		log.log('  Forwarding MakeRoute to the first route')

		ret += self.__getLinkObject(nextRoute).makeRouteOutgoing(msg)

		#route time-out:
		#TODO: configurable time-out value?
		ret.append(messages.TimeoutMessage(timestamp=time.time()+5.0, message=\
			messages.NodeStateTimeout_Route(
				transactionID=msg.transactionID, isPayerSide=msg.isPayerSide,
				payerID=newTx.payerID
				)))

		return ret