Esempio n. 1
0
class MerchantWalletManager(object):
    def __init__(self, walletMessageType, entity):

        # isMessageType, dsdbMessageType, amount):
        self.walletMessageType = walletMessageType
        self.entity = entity

        #self.isMessageType = isMessageType
        #self.dsdbMessageType = dsdbMessageType
        if not self.walletMessageType.globals.status.can(
                MessageStatuses.PrivilegeServer):
            raise MessageError(
                'given messageType does not have PrivilegeServer')

        class messages:
            pass

        self.walletMessages = messages()
        self.isMessages = messages()
        self.dsdbMessages = messages()
        del messages

        # All the responses we can get from the IS (we are client)
        #self.isMessages.MKP = MintingKeyPass(self.resumeConversation) # this are being handled elsewhere (BlankAndMintingKey)
        #self.isMessages.MKF = MintingKeyFailure(self.resumeConversation) # this is being handled elsewhere (BlankAndMintingKey)
        self.isMessages.MA = MintAccept(self.resumeConversation)
        self.isMessages.MR = MintReject(self.resumeConversation)
        self.isMessages.FMF = FetchMintedFailure(self.resumeConversation)
        self.isMessages.FMW = FetchMintedWait(self.resumeConversation)
        self.isMessages.FMA = FetchMintedAccept(self.resumeConversation)
        self.isMessages.RCR = RedeemCoinsReject(self.resumeConversation)
        self.isMessages.RCA = RedeemCoinsAccept(self.resumeConversation)

        # All messages can get from the other wallet (we are server)
        self.walletMessages.CR = CoinsRedeem(self.resumeConversation)
        self.walletMessages.BP = BlankPresent(self.resumeConversation)

        # All the responses we can get from the DSDB
        self.dsdbMessages.LCA = LockCoinsAccept(self.resumeConversation)
        self.dsdbMessages.LCF = LockCoinsFailure(self.resumeConversation)
        self.dsdbMessages.UCP = UnlockCoinsPass(self.resumeConversation)
        self.dsdbMessages.UCF = UnlockCoinsFailure(self.resumeConversation)

        # Add handlers for all the messages using walletMessages if starts conversation
        self.walletMessageType.addMessageHandler(self.walletMessages.BP)
        self.walletMessageType.addMessageHandler(BlankReject())
        self.walletMessageType.addMessageHandler(BlankFailure())
        self.walletMessageType.addMessageHandler(BlankAccept())
        self.walletMessageType.addMessageHandler(self.walletMessages.CR)
        self.walletMessageType.addMessageHandler(CoinsReject())
        self.walletMessageType.addMessageHandler(CoinsAccept())

        class state:
            __slots__ = (
                'blanks',  # the blanks given in BlankPresent
                'dsdb_certificate',  # the dsdb certificate given in BlankPresent
                'mintBlanks',  # blanks we created for use with a MintRequest (to make new coins)
                'dsdb_lock',  # the lock we receive when we perform a LockRequest
                'coins',  # the coins received from the other wallet with a CoinsRedeem
                'mintingKeysKeyID',  # the minting key certificates for all coins received
                'mintingKeysDenomination',  # the minting key certificates for all denominations of all coins received
                'mintRequestID',  # the request id generated for the MintRequest
                'target',  # the target for the MintRequest
                'signatures',  # the signatures returned from IS via FetchMintedRequest
                'newCoins',  # our newly minted coins after
                'mintingFailures'  # any coins where the signature was invalid. Nothing we can really do with this though.
            )

        self.persistant = state()
        del state

        self.lastMessageIdentifier = None

    # an explaination of how this class treats the exchange. We first wait for a BlankPresent from the wallet. We look at the issuer and
    # let the client decide if he wants to accept.
    # if he does, we make matching blanks and depending on the issuer, MintRequest now (may do after RedeemCoins.
    # we verify the blanks against the DSDB and then BlankAccept. We get the CoinsRedeem, test them, then CoinsAccept.
    # now we RedeemCoinsRequest, and potentially MintRequest at this point. Finally, we FetchMintedRequest to get the new coins. Done. Whew!

    # More information. If isRequiresMRbeforeRCR is true, the chain when the wallet accepts the coins goes:
    #   MINT_REQUEST -> (MINT_ACCEPT) -> REDEEM_COINS_REQUEST -> (REDEEM_COINS_ACCEPT) -> FETCH_MINTED_REQUEST -> (FETCH_MINTED_ACCEPT)
    # If isRequiresMRbeforeRCR is false, the chain when the wallet sends the COINS_REQUEST goes:
    #   REDEEM_COINS_REQUEST -> (REDEEM_COINS_ACCEPT) -> MINT_REQUEST -> (MINT_ACCEPT) -> FETCH_MINTED_REQUEST -> (FETCH_MINTED_ACCEPT

    def resumeConversation(self, message, result):
        if isinstance(message, BlankPresent):
            self.setHandler(BlankAndMintingKey(
                self, message))  # First we receive the blanks
        elif isinstance(message, MintAccept) or isinstance(
                message, MintReject):
            self.setHandler(Mint(
                self, message))  # Then we (may) try to mint our own blanks
        elif isinstance(message, LockCoinsFailure) or isinstance(
                message, LockCoinsAccept):
            self.setHandler(LockCoins(
                self, message))  # We also have to try to lock the coins...
        elif isinstance(message, CoinsRedeem):
            self.setHandler(
                Coins(self, message)
            )  # We locked the coins, and they are valid. We sent a BlankAccept. Next we get told to redeem them
        elif isinstance(message, RedeemCoinsReject) or isinstance(
                message, RedeemCoinsAccept):
            self.setHandler(
                RedeemCoins(self, message)
            )  # Now we redeem them (note: the next step may be to try to mint them...)
        elif isinstance(message, FetchMintedWait) or isinstance(
                message, FetchMintedFailure) or isinstance(
                    message, FetchMintedAccept):
            self.setHandler(FetchMinted(
                self, message))  # And finally, get the coins.
        elif isinstance(message, UnlockCoinsPass) or isinstance(
                message, UnlockCoinsFailure):
            self.setHandler(UnlockCoins(
                self, message))  # If we erred, we unlock to be nice
        else:
            raise MessageError('Message %s does not continue a conversation' %
                               message.identifier)

    def setHandler(self, handler):
        self.handler = handler

    def connectToDSDB(self, dsdb_certificate):
        """sets up the dsdbMessageType and links the callbacks."""
        client = MessageStatuses.getBaseClient()
        self.dsdbMessageType = MessageType(client)

        # Add handlers for all the messages using dsdbMessages if it continues conversation
        self.dsdbMessageType.addMessageHandler(LockCoinsRequest())
        self.dsdbMessageType.addMessageHandler(self.dsdbMessages.LCF)
        self.dsdbMessageType.addMessageHandler(self.dsdbMessages.LCA)
        self.dsdbMessageType.addMessageHandler(UnlockCoinsRequest())
        self.dsdbMessageType.addMessageHandler(self.dsdbMessages.UCF)
        self.dsdbMessageType.addMessageHandler(self.dsdbMessages.UCP)

        self.entity.connectToDSDB(self.dsdbMessageType, dsdb_certificate)

    def connectToIS(self, currency_description_document):
        """sets up the isMessageType and links the callbacks."""
        client = MessageStatuses.getBaseClient()
        self.isMessageType = MessageType(client)

        # Add handlers for all the messages using isMessages if it continues the conversation
        self.isMessageType.addMessageHandler(MintingKeyFetchKeyID())
        self.isMessageType.addMessageHandler(MintingKeyFetchDenomination())
        #self.isMessageType.addMessageHandler(self.isMessages.MKP)
        #self.isMessageType.addMessageHandler(self.isMessages.MKF)
        self.isMessageType.addMessageHandler(
            MintingKeyPass()
        )  # These normally would continue, but are folded into BlankAndMintingKey
        self.isMessageType.addMessageHandler(
            MintingKeyFailure()
        )  # These normally would continue, but are folded into BlankAndMintingKey
        self.isMessageType.addMessageHandler(MintRequest())
        self.isMessageType.addMessageHandler(self.isMessages.MA)
        self.isMessageType.addMessageHandler(self.isMessages.MR)
        self.isMessageType.addMessageHandler(FetchMintedRequest())
        self.isMessageType.addMessageHandler(self.isMessages.FMF)
        self.isMessageType.addMessageHandler(self.isMessages.FMW)
        self.isMessageType.addMessageHandler(self.isMessages.FMA)
        self.isMessageType.addMessageHandler(RedeemCoinsRequest())
        self.isMessageType.addMessageHandler(self.isMessages.RCR)
        self.isMessageType.addMessageHandler(self.isMessages.RCA)

        self.entity.connectToIS(self.isMessageType,
                                currency_description_document)

    def success(self, message, handler):
        print 'Received a success! Message class: %s. Handler class: %s' % (
            message.__class__, handler.__class__)

    def failure(self, message, handler):
        print 'Receive a failure. :( Message %s Sentence: %s' % (
            message.identifier, message.sentence)
        print 'We should do something like un-hook ourselves or something.'

    def waitForFetchMint(self, message, handler):
        print 'We were told to wait on our FetchMintedRequest. Reason: %s' % message.messageLayer.globals.reason
