class AuctionReqProcessorPlugin(HasCliCommands): pluginType = PLUGIN_TYPE_PROCESSING supportsCli = True validTxnTypes = [AUCTION_START, AUCTION_END, PLACE_BID, GET_BAL] STARTING_BALANCE = 1000 grams = [getPipedRegEx(pat) for pat in [ "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>start\s+auction) \s+ (?P<auction_id>[a-zA-Z0-9\-]+) \s*) ", "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>end\s+auction) \s+ (?P<auction_id>[a-zA-Z0-9\-]+) \s*) ", "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>place\s+bid) \s+ (?P<amount>[0-9]+) \s+ on \s+(?P<auction_id>[a-zA-Z0-9\-]+) \s*) ", "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>balance) \s*) " ]] cliActionNames = {'balance', 'start auction', 'end auction', 'place bid'} def __init__(self): self.count = 0 self._cli = None # TODO: NEED SOME WAY TO INTEGRATE PERSISTENCE IN PLUGIN # Balances of all client self.balances = {} # type: Dict[str, int] self.auctions = {} # type: Dict[str, SimpleNamespace] def auctionExists(self, id): return id in self.auctions def auctionLive(self, id): return self.auctionExists(id) and self.auctions[id].status def process(self, request): result = {} frm = request.identifier typ = request.operation.get(TXN_TYPE) data = request.operation.get(DATA) id = isinstance(data, dict) and data.get(ID) if frm not in self.balances: self.balances[frm] = self.STARTING_BALANCE if typ in (AUCTION_START, AUCTION_END, PLACE_BID, GET_BAL): if typ == AUCTION_START: id = data.get(ID) success = not self.auctionExists(id) result = {SUCCESS: success} if success: # self.auctions[id] = Auction(id, frm, 0, None, 1) auction = { ID: id, CREATOR: frm, HIGHEST_BID: 0, HIGHEST_BIDDER: None, STATUS: 1 } self.auctions[id] = SimpleNamespace(**auction) result.update(auction) if typ == AUCTION_END: success = self.auctionExists(id) and frm == self.auctions[id].creator result = {SUCCESS: success} if success: self.auctions[id].status = 0 result.update(self.auctions[id].__dict__) # TODO: Consider sending a message to the winner of the auction if typ == PLACE_BID: amount = data.get(AMOUNT) success = self.balances[frm] >= amount and \ self.auctionLive(id) \ and self.auctions[id].highestBid < amount result = {SUCCESS: success} if success: self._bid(id, frm, amount) result.update(self.auctions[id].__dict__) if typ == GET_BAL: result[SUCCESS] = True result[BALANCE] = self.balances.get(frm, 0) else: print("Unknown transaction type") return result def _bid(self, auctionId, frm, bid): lastBidder = self.auctions[auctionId].highestBidder if lastBidder: self.balances[lastBidder] += self.auctions[auctionId].highestBid self.balances[frm] -= bid self.auctions[auctionId].highestBid = bid self.auctions[auctionId].highestBidder = frm @property def actions(self): return [self._clientAction, ] def _clientAction(self, matchedVars): if matchedVars.get('client') == 'client': client_name = matchedVars.get('client_name') client_action = matchedVars.get('cli_action') auctionId = matchedVars.get('auction_id') if client_action in ("start auction", "end auction"): frm = client_name if not self.cli.clientExists(frm): self.cli.printMsgForUnknownClient() else: txn = { TXN_TYPE: AUCTION_START if client_action == "start auction" else AUCTION_END, DATA: { ID: auctionId } } self.cli.sendMsg(frm, txn) return True elif client_action == "place bid": frm = client_name if not self.cli.clientExists(frm): self.cli.printMsgForUnknownClient() else: amount = int(matchedVars.get('amount')) txn = { TXN_TYPE: PLACE_BID, DATA: { ID: auctionId, AMOUNT: amount } } self.cli.sendMsg(frm, txn) return True elif client_action == "balance": frm = client_name if not self.cli.clientExists(frm): self.cli.printMsgForUnknownClient() else: wallet = self.cli.wallets.get(frm, None) txn = { TXN_TYPE: GET_BAL, TARGET_NYM: wallet.defaultId } self.cli.sendMsg(frm, txn) return True
class BankReqProcessorPlugin(HasCliCommands): pluginType = PLUGIN_TYPE_PROCESSING supportsCli = True validTxnTypes = [CREDIT, GET_BAL, GET_ALL_TXNS] STARTING_BALANCE = 1000 grams = [getPipedRegEx(pat) for pat in [ "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>credit) \s+ (?P<amount>[0-9]+) \s+ to \s+(?P<second_client_name>[a-zA-Z0-9]+) \s*) ", "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>balance) \s*) ", "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) \s+ (?P<cli_action>transactions) \s*)" ]] cliActionNames = {'credit', 'balance', 'transactions'} def __init__(self): self.count = 0 self._cli = None # TODO: NEED SOME WAY TO INTEGRATE PERSISTENCE IN PLUGIN # Balances of all client self.balances = {} # type: Dict[str, int] # Txns of all clients, each txn is a tuple like (from, to, amount) self.txns = [] # type: List[Tuple] def process(self, request): result = {} if request.operation.get(TXN_TYPE) in (CREDIT, GET_BAL, GET_ALL_TXNS): frm = request.identifier if frm not in self.balances: self.balances[frm] = self.STARTING_BALANCE if request.operation.get(TXN_TYPE) == CREDIT: to = request.operation[TARGET_NYM] if to not in self.balances: self.balances[to] = self.STARTING_BALANCE amount = request.operation[DATA][AMOUNT] if amount > self.balances[frm]: result[SUCCESS] = False else: result[SUCCESS] = True self.balances[to] += amount self.balances[frm] -= amount self.txns.append((frm, to, amount)) elif request.operation.get(TXN_TYPE) == GET_BAL: result[SUCCESS] = True result[BALANCE] = self.balances.get(frm, 0) elif request.operation.get(TXN_TYPE) == GET_ALL_TXNS: result[SUCCESS] = True result[ALL_TXNS] = [txn for txn in self.txns if frm in txn] self.count += 1 else: print("Unknown transaction type") return result @property def actions(self): return [self._clientAction, ] def _clientAction(self, matchedVars): if matchedVars.get('client') == 'client': client_name = matchedVars.get('client_name') client_action = matchedVars.get('cli_action') if client_action == "credit": frm = client_name to = matchedVars.get('second_client_name') toWallet = self.cli.wallets.get(to, None) if not self.cli.clientExists(frm) or not self.cli.clientExists(to): self.cli.printMsgForUnknownClient() else: amount = int(matchedVars.get('amount')) txn = { TXN_TYPE: CREDIT, TARGET_NYM: toWallet.defaultId, DATA: { AMOUNT: amount }} self.cli.sendMsg(frm, txn) return True elif client_action == "balance": frm = client_name if not self.cli.clientExists(frm): self.cli.printMsgForUnknownClient() else: wallet = self.cli.wallets.get(frm, None) txn = { TXN_TYPE: GET_BAL, TARGET_NYM: wallet.defaultId } self.cli.sendMsg(frm, txn) return True elif client_action == "transactions": frm = client_name if not self.cli.clientExists(frm): self.cli.printMsgForUnknownClient() else: wallet = self.cli.wallets.get(frm, None) txn = { TXN_TYPE: GET_ALL_TXNS, TARGET_NYM: wallet.defaultId } self.cli.sendMsg(frm, txn) return True
from plenum.cli.constants import CLIENT_GRAMS_CLIENT_COMMAND_REG_EX, relist, \ CLI_CMDS, getPipedRegEx, CLIENT_GRAMS_USE_KEYPAIR_REG_EX CLIENT_GRAMS_CLIENT_WITH_IDENTIFIER_FORMATTED_REG_EX = getPipedRegEx( CLIENT_GRAMS_CLIENT_COMMAND_REG_EX + "\s+ (?P<with_identifier>with\s+identifier) " "\s+ (?P<nym>[a-zA-Z0-9=]+) \s*") \ .format(relist(CLI_CMDS)) CLIENT_GRAMS_CLIENT_ADD_FORMATTED_REG_EX = getPipedRegEx( "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) " "\s+ (?P<cli_action>add) \s+ (?P<role>sponsor|user) " "\s+ (?P<other_client_name>[a-zA-Z0-9]+) \s*)") CLIENT_GRAMS_USE_KEYPAIR_FORMATTED_REG_EX = getPipedRegEx( CLIENT_GRAMS_USE_KEYPAIR_REG_EX) # TODO we can genericize the other TXN types in the same way TXN_NYM = "(\s* (?P<{cmdName}>{cmd}\s+NYM) " \ "\s+ (?P<dest>dest=) \s* (?P<dest_id>[A-Za-z0-9+=/]*)" \ "(\s+ (?P<role_key>role=) \s* (?P<role>TRUSTEE|TGB|SPONSOR|STEWARD|))?" \ "(\s+ (?P<ver_key>verkey=) \s* (?P<new_ver_key>[~A-Za-z0-9+=/]*))?)" SEND_NYM_REG_EX = TXN_NYM.format(cmdName='send_nym', cmd='send') ADD_GENESIS_NYM_REG_EX = TXN_NYM.format(cmdName='add_genesis', cmd='add \s+ genesis \s+ transaction') GET_NYM_REG_EX = "(\s* (?P<send_get_nym>send\s+GET_NYM) " \ "\s+ (?P<dest>dest=)\s*(?P<dest_id>[A-Za-z0-9+=/]*) \s*) "
from plenum.cli.constants import CLIENT_GRAMS_CLIENT_COMMAND_REG_EX, relist, \ CLI_CMDS, getPipedRegEx, CLIENT_GRAMS_USE_KEYPAIR_REG_EX from indy_common.roles import Roles from indy_common.transactions import IndyTransactions CLIENT_GRAMS_CLIENT_WITH_DID_FORMATTED_REG_EX = getPipedRegEx( CLIENT_GRAMS_CLIENT_COMMAND_REG_EX + "\s+ (?P<with_DID>with\s+DID) " "\s+ (?P<nym>[a-zA-Z0-9=]+) \s*") \ .format(relist(CLI_CMDS)) CLIENT_GRAMS_CLIENT_ADD_FORMATTED_REG_EX = getPipedRegEx( "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) " "\s+ (?P<cli_action>add) \s+ (?P<role>{trustAnchor}|user) " "\s+ (?P<other_client_name>[a-zA-Z0-9]+) \s*)".format(trustAnchor=Roles.TRUST_ANCHOR.name)) CLIENT_GRAMS_USE_KEYPAIR_FORMATTED_REG_EX = getPipedRegEx( CLIENT_GRAMS_USE_KEYPAIR_REG_EX) # TODO we can genericize the other TXN types in the same way TXN_NYM = "(\s* (?P<{{cmdName}}>{{cmd}}\s+{nym}) " \ "\s+ (?P<dest>dest=) \s* (?P<dest_id>[A-Za-z0-9+=/]*)" \ "(\s+ (?P<role_key>role=) \s* (?P<role>{trustee}|{tgb}|{trustAnchor}|{steward}|))?" \ "(\s+ (?P<ver_key>verkey=) \s* (?P<new_ver_key>[~A-Za-z0-9+=/]+))?)".format(nym=IndyTransactions.NYM.name, trustee=Roles.TRUSTEE.name, tgb=Roles.TGB.name, trustAnchor=Roles.TRUST_ANCHOR.name, steward=Roles.STEWARD.name) SEND_NYM_REG_EX = TXN_NYM.format(cmdName='send_nym', cmd='send')
from plenum.cli.constants import CLIENT_GRAMS_CLIENT_COMMAND_REG_EX, relist, \ CLI_CMDS, getPipedRegEx, CLIENT_GRAMS_USE_KEYPAIR_REG_EX from indy_common.roles import Roles from indy_common.transactions import IndyTransactions CLIENT_GRAMS_CLIENT_WITH_DID_FORMATTED_REG_EX = getPipedRegEx( CLIENT_GRAMS_CLIENT_COMMAND_REG_EX + "\s+ (?P<with_DID>with\s+DID) " "\s+ (?P<nym>[a-zA-Z0-9=]+) \s*") \ .format(relist(CLI_CMDS)) CLIENT_GRAMS_CLIENT_ADD_FORMATTED_REG_EX = getPipedRegEx( "(\s* (?P<client>client) \s+ (?P<client_name>[a-zA-Z0-9]+) " "\s+ (?P<cli_action>add) \s+ (?P<role>{trustAnchor}|user) " "\s+ (?P<other_client_name>[a-zA-Z0-9]+) \s*)".format(trustAnchor=Roles.TRUST_ANCHOR.name)) CLIENT_GRAMS_USE_KEYPAIR_FORMATTED_REG_EX = getPipedRegEx( CLIENT_GRAMS_USE_KEYPAIR_REG_EX) # TODO we can genericize the other TXN types in the same way TXN_NYM = "(\s* (?P<{{cmdName}}>{{cmd}}\s+{nym}) " \ "\s+ (?P<dest>dest=) \s* (?P<dest_id>[A-Za-z0-9+=/]*)" \ "(\s+ (?P<role_key>role=) \s* (?P<role>{trustee}|{tgb}|{trustAnchor}|{steward}|))?" \ "(\s+ (?P<ver_key>verkey=) \s* (?P<new_ver_key>[~A-Za-z0-9+=/]*))?)".format(nym=IndyTransactions.NYM.name, trustee=Roles.TRUSTEE.name, tgb=Roles.TGB.name, trustAnchor=Roles.TRUST_ANCHOR.name, steward=Roles.STEWARD.name) SEND_NYM_REG_EX = TXN_NYM.format(cmdName='send_nym', cmd='send')