Exemple #1
0
	def makeRouteOutgoing(self, msg):
		routeID = self.__makeRouteID(msg.transactionID, msg.isPayerSide)
		isOutgoing = msg.isPayerSide

		#Try the channels one by one:
		for i, c in enumerate(self.channels):

			#Reserve funds in channel.
			try:
				c.reserve(isOutgoing, routeID, msg.startTime, msg.endTime, msg.amount)
			except Exception as e:
				#TODO: make sure the state of the channel is restored?
				log.log("Reserving on channel %d failed: returned exception \"%s\"" % (i, str(e)))
				continue

			log.log("Reserving on channel %d succeeded" % i)

			msg = copy.deepcopy(msg)
			msg.ID = self.remoteID
			msg.channelIndex = i

			return \
			[
			messages.OutboundMessage(localID=self.localID, message=msg)
			]

		#None of the channels worked (or there are no channels):
		#TODO: haveNoRoute
		return []
Exemple #2
0
	def settleCommitOutgoing(self, msg):
		transactionID = settings.hashAlgorithm(msg.token)
		routeID = self.__makeRouteID(transactionID, msg.isPayerSide)
		try:
			c, ci = self.__findChannelWithRoute(routeID)
		except RouteNotInChannelsException:
			log.log('No channel found for route; assuming settleCommitOutgoing was already performed, so we skip it.')
			return []

		ret = self.handleChannelOutput(
			ci,
			c.settleCommitOutgoing(routeID, msg.token)
			)

		#TODO: add payload
		msg = copy.deepcopy(msg)
		msg.ID = self.remoteID
		return ret + \
		[
			messages.OutboundMessage(localID=self.localID, message=msg),
			messages.FilterTimeouts(function = lambda message: \
				not(
					isinstance(message, messages.LinkTimeout_Commit)
					and
					message.transactionID == transactionID
					and
					message.isPayerSide == msg.isPayerSide
					and
					message.ID == self.localID
				))
		]
Exemple #3
0
 def haveRouteOutgoing(self, msg):
     #Simply pass it to the payer, who keeps track of whether the route is complete
     return \
     [
     messages.OutboundMessage(localID = msg.ID, message = \
      messages.HaveRoute(transactionID=None, isPayerSide=False)
      )
     ]
Exemple #4
0
    def haveNoRouteOutgoing(self, transactionID, isPayerSide):
        self.state = self.states.cancelled

        return self.__removeTimeouts() + \
        [
        messages.OutboundMessage(localID = messages.payerLocalID, message = \
         messages.Cancel()
        ),
        messages.SetEvent(event=messages.SetEvent.events.paymentFinished)
        ]
Exemple #5
0
    def msg_confirm(self, msg):
        log.log("PayerLink: Received confirm: %s" % str(msg.agreement))

        if self.state != self.states.hasReceipt:
            raise Exception(
             "msg_confirm should not be called in state %s" % \
              self.state
             )

        ret = []

        if msg.agreement:
            self.state = self.states.confirmed

            ret = \
            [
            messages.OutboundMessage(localID = messages.payerLocalID, message = \
             messages.Confirm(meetingPointID=self.meetingPointID)
            ),
            messages.MakeRoute( #This will start the transaction routing
             ID=messages.payerLocalID,
             routingContext=self.routingContext,
             amount=self.amount,
             transactionID=self.transactionID,
             startTime=None, #Will be received from the payee side
             endTime=None, #Will be received from the payee side
             meetingPointID=self.meetingPointID,
             isPayerSide=True
             )
            ]

        else:
            self.state = self.states.cancelled

            ret = self.__removeTimeouts() + \
            [
            messages.OutboundMessage(localID = messages.payerLocalID, message = \
             messages.Cancel()
            ),
            messages.SetEvent(event=messages.SetEvent.events.paymentFinished)
            ]

        return ret
Exemple #6
0
	def haveRouteOutgoing(self, msg):
		routeID = self.__makeRouteID(msg.transactionID, msg.isPayerSide)
		isOutgoing = not msg.isPayerSide

		c, ci = self.__findChannelWithRoute(routeID)
		c.updateReservation(isOutgoing, routeID, msg.startTime, msg.endTime)

		#Forward to peer:
		msg = copy.deepcopy(msg)
		msg.ID = self.remoteID
		return [messages.OutboundMessage(localID=self.localID, message=msg)]
Exemple #7
0
    def lockOutgoing(self, msg):
        log.log("Payee: locked; committing")

        self.state = self.states.sentRequestCommit

        return \
        [
        messages.RequestCommit(ID=self.ID, token=self.token, isPayerSide=False),
        messages.OutboundMessage(localID = self.ID, message = \
         messages.SettleCommit(token=self.token)
         )
        ]
