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