class ConsumerWalletManager(object):
    def __init__(self, walletMessageType, entity, coins):
        self.walletMessageType = walletMessageType
        self.entity = entity

        #self.isMessageType = isMessageType
        if not self.walletMessageType.globals.status.can(
                MessageStatuses.PrivilegeClient):
            raise MessageError(
                'given messageType does not have PrivilegeClient')

        class messages:
            pass

        self.walletMessages = messages()
        self.isMessages = messages()
        del messages

        # All the responses we can get from the IS
        self.isMessages.DKP = DSDBKeyPass(self.resumeConversation)

        # All the responses we can get from the other wallet
        self.walletMessages.BR = BlankReject(self.resumeConversation)
        self.walletMessages.BF = BlankFailure(self.resumeConversation)
        self.walletMessages.BA = BlankAccept(self.resumeConversation)
        self.walletMessages.CR = CoinsReject(self.resumeConversation)
        self.walletMessages.CA = CoinsAccept(self.resumeConversation)

        # Add handlers for all the messages using walletMessages if continues conversation
        self.walletMessageType.addMessageHandler(BlankPresent())
        self.walletMessageType.addMessageHandler(self.walletMessages.BR)
        self.walletMessageType.addMessageHandler(self.walletMessages.BF)
        self.walletMessageType.addMessageHandler(self.walletMessages.BA)
        self.walletMessageType.addMessageHandler(CoinsRedeem())
        self.walletMessageType.addMessageHandler(self.walletMessages.CR)
        self.walletMessageType.addMessageHandler(self.walletMessages.CA)

        self.coins = coins

        class state:
            pass

        self.persistant = state()
        del state

        self.lastMessageIdentifier = None

    def resumeConversation(self, message, result):
        if isinstance(message, DSDBKeyPass):
            self.setHandler(DSDBKey(self, message))
        elif isinstance(message, BlankReject) or isinstance(
                message, BlankFailure) or isinstance(message, BlankAccept):
            self.setHandler(Blank(self, message))
        elif isinstance(message, CoinsReject) or isinstance(
                message, CoinsAccept):
            self.setHandler(Coins(self, message))

        else:
            raise MessageError('Message %s does not continue a conversation' %
                               message.identifier)

    def setHandler(self, handler):
        self.handler = handler

    def startConversation(self):
        #this is kind of a hack. Okay. A lot of a hack
        self.connectToIS(self.entity.cdds[self.coins[0].currency_identifier])

        dkr = DSDBKeyRequest()
        self.isMessageType.addOutput(
            dkr)  # and so it starts. Flow follows to DSDBKey

    def success(self, message, handler):
        print 'Received a success! Message class: %s. Handler class: %s' % (
            message.__class__, handler.__class__)

    def failure(self, message, handler):
        print 'Received a failure. Message %s Sentence: %s' % (
            message.identifier, message.sentence)
        print 'We should do something like un-hook ourselves or something.'

    def connectToIS(self, currency_description_document):
        """sets up the isMessageType and links the callbacks."""
        client = MessageStatuses.getBaseClient()
        self.isMessageType = MessageType(client)

        # Add handlers for all the messages, using isMessages if continues conversation
        self.isMessageType.addMessageHandler(DSDBKeyRequest())
        self.isMessageType.addMessageHandler(self.isMessages.DKP)

        self.entity.connectToIS(self.isMessageType,
                                currency_description_document)

        #FIXME: This is one of many places we enforce the one currency at a time
        self.cdd = currency_description_document