Exemple #8
0
	def cancelOutgoing(self, msg):
		routeID = self.__makeRouteID(msg.transactionID, msg.isPayerSide)
		isOutgoing = msg.isPayerSide

		c, ci = self.__findChannelWithRoute(routeID)
		ret = self.handleChannelOutput(
			ci,
			c.unreserve(isOutgoing, routeID)
			)

		msg = copy.deepcopy(msg)
		msg.ID = self.remoteID
		return ret + [messages.OutboundMessage(localID=self.localID, message=msg)]
Exemple #9
0
	def settleRollbackOutgoing(self, msg):
		#TODO: process payload
		routeID = self.__makeRouteID(msg.transactionID, msg.isPayerSide)
		c, ci = self.__findChannelWithRoute(routeID)

		ret = self.handleChannelOutput(
			ci,
			c.settleRollbackOutgoing(routeID)
			)

		#TODO: add payload
		msg = copy.deepcopy(msg)
		msg.ID = self.remoteID
		return ret + [messages.OutboundMessage(localID=self.localID, message=msg)]
Exemple #10
0
    def msg_pay(self, msg):
        if self.state != self.states.initial:
            raise Exception(
             "msg_pay should not be called in state %s" % \
              self.state
             )

        return [messages.OutboundMessage(localID = msg.ID, message = \
         messages.Receipt(
          amount=self.amount,
          receipt=self.receipt,
          transactionID=self.transactionID,
          meetingPoints=self.meetingPoints
         ))]
Exemple #11
0
    def haveNoRouteOutgoing(self, transactionID, isPayerSide):
        if self.state != self.states.confirmed:
            raise Exception(
             "haveNoRouteOutgoing should not be called in state %s" % \
              self.state
             )

        self.state = self.states.cancelled

        return \
        [
        messages.OutboundMessage(localID = self.ID, message = \
         messages.Cancel()
         )
        ]
Exemple #12
0
	def haveNoRouteOutgoing(self, transactionID, isPayerSide):
		routeID = self.__makeRouteID(transactionID, isPayerSide)
		isOutgoing = not isPayerSide

		c, ci = self.__findChannelWithRoute(routeID)
		ret = self.handleChannelOutput(
			ci,
			c.unreserve(isOutgoing, routeID)
			)

		return ret + \
		[
		messages.OutboundMessage(localID=self.localID,
			message=messages.HaveNoRoute(
				transactionID=transactionID, isPayerSide=isPayerSide))
		]
Exemple #13
0
    def settleRollbackOutgoing(self, msg):
        if self.state != self.states.locked:
            raise Exception(
             "settleRollbackOutgoing should not be called in state %s" % \
              self.state
             )

        log.log("Payer: received settleRollback -> cancelled")
        self.state = self.states.cancelled

        return self.__removeTimeouts() + \
        [
        messages.OutboundMessage(localID = messages.payerLocalID, message = \
         messages.Cancel()
        ),
        messages.SetEvent(event=messages.SetEvent.events.paymentFinished)
        ]
Exemple #14
0
	def msg_ownDeposit(self, msg):
		if self.remoteID is None:
			raise Exception('Can not deposit into a link whose remote ID is unknown')

		self.channels.append(msg.channel)
		channelIndex = len(self.channels) - 1

		#Allow the channel to start a conversation with the peer,
		#related to the deposit.
		return \
			[
			messages.OutboundMessage(localID=self.localID,
				message=messages.Deposit(
					channelIndex=channelIndex,
					channelClass=str(msg.channel.__class__.__name__)
				))
			] + \
			self.startChannelConversation(channelIndex)
Exemple #15
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
					))
		]
Exemple #16
0
	def handleChannelOutput(self, channelIndex, channelOutput):
		log.log("Channel output: " + str(channelOutput))

		channelMessages, otherMessages = channelOutput

		ret = otherMessages
		for msg in ret:
			if isinstance(msg, messages.BitcoinCommand):
				msg.returnID = self.localID
				msg.returnChannelIndex = channelIndex
			elif isinstance(msg, messages.NodeState_TimeoutRollback):
				msg.ID = self.localID
				msg.isPayerSide, msg.transactionID = \
					self.__decodeRouteID(msg.transactionID)

		ret += \
		[
			messages.OutboundMessage(localID=self.localID,
				message=messages.ChannelMessage(
				channelIndex=channelIndex, message=m))
			for m in channelMessages
		]

		return ret
Exemple #17
0
	def requestCommitOutgoing(self, msg):
		msg = copy.deepcopy(msg)
		msg.ID = self.remoteID
		return [messages.OutboundMessage(localID=self.localID, message=msg)]