class MerchantWalletManager(object):
    def __init__(self, walletMessageType, entity):
        
        # isMessageType, dsdbMessageType, amount):
        self.walletMessageType = walletMessageType
        self.entity = entity

        #self.isMessageType = isMessageType
        #self.dsdbMessageType = dsdbMessageType
        if not self.walletMessageType.globals.status.can(MessageStatuses.PrivilegeServer):
            raise MessageError('given messageType does not have PrivilegeServer')

        class messages: pass
        self.walletMessages = messages()
        self.isMessages = messages()
        self.dsdbMessages = messages()
        del messages

        # All the responses we can get from the IS (we are client)
        #self.isMessages.MKP = MintingKeyPass(self.resumeConversation) # this are being handled elsewhere (BlankAndMintingKey)
        #self.isMessages.MKF = MintingKeyFailure(self.resumeConversation) # this is being handled elsewhere (BlankAndMintingKey)
        self.isMessages.MA = MintAccept(self.resumeConversation)
        self.isMessages.MR = MintReject(self.resumeConversation)
        self.isMessages.FMF = FetchMintedFailure(self.resumeConversation)
        self.isMessages.FMW = FetchMintedWait(self.resumeConversation)
        self.isMessages.FMA = FetchMintedAccept(self.resumeConversation)
        self.isMessages.RCR = RedeemCoinsReject(self.resumeConversation)
        self.isMessages.RCA = RedeemCoinsAccept(self.resumeConversation)

        # All messages can get from the other wallet (we are server)
        self.walletMessages.CR = CoinsRedeem(self.resumeConversation)
        self.walletMessages.BP = BlankPresent(self.resumeConversation)
        
        # All the responses we can get from the DSDB
        self.dsdbMessages.LCA = LockCoinsAccept(self.resumeConversation)
        self.dsdbMessages.LCF = LockCoinsFailure(self.resumeConversation)
        self.dsdbMessages.UCP = UnlockCoinsPass(self.resumeConversation)
        self.dsdbMessages.UCF = UnlockCoinsFailure(self.resumeConversation)

        # Add handlers for all the messages using walletMessages if starts conversation
        self.walletMessageType.addMessageHandler(self.walletMessages.BP)
        self.walletMessageType.addMessageHandler(BlankReject())
        self.walletMessageType.addMessageHandler(BlankFailure())
        self.walletMessageType.addMessageHandler(BlankAccept())
        self.walletMessageType.addMessageHandler(self.walletMessages.CR)
        self.walletMessageType.addMessageHandler(CoinsReject())
        self.walletMessageType.addMessageHandler(CoinsAccept())

        class state:
            __slots__ = ('blanks', # the blanks given in BlankPresent
                         'dsdb_certificate', # the dsdb certificate given in BlankPresent
                         'mintBlanks', # blanks we created for use with a MintRequest (to make new coins)
                         'dsdb_lock', # the lock we receive when we perform a LockRequest
                         'coins', # the coins received from the other wallet with a CoinsRedeem
                         'mintingKeysKeyID', # the minting key certificates for all coins received
                         'mintingKeysDenomination', # the minting key certificates for all denominations of all coins received
                         'mintRequestID', # the request id generated for the MintRequest
                         'target', # the target for the MintRequest
                         'signatures', # the signatures returned from IS via FetchMintedRequest
                         'newCoins', # our newly minted coins after
                         'mintingFailures' # any coins where the signature was invalid. Nothing we can really do with this though.
                         )
        self.persistant = state()
        del state

        self.lastMessageIdentifier = None


    # an explaination of how this class treats the exchange. We first wait for a BlankPresent from the wallet. We look at the issuer and 
    # let the client decide if he wants to accept.
    # if he does, we make matching blanks and depending on the issuer, MintRequest now (may do after RedeemCoins.
    # we verify the blanks against the DSDB and then BlankAccept. We get the CoinsRedeem, test them, then CoinsAccept.
    # now we RedeemCoinsRequest, and potentially MintRequest at this point. Finally, we FetchMintedRequest to get the new coins. Done. Whew!

    # More information. If isRequiresMRbeforeRCR is true, the chain when the wallet accepts the coins goes:
    #   MINT_REQUEST -> (MINT_ACCEPT) -> REDEEM_COINS_REQUEST -> (REDEEM_COINS_ACCEPT) -> FETCH_MINTED_REQUEST -> (FETCH_MINTED_ACCEPT)
    # If isRequiresMRbeforeRCR is false, the chain when the wallet sends the COINS_REQUEST goes:
    #   REDEEM_COINS_REQUEST -> (REDEEM_COINS_ACCEPT) -> MINT_REQUEST -> (MINT_ACCEPT) -> FETCH_MINTED_REQUEST -> (FETCH_MINTED_ACCEPT

    
    def resumeConversation(self, message, result):
        if isinstance(message, BlankPresent):
            self.setHandler(BlankAndMintingKey(self, message)) # First we receive the blanks
        elif isinstance(message, MintAccept) or isinstance(message, MintReject):
            self.setHandler(Mint(self, message)) # Then we (may) try to mint our own blanks
        elif isinstance(message, LockCoinsFailure) or isinstance(message, LockCoinsAccept):
            self.setHandler(LockCoins(self, message)) # We also have to try to lock the coins...
        elif isinstance(message, CoinsRedeem):
            self.setHandler(Coins(self, message)) # We locked the coins, and they are valid. We sent a BlankAccept. Next we get told to redeem them
        elif isinstance(message, RedeemCoinsReject) or isinstance(message, RedeemCoinsAccept):
            self.setHandler(RedeemCoins(self, message)) # Now we redeem them (note: the next step may be to try to mint them...)
        elif isinstance(message, FetchMintedWait) or isinstance(message, FetchMintedFailure) or isinstance(message, FetchMintedAccept):
            self.setHandler(FetchMinted(self, message)) # And finally, get the coins.
        elif isinstance(message, UnlockCoinsPass) or isinstance(message, UnlockCoinsFailure):
            self.setHandler(UnlockCoins(self, message)) # If we erred, we unlock to be nice
        else:
            raise MessageError('Message %s does not continue a conversation' % message.identifier)

    def setHandler(self, handler):
        self.handler = handler

    def connectToDSDB(self, dsdb_certificate):
        """sets up the dsdbMessageType and links the callbacks."""
        client = MessageStatuses.getBaseClient()
        self.dsdbMessageType = MessageType(client)

        # Add handlers for all the messages using dsdbMessages if it continues conversation
        self.dsdbMessageType.addMessageHandler(LockCoinsRequest())
        self.dsdbMessageType.addMessageHandler(self.dsdbMessages.LCF)
        self.dsdbMessageType.addMessageHandler(self.dsdbMessages.LCA)
        self.dsdbMessageType.addMessageHandler(UnlockCoinsRequest())
        self.dsdbMessageType.addMessageHandler(self.dsdbMessages.UCF)
        self.dsdbMessageType.addMessageHandler(self.dsdbMessages.UCP)        

        self.entity.connectToDSDB(self.dsdbMessageType, dsdb_certificate)

    def connectToIS(self, currency_description_document):
        """sets up the isMessageType and links the callbacks."""
        client = MessageStatuses.getBaseClient()
        self.isMessageType = MessageType(client)

        # Add handlers for all the messages using isMessages if it continues the conversation
        self.isMessageType.addMessageHandler(MintingKeyFetchKeyID())
        self.isMessageType.addMessageHandler(MintingKeyFetchDenomination())
        #self.isMessageType.addMessageHandler(self.isMessages.MKP)
        #self.isMessageType.addMessageHandler(self.isMessages.MKF)
        self.isMessageType.addMessageHandler(MintingKeyPass()) # These normally would continue, but are folded into BlankAndMintingKey
        self.isMessageType.addMessageHandler(MintingKeyFailure()) # These normally would continue, but are folded into BlankAndMintingKey
        self.isMessageType.addMessageHandler(MintRequest())
        self.isMessageType.addMessageHandler(self.isMessages.MA)
        self.isMessageType.addMessageHandler(self.isMessages.MR)
        self.isMessageType.addMessageHandler(FetchMintedRequest())
        self.isMessageType.addMessageHandler(self.isMessages.FMF)
        self.isMessageType.addMessageHandler(self.isMessages.FMW)
        self.isMessageType.addMessageHandler(self.isMessages.FMA)
        self.isMessageType.addMessageHandler(RedeemCoinsRequest())
        self.isMessageType.addMessageHandler(self.isMessages.RCR)
        self.isMessageType.addMessageHandler(self.isMessages.RCA)
    
        self.entity.connectToIS(self.isMessageType, currency_description_document)

    def success(self, message, handler):
        print 'Received a success! Message class: %s. Handler class: %s' % (message.__class__, handler.__class__)

    def failure(self, message, handler):
        print 'Receive a failure. :( Message %s Sentence: %s' % (message.identifier, message.sentence)
        print 'We should do something like un-hook ourselves or something.'

    def waitForFetchMint(self, message, handler):
        print 'We were told to wait on our FetchMintedRequest. Reason: %s' % message.messageLayer.globals.reason
class ConsumerWalletManager(object):
    def __init__(self, walletMessageType, entity, coins):
        self.walletMessageType = walletMessageType
        self.entity = entity

        #self.isMessageType = isMessageType
        if not self.walletMessageType.globals.status.can(MessageStatuses.PrivilegeClient):
            raise MessageError('given messageType does not have PrivilegeClient')
        

        class messages: pass
        self.walletMessages = messages()
        self.isMessages = messages()
        del messages

        # All the responses we can get from the IS
        self.isMessages.DKP = DSDBKeyPass(self.resumeConversation)

        # All the responses we can get from the other wallet
        self.walletMessages.BR = BlankReject(self.resumeConversation)
        self.walletMessages.BF = BlankFailure(self.resumeConversation)
        self.walletMessages.BA = BlankAccept(self.resumeConversation)
        self.walletMessages.CR = CoinsReject(self.resumeConversation)
        self.walletMessages.CA = CoinsAccept(self.resumeConversation)

        # Add handlers for all the messages using walletMessages if continues conversation
        self.walletMessageType.addMessageHandler(BlankPresent())
        self.walletMessageType.addMessageHandler(self.walletMessages.BR)
        self.walletMessageType.addMessageHandler(self.walletMessages.BF)
        self.walletMessageType.addMessageHandler(self.walletMessages.BA)
        self.walletMessageType.addMessageHandler(CoinsRedeem())
        self.walletMessageType.addMessageHandler(self.walletMessages.CR)
        self.walletMessageType.addMessageHandler(self.walletMessages.CA)

        self.coins = coins

        class state: pass
        self.persistant = state()
        del state

        self.lastMessageIdentifier = None

    def resumeConversation(self, message, result):
        if isinstance(message, DSDBKeyPass):
            self.setHandler(DSDBKey(self, message))
        elif isinstance(message, BlankReject) or isinstance(message, BlankFailure) or isinstance(message, BlankAccept):
            self.setHandler(Blank(self, message))
        elif isinstance(message, CoinsReject) or isinstance(message, CoinsAccept):
            self.setHandler(Coins(self, message))

        else:
            raise MessageError('Message %s does not continue a conversation' % message.identifier)

    def setHandler(self, handler):
        self.handler = handler

    def startConversation(self):
        #this is kind of a hack. Okay. A lot of a hack
        self.connectToIS(self.entity.cdds[self.coins[0].currency_identifier])

        dkr = DSDBKeyRequest()
        self.isMessageType.addOutput(dkr) # and so it starts. Flow follows to DSDBKey

    def success(self, message, handler):
        print 'Received a success! Message class: %s. Handler class: %s' % (message.__class__, handler.__class__)

    def failure(self, message, handler):
        print 'Received a failure. Message %s Sentence: %s' % (message.identifier, message.sentence)
        print 'We should do something like un-hook ourselves or something.'

    def connectToIS(self, currency_description_document):
        """sets up the isMessageType and links the callbacks."""
        client = MessageStatuses.getBaseClient()
        self.isMessageType = MessageType(client)
        
        # Add handlers for all the messages, using isMessages if continues conversation
        self.isMessageType.addMessageHandler(DSDBKeyRequest())
        self.isMessageType.addMessageHandler(self.isMessages.DKP)

        self.entity.connectToIS(self.isMessageType, currency_description_document)

        #FIXME: This is one of many places we enforce the one currency at a time
        self.cdd = currency_description_document