This function is called by client transaction functions when they want
        to send a message to the application.
181083
def response(self, apdu):
        """"""
        if _debug: ClientSSM._debug("response %r", apdu)

        # make sure it has a good source and destination
        apdu.pduSource = self.pdu_address
        apdu.pduDestination = None

        # send it to the application
        self.ssmSAP.sap_response(apdu)
98530
function createMessage(type, transaction) {
  const msg = new StunMessage();

  msg.setType(type);
  msg.setTransactionID(transaction || createTransaction());

  return msg;
}
781636
@Override
    public void eventPostCommitAdd(Transaction transaction) throws SevereMessageStoreException
    {
        super.eventPostCommitAdd(transaction);
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(this, tc, "eventPostCommitAdd", transaction);

        if (failedInitInRestore)
        {
            initialiseNonPersistent(true);
            setRegisterForPostEvents(true);
        }

        if (TraceComponent.isAnyTracingEnabled() && UserTrace.tc_mt.isDebugEnabled())
        {
            try
            {
                if (getJSMessage(true).isApiMessage())
                {
                    boolean foreignBus = false;
                    boolean link = false;
                    boolean mqlink = false;

                    String targetME = null;
                    if (debugName != null)
                    {
                        SIMPItemStream itemstream = (SIMPItemStream) getItemStream();

                        BaseDestinationHandler destination = getDestinationHandler(false, itemstream);

                        if (itemstream instanceof PubSubMessageItemStream)
                        {
                            targetME = destination.getMessageProcessor().getMessagingEngineName();
                        }
                        else
                        {
                            SIBUuid8 meUUID = ((PtoPMessageItemStream) itemstream).getLocalizingMEUuid();
                            if (meUUID.equals(destination.getMessageProcessor().getMessagingEngineUuid()))
                                targetME = destination.getMessageProcessor().getMessagingEngineName();
                            else
                            {
                                // If it's not the local messaging engine, then don't attempt the very
                                // expensive operation of trawling through admin for a messaging engine
                                // we may (intra-bus) or may not (inter-bus) know about - just for UserTrace.
                                // While the V7 and later interface is better than V6.1, looking up the
                                // name would be an excessive overhead in the critical path.
                                targetME = meUUID.toString();
                            }

                        }

                        foreignBus = destination.isForeignBus();
                        link = destination.isLink();
                        mqlink = destination.isMQLink();
                    }

                    String apiMsgId = null;
                    String correlationId = null;

                    if (getJSMessage(true) instanceof JsApiMessage)
                    {
                        apiMsgId = ((JsApiMessage) getJSMessage(true)).getApiMessageId();
                        correlationId = ((JsApiMessage) getJSMessage(true)).getCorrelationId();
                    }
                    else
                    {
                        if (getJSMessage(true).getApiMessageIdAsBytes() != null)
                            apiMsgId = new String(getJSMessage(true).getApiMessageIdAsBytes());

                        if (getJSMessage(true).getCorrelationIdAsBytes() != null)
                            correlationId = new String(getJSMessage(true).getCorrelationIdAsBytes());
                    }

                    String msg = "PRODUCER_SEND_COMMIT_CWSJU0003";

                    if (foreignBus)
                        msg = "PRODUCER_SEND_COMMIT_BUS_CWSJU0064";
                    else if (mqlink)
                        msg = "PRODUCER_SEND_COMMIT_MQLINK_CWSJU0066";
                    else if (link)
                        msg = "PRODUCER_SEND_COMMIT_LINK_CWSJU0065";

                    SibTr.debug(this, UserTrace.tc_mt,
                                nls_mt.getFormattedMessage(
                                                           msg,
                                                           new Object[] {
                                                                         apiMsgId,
                                                                         getJSMessage(true).getSystemMessageId(),
                                                                         correlationId,
                                                                         debugName,
                                                                         targetME },
                                                           null));
                }
            } catch (MessageStoreException e)
            {
                // No FFDC code needed

                // Log the exception
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                    SibTr.exception(tc, e);

                // As the item is no longer in the store it has likely been committed already.
                // there doesn't seem any point to log the Message Trace at this point.
            }
        }

        // Remove temporary hack to delete publication with no subscribers 183715.1
        if (!transaction.isAutoCommit())
        {
            try
            {
                if (POST_COMMIT_ADD_1 != null)
                {
                    POST_COMMIT_ADD_1.messageEventOccurred(MessageEvents.POST_COMMIT_ADD, this, transaction);
                }
                if (POST_COMMIT_ADD_2 != null)
                {
                    POST_COMMIT_ADD_2.messageEventOccurred(MessageEvents.POST_COMMIT_ADD, this, transaction);
                }
            } catch (SIException e)
            {
                FFDCFilter.processException(
                                            e,
                                            "com.ibm.ws.sib.processor.impl.store.items.MessageItem.eventPostCommitAdd",
                                            "1:1313:1.244.1.40",
                                            this);

                SibTr.exception(tc, e);

                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                    SibTr.exit(this, tc, "eventPostCommitAdd", e);

                throw new SIErrorException(e);
            }
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(this, tc, "eventPostCommitAdd");
    }
293180
function InternalCB (data) {

        // [good or bad] let's notify user application
        if (data.status != 0) callback (data);

        // it's time to move to next message
        if (data.status <= 0) {
            if (++idx < smsarray.length) {
                new SmsRequest (smsc, InternalCB, smsarray [idx]);
            } else {
                callback ({status: 0});
            }
        }
    }
1219024
function (data, callback) {
    this.debug("Sending: %s", JSON.stringify(data));
    var message = dazeusify.call(this, data);
    this.client.write(message, callback);
}
665865
def onMessage(self, client, userdata, msg):
        
        dataIdentifier = DataIdentifier(self.broker, msg.topic)
        self.dataHandler.onNewData(dataIdentifier, msg.payload)
614261
function onMessage(data) {
    if (data.type == "utf8") {
        message = JSON.parse(data.utf8Data);
        switch (message.command) {
            case "setJoints":
                console.log("Client has request to add joints: " + message.data);
                nuimotion.jointsTracking = message.data;
                break;

            case "addListener":
                console.log("Client has request to add events: " + message.data);
                if (!nuimotion._eventCallbackDict[message.data]) {
                    nuimotion.addListener(message.data, onEvent);
                }
                break;

            case "addGesture":
                console.log("Client has request to add gestures: " + message.data);
                if (!nuimotion._gestureCallbackDict[message.data]) {
                    nuimotion.addGesture(message.data, onEvent);
                }
                break;
        }
    }
}
924761
function TransactionBuilder(apiClient) {
    
    if (typeof apiClient.namespace === "undefined" || apiClient.namespace === null) {
        throw new Error("The API client has not been initialized");
    }
    
    this.client = apiClient;
    this.records = [];
    this.keys = [];
    this.metadata = ByteBuffer.fromHex("");
}
131778
function sendTextMessage(recipientId, messageText) {
    var messageData = {
        recipient: {
            id: recipientId
        },
        message: {
            text: messageText
        }
    };
    callSendAPI(messageData);
}
1289935
private void internalHandleMessage(MessageItem msg,
                                       TransactionCommon transaction,
                                       SIBUuid8 sourceMEUuid,
                                       JsDestinationAddress inAddress,
                                       MessageProducer sender,
                                       boolean msgFRP)
                    throws SIConnectionLostException, SIRollbackException, SINotPossibleInCurrentConfigurationException,
                    SIIncorrectCallException, SIResourceException
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(tc, "internalHandleMessage", new Object[] { msg,
                                                                   transaction,
                                                                   sourceMEUuid,
                                                                   inAddress,
                                                                   sender,
                                                                   msgFRP });

        if (TraceComponent.isAnyTracingEnabled() && UserTrace.tc_mt.isDebugEnabled())
            traceSend(msg);

        super.handleMessage(msg);

        // Remember if the original user transaction was a real one or not
        msg.setTransacted(!transaction.isAutoCommit());

        //Inbound pub/sub messages are discarded once the destination is marked as 
        //deleted.
        if (!(_destination.isToBeDeleted()))
        {
            //For debug purposes, tell the message which destinations its on
            if (TraceComponent.isAnyTracingEnabled() && UserTrace.tc_mt.isDebugEnabled())
            {
                msg.setDebugName(_destination.getName());
            }

            if (sourceMEUuid.equals(_localMEUuid))
            {
                localPut(msg, transaction);
            }
            else
            {
                // Note: important to pass the originating cellule here so we
                // can update the origin map.
                try
                {
                    remotePut(msg, sourceMEUuid);
                } catch (SIResourceException e)
                {
                    // No FFDC code needed

                    SIMPResourceException ee = new SIMPResourceException(e);
                    ee.setExceptionReason(SIRCConstants.SIRC0901_INTERNAL_MESSAGING_ERROR);
                    ee.setExceptionInserts(new String[] { "com.ibm.ws.sib.processor.impl.PubSubInputHandler.handleMessage",
                                                         "1:1134:1.329.1.1",
                                                         SIMPUtils.getStackTrace(e)
                    });
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                        SibTr.exit(tc, "internalHandleMessage", ee);
                    throw ee;
                }
            }
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(tc, "internalHandleMessage");

        return;
    }
1355265
function messageResend(details, callback) {
        createsend.post('transactional/messages/'+details.messageID+'/resend', null, null, function(error, results) {
            txResponseCallback(error, results, callback);
        }, true);
    }
744307
def _callInTransaction(self, func, *args, **kwargs):
        """"""
        # No nesting of transactions
        self.conn.rollback()

        try:
            self.cur = self.conn.cursor()
            try:
                ret = func(*args, **kwargs)
            finally:
                self.cur.close()
                self.cur = None
        except:
            self.conn.rollback()
            raise
        else:
            self.conn.commit()

        return ret
1173034
private void sendDataToClient(BufferedWriter outToClient, String kafToString)
      throws IOException {
    outToClient.write(kafToString);
    outToClient.close();
  }
478745
public void sendMessage(final SMSBroker sms) {
		
		final int smsId = sms.getId();
		final String smsRecipient = sms.getRecipient();
		final String smsMessage = sms.getMessage();
		
		if (logger.isDebugEnabled()) {
			logger.debug("Entering into send message with parameter : ");
			logger.debug("   - message id : " + smsId);
			logger.debug("   - message recipient : " + smsRecipient);
			logger.debug("   - message : " + smsMessage);
		}
		
		try {
			final String messageISOLatin = new String(smsMessage.getBytes(),"ISO-8859-1");
			if (logger.isDebugEnabled()) {
				logger.debug("sending encoded message : " + messageISOLatin);
			}

			final SMText smText = RequestFactory.createSMText(smsId, smsRecipient, messageISOLatin);
			smText.setNotificationLevel(NOTIFICATION_LEVEL);
			
			// only send the message if required
			if (!simulateMessageSending) {
				olmConnector.submit(smText);
                logger.debug("message with : " + " - id : " + smsId + "successfully sent");
			} else {
				logger.warn("Message with id : " + smsId + " not sent because simlation mode is enable");
			}

			
		} catch (Throwable t) {
			logger.error("An error occurs sending SMS : " + 
				     " - id : " + smsId + 
				     " - recipient : " + smsRecipient + 
				     " - message : " + smsMessage);
		}		

	}
303116
function handleMessageFromHub(ws, json, device_pubkey, bIndirectCorrespondent, callbacks){
	var subject = json.subject;
	var body = json.body;
	if (!subject || typeof body == "undefined")
		return callbacks.ifError("no subject or body");
	//if (bIndirectCorrespondent && ["cancel_new_wallet", "my_xpubkey", "new_wallet_address"].indexOf(subject) === -1)
	//    return callbacks.ifError("you're indirect correspondent, cannot trust "+subject+" from you");
	var from_address = objectHash.getDeviceAddress(device_pubkey);
	
	switch (subject){
		case "pairing":
			device.handlePairingMessage(json, device_pubkey, callbacks);
			break;
		
		case "text":
			message_counter++;
			if (!ValidationUtils.isNonemptyString(body))
				return callbacks.ifError("text body must be string");
			// the wallet should have an event handler that displays the text to the user
			eventBus.emit("text", from_address, body, message_counter);
			callbacks.ifOk();
			break;

		case "object":
			message_counter++;
			if(typeof body !== 'object')
				return callbacks.ifError("body must be object");

			eventBus.emit("object", from_address, body, message_counter);
			callbacks.ifOk();
			break;

		case "removed_paired_device":
		//	if(conf.bIgnoreUnpairRequests) {
		//		// unpairing is ignored
		//		callbacks.ifError("removed_paired_device ignored: "+from_address);
		//	} else {
				determineIfDeviceCanBeRemoved(from_address, function(bRemovable){
					if (!bRemovable)
						return callbacks.ifError("device "+from_address+" is not removable");
					if (conf.bIgnoreUnpairRequests){
						db.query("UPDATE correspondent_devices SET is_blackhole=1 WHERE device_address=?", [from_address]);
						return callbacks.ifOk();
					}
					device.removeCorrespondentDevice(from_address, function(){
						eventBus.emit("removed_paired_device", from_address);
						callbacks.ifOk();
					});
				});
		//	}
			break;

		case "chat_recording_pref":
			message_counter++;
			eventBus.emit("chat_recording_pref", from_address, body, message_counter);
			callbacks.ifOk();
			break;
		
		case "create_new_wallet":
			// {wallet: "base64", wallet_definition_template: [...]}
			walletDefinedByKeys.handleOfferToCreateNewWallet(body, from_address, callbacks);
			break;
		
		case "cancel_new_wallet":
			// {wallet: "base64"}
			if (!ValidationUtils.isNonemptyString(body.wallet))
				return callbacks.ifError("no wallet");
			walletDefinedByKeys.deleteWallet(body.wallet, from_address, callbacks.ifOk);
			break;
		
		case "my_xpubkey": // allowed from non-correspondents
			// {wallet: "base64", my_xpubkey: "base58"}
			if (!ValidationUtils.isNonemptyString(body.wallet))
				return callbacks.ifError("no wallet");
			if (!ValidationUtils.isNonemptyString(body.my_xpubkey))
				return callbacks.ifError("no my_xpubkey");
			if (body.my_xpubkey.length > 112)
				return callbacks.ifError("my_xpubkey too long");
			walletDefinedByKeys.addDeviceXPubKey(body.wallet, from_address, body.my_xpubkey, callbacks.ifOk);
			break;
		
		case "wallet_fully_approved": // allowed from non-correspondents
			// {wallet: "base64"}
			if (!ValidationUtils.isNonemptyString(body.wallet))
				return callbacks.ifError("no wallet");
			walletDefinedByKeys.handleNotificationThatWalletFullyApproved(body.wallet, from_address, callbacks.ifOk);
			break;
		
		case "new_wallet_address":
			// {wallet: "base64", is_change: (0|1), address_index: 1234, address: "BASE32"}
			if (!ValidationUtils.isNonemptyString(body.wallet))
				return callbacks.ifError("no wallet");
			if (!(body.is_change === 0 || body.is_change === 1))
				return callbacks.ifError("bad is_change");
			if (!ValidationUtils.isNonnegativeInteger(body.address_index))
				return callbacks.ifError("bad address_index");
			if (!ValidationUtils.isValidAddress(body.address))
				return callbacks.ifError("no address or bad address");
			walletDefinedByKeys.addNewAddress(body.wallet, body.is_change, body.address_index, body.address, function(err){
				if (err)
					return callbacks.ifError(err);
				callbacks.ifOk();
			});
			break;
			
		case "create_new_shared_address":
			// {address_definition_template: [...]}
			if (!ValidationUtils.isArrayOfLength(body.address_definition_template, 2))
				return callbacks.ifError("no address definition template");
			walletDefinedByAddresses.validateAddressDefinitionTemplate(
				body.address_definition_template, from_address, 
				function(err, assocMemberDeviceAddressesBySigningPaths){
					if (err)
						return callbacks.ifError(err);
					// this event should trigger a confirmatin dialog, user needs to approve creation of the shared address and choose his 
					// own address that is to become a member of the shared address
					eventBus.emit("create_new_shared_address", body.address_definition_template, assocMemberDeviceAddressesBySigningPaths);
					callbacks.ifOk();
				}
			);
			break;
		
		case "approve_new_shared_address":
			// {address_definition_template_chash: "BASE32", address: "BASE32", device_addresses_by_relative_signing_paths: {...}}
			if (!ValidationUtils.isValidAddress(body.address_definition_template_chash))
				return callbacks.ifError("invalid addr def c-hash");
			if (!ValidationUtils.isValidAddress(body.address))
				return callbacks.ifError("invalid address");
			if (typeof body.device_addresses_by_relative_signing_paths !== "object" 
					|| Object.keys(body.device_addresses_by_relative_signing_paths).length === 0)
				return callbacks.ifError("invalid device_addresses_by_relative_signing_paths");
			walletDefinedByAddresses.approvePendingSharedAddress(body.address_definition_template_chash, from_address, 
				body.address, body.device_addresses_by_relative_signing_paths);
			callbacks.ifOk();
			break;
			
		case "reject_new_shared_address":
			// {address_definition_template_chash: "BASE32"}
			if (!ValidationUtils.isValidAddress(body.address_definition_template_chash))
				return callbacks.ifError("invalid addr def c-hash");
			walletDefinedByAddresses.deletePendingSharedAddress(body.address_definition_template_chash);
			callbacks.ifOk();
			break;
			
		case "new_shared_address":
			// {address: "BASE32", definition: [...], signers: {...}}
			walletDefinedByAddresses.handleNewSharedAddress(body, {
				ifError: callbacks.ifError,
				ifOk: function(){
					callbacks.ifOk();
					eventBus.emit('maybe_new_transactions');
				}
			});
			break;
			
		// request to sign a unit created on another device
		// two use cases:
		// 1. multisig: same address hosted on several devices
		// 2. multilateral signing: different addresses signing the same message, such as a (dumb) contract
		case "sign":
			// {address: "BASE32", signing_path: "r.1.2.3", unsigned_unit: {...}}
			if (!ValidationUtils.isValidAddress(body.address))
				return callbacks.ifError("no address or bad address");
			if (!ValidationUtils.isNonemptyString(body.signing_path) || body.signing_path.charAt(0) !== 'r')
				return callbacks.ifError("bad signing path");
			var objUnit = body.unsigned_unit;
			if (typeof objUnit !== "object")
				return callbacks.ifError("no unsigned unit");
			var bJsonBased = (objUnit.version !== constants.versionWithoutTimestamp);
			// replace all existing signatures with placeholders so that signing requests sent to us on different stages of signing become identical,
			// hence the hashes of such unsigned units are also identical
			objUnit.authors.forEach(function(author){
				var authentifiers = author.authentifiers;
				for (var path in authentifiers)
					authentifiers[path] = authentifiers[path].replace(/./, '-'); 
			});
			var assocPrivatePayloads = body.private_payloads;
			if ("private_payloads" in body){
				if (typeof assocPrivatePayloads !== "object" || !assocPrivatePayloads)
					return callbacks.ifError("bad private payloads");
				for (var payload_hash in assocPrivatePayloads){
					var payload = assocPrivatePayloads[payload_hash];
					var hidden_payload = _.cloneDeep(payload);
					if (payload.denomination) // indivisible asset.  In this case, payload hash is calculated based on output_hash rather than address and blinding
						hidden_payload.outputs.forEach(function(o){
							delete o.address;
							delete o.blinding;
						});
					var calculated_payload_hash = objectHash.getBase64Hash(hidden_payload, bJsonBased);
					if (payload_hash !== calculated_payload_hash)
						return callbacks.ifError("private payload hash does not match");
					if (!ValidationUtils.isNonemptyArray(objUnit.messages))
						return callbacks.ifError("no messages in unsigned unit");
					if (objUnit.messages.filter(function(objMessage){ return (objMessage.payload_hash === payload_hash); }).length !== 1)
						return callbacks.ifError("no such payload hash in the messages");
				}
			}
			if (objUnit.messages){
				var arrMessages = objUnit.messages;
				if (!Array.isArray(arrMessages))
					return callbacks.ifError("bad type of messages");
				for (var i=0; i<arrMessages.length; i++){
					if (arrMessages[i].payload === undefined)
						continue;
					var calculated_payload_hash = objectHash.getBase64Hash(arrMessages[i].payload, bJsonBased);
					if (arrMessages[i].payload_hash !== calculated_payload_hash)
						return callbacks.ifError("payload hash does not match");
				}
			}
			else if (objUnit.signed_message){
				// ok
			}
			else
				return callbacks.ifError("neither messages nor signed_message");
			// findAddress handles both types of addresses
			findAddress(body.address, body.signing_path, {
				ifError: callbacks.ifError,
				ifLocal: function(objAddress){
					// the commented check would make multilateral signing impossible
					//db.query("SELECT 1 FROM extended_pubkeys WHERE wallet=? AND device_address=?", [row.wallet, from_address], function(sender_rows){
					//    if (sender_rows.length !== 1)
					//        return callbacks.ifError("sender is not cosigner of this address");
						callbacks.ifOk();
						if (objUnit.signed_message && !ValidationUtils.hasFieldsExcept(objUnit, ["signed_message", "authors"])){
							objUnit.unit = objectHash.getBase64Hash(objUnit); // exact value doesn't matter, it just needs to be there
							return eventBus.emit("signing_request", objAddress, body.address, objUnit, assocPrivatePayloads, from_address, body.signing_path);
						}
						objUnit.unit = objectHash.getUnitHash(objUnit);
						var objJoint = {unit: objUnit, unsigned: true};
						eventBus.once("validated-"+objUnit.unit, function(bValid){
							if (!bValid){
								console.log("===== unit in signing request is invalid");
								return;
							}
							// This event should trigger a confirmation dialog.
							// If we merge coins from several addresses of the same wallet, we'll fire this event multiple times for the same unit.
							// The event handler must lock the unit before displaying a confirmation dialog, then remember user's choice and apply it to all
							// subsequent requests related to the same unit
							eventBus.emit("signing_request", objAddress, body.address, objUnit, assocPrivatePayloads, from_address, body.signing_path);
						});
						// if validation is already under way, handleOnlineJoint will quickly exit because of assocUnitsInWork.
						// as soon as the previously started validation finishes, it will trigger our event handler (as well as its own)
						network.handleOnlineJoint(ws, objJoint);
					//});
				},
				ifRemote: function(device_address){
					if (device_address === from_address){
						callbacks.ifError("looping signing request for address "+body.address+", path "+body.signing_path);
						throw Error("looping signing request for address "+body.address+", path "+body.signing_path);
					}
					var text_to_sign = objectHash.getUnitHashToSign(body.unsigned_unit).toString("base64");
					// I'm a proxy, wait for response from the actual signer and forward to the requestor
					eventBus.once("signature-"+device_address+"-"+body.address+"-"+body.signing_path+"-"+text_to_sign, function(sig){
						sendSignature(from_address, text_to_sign, sig, body.signing_path, body.address);
					});
					// forward the offer to the actual signer
					device.sendMessageToDevice(device_address, subject, body);
					callbacks.ifOk();
				},
				ifMerkle: function(bLocal){
					callbacks.ifError("there is merkle proof at signing path "+body.signing_path);
				},
				ifUnknownAddress: function(){
					callbacks.ifError("not aware of address "+body.address+" but will see if I learn about it later");
					eventBus.once("new_address-"+body.address, function(){
						// rewrite callbacks to avoid duplicate unlocking of mutex
						handleMessageFromHub(ws, json, device_pubkey, bIndirectCorrespondent, { ifOk: function(){}, ifError: function(){} });
					});
				}
			});
			break;
		
		case "signature":
			// {signed_text: "base64 of sha256", signing_path: "r.1.2.3", signature: "base64"}
			if (!ValidationUtils.isStringOfLength(body.signed_text, constants.HASH_LENGTH)) // base64 of sha256
				return callbacks.ifError("bad signed text");
			if (!ValidationUtils.isStringOfLength(body.signature, constants.SIG_LENGTH) && body.signature !== '[refused]')
				return callbacks.ifError("bad signature length");
			if (!ValidationUtils.isNonemptyString(body.signing_path) || body.signing_path.charAt(0) !== 'r')
				return callbacks.ifError("bad signing path");
			if (!ValidationUtils.isValidAddress(body.address))
				return callbacks.ifError("bad address");
			eventBus.emit("signature-" + from_address + "-" + body.address + "-" + body.signing_path + "-" + body.signed_text, body.signature);
			callbacks.ifOk();
			break;
			
		case 'private_payments':
			handlePrivatePaymentChains(ws, body, from_address, callbacks);
			break;
			
		case 'payment_notification':
			// note that since the payments are public, an evil user might notify us about a payment sent by someone else 
			// (we'll be fooled to believe it was sent by the evil user).  It is only possible if he learns our address, e.g. if we make it public.
			// Normally, we generate a one-time address and share it in chat session with the future payer only.
			var current_message_counter = ++message_counter;
			var unit = body;
			if (!ValidationUtils.isStringOfLength(unit, constants.HASH_LENGTH))
				return callbacks.ifError("invalid unit in payment notification");
			var bEmitted = false;
			var emitPn = function(objJoint){
				if (bEmitted)
					return;
				bEmitted = true;
				emitNewPublicPaymentReceived(from_address, objJoint.unit, current_message_counter);
			};
			eventBus.once('saved_unit-'+unit, emitPn);
			storage.readJoint(db, unit, {
				ifNotFound: function(){
					console.log("received payment notification for unit "+unit+" which is not known yet, will wait for it");
					callbacks.ifOk();
				},
				ifFound: function(objJoint){
					emitPn(objJoint);
					eventBus.removeListener('saved_unit-'+unit, emitPn);
					callbacks.ifOk();
				}
			});
			break;
		
		case 'prosaic_contract_offer':
			body.peer_device_address = from_address;
			if (!body.title || !body.text || !body.creation_date)
				return callbacks.ifError("not all contract fields submitted");
			if (!ValidationUtils.isValidAddress(body.peer_address) || !ValidationUtils.isValidAddress(body.my_address))
				return callbacks.ifError("either peer_address or address is not valid in contract");
			if (body.hash !== prosaic_contract.getHash(body))
				return callbacks.ifError("wrong contract hash");
			if (!/^\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}:\d{2}$/.test(body.creation_date))
				return callbacks.ifError("wrong contract creation date");
			prosaic_contract.store(body);
			var chat_message = "(prosaic-contract:" + Buffer.from(JSON.stringify(body), 'utf8').toString('base64') + ")";
			eventBus.emit("text", from_address, chat_message, ++message_counter);
			callbacks.ifOk();
			break;

		case 'prosaic_contract_shared':
			if (!body.title || !body.text || !body.creation_date)
				return callbacks.ifError("not all contract fields submitted");
			if (!ValidationUtils.isValidAddress(body.peer_address) || !ValidationUtils.isValidAddress(body.my_address))
				return callbacks.ifError("either peer_address or address is not valid in contract");
			if (body.hash !== prosaic_contract.getHash(body))
				return callbacks.ifError("wrong contract hash");
			if (!/^\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}:\d{2}$/.test(body.creation_date))
				return callbacks.ifError("wrong contract creation date");
			db.query("SELECT 1 FROM my_addresses \n\
					JOIN wallet_signing_paths USING(wallet)\n\
					WHERE my_addresses.address=? AND wallet_signing_paths.device_address=?",[body.my_address, from_address],
				function(rows) {
					if (!rows.length)
						return callbacks.ifError("contract does not contain my address");
					prosaic_contract.store(body);
					callbacks.ifOk();
				}
			);
			break;

		case 'prosaic_contract_response':
			var validation = require('./validation.js');

			if (body.status !== "accepted" && body.status !== "declined")
				return callbacks.ifError("wrong status supplied");

			prosaic_contract.getByHash(body.hash, function(objContract){
				if (!objContract)
					return callbacks.ifError("wrong contract hash");
				if (body.status === "accepted" && !body.signed_message)
					return callbacks.ifError("response is not signed");
				var processResponse = function(objSignedMessage) {
					if (body.authors && body.authors.length) {
						if (body.authors.length !== 1)
							return callbacks.ifError("wrong number of authors received");
						var author = body.authors[0];
						if (author.definition && (author.address !== objectHash.getChash160(author.definition)))
							return callbacks.ifError("incorrect definition received");
						if (!ValidationUtils.isValidAddress(author.address) || author.address !== objContract.peer_address)
							return callbacks.ifError("incorrect author address");
						// this can happen when acceptor and offerer have same device in cosigners
						db.query('SELECT 1 FROM my_addresses WHERE address=? \n\
							UNION SELECT 1 FROM shared_addresses WHERE shared_address=?', [author.address, author.address], function(rows) {
								if (rows.length)
									return;
								db.query("INSERT "+db.getIgnore()+" INTO peer_addresses (address, device_address, signing_paths, definition) VALUES (?, ?, ?, ?)",
									[author.address, from_address, JSON.stringify(Object.keys(objSignedMessage.authors[0].authentifiers)), JSON.stringify(author.definition)],
									function(res) {
										if (res.affectedRows == 0)
											db.query("UPDATE peer_addresses SET signing_paths=?, definition=? WHERE address=?", [JSON.stringify(Object.keys(objSignedMessage.authors[0].authentifiers)), JSON.stringify(author.definition), author.address]);
									}
								);
							}
						);
					}
					if (objContract.status !== 'pending')
						return callbacks.ifError("contract is not active, current status: " + objContract.status);
					var objDateCopy = new Date(objContract.creation_date_obj);
					if (objDateCopy.setHours(objDateCopy.getHours() + objContract.ttl) < Date.now())
						return callbacks.ifError("contract already expired");
					prosaic_contract.setField(objContract.hash, "status", body.status);
					eventBus.emit("text", from_address, "contract \""+objContract.title+"\" " + body.status, ++message_counter);
					eventBus.emit("prosaic_contract_response_received" + body.hash, (body.status === "accepted"), body.authors);
					callbacks.ifOk();
				};
				if (body.signed_message) {
					var signedMessageJson = Buffer.from(body.signed_message, 'base64').toString('utf8');
					try{
						var objSignedMessage = JSON.parse(signedMessageJson);
					}
					catch(e){
						return callbacks.ifError("wrong signed message");
					}
					validation.validateSignedMessage(objSignedMessage, function(err) {
						if (err || objSignedMessage.authors[0].address !== objContract.peer_address || objSignedMessage.signed_message != objContract.title)
							return callbacks.ifError("wrong contract signature");
						processResponse(objSignedMessage);
					});
				} else
					processResponse();
			});
			break;

		case 'prosaic_contract_update':
			prosaic_contract.getByHash(body.hash, function(objContract){
				if (!objContract || objContract.peer_device_address !== from_address)
					return callbacks.ifError("wrong contract hash or not an owner");
				if (body.field == "status") {
					if (body.value !== "revoked" || objContract.status !== "pending")
							return callbacks.ifError("wrong status for contract supplied");
				} else 
				if (body.field == "unit") {
					if (objContract.status !== "accepted")
						return callbacks.ifError("contract was not accepted");
					if (objContract.unit)
							return callbacks.ifError("unit was already provided for this contract");
				} else
				if (body.field == "shared_address") {
					if (objContract.status !== "accepted")
						return callbacks.ifError("contract was not accepted");
					if (objContract.shared_address)
							return callbacks.ifError("shared_address was already provided for this contract");
						if (!ValidationUtils.isValidAddress(body.value))
							return callbacks.ifError("invalid address provided");
				} else {
					return callbacks.ifError("wrong field");
				}
				prosaic_contract.setField(objContract.hash, body.field, body.value);
				callbacks.ifOk();
			});
			break;
			
		default:
			callbacks.ifError("unknnown subject: "+subject);
	}
}
779646
function receiveMessageFromBrackets(msgObj) {
        var argList = msgObj.args;
        argList.unshift(msgObj.requester || "");
        functionMap[msgObj.fn].apply(null, argList);
    }
1192319
public void handleTransaction(ChaincodeMessage message) {
		// The defer followed by triggering a go routine dance is needed to ensure that the previous state transition
		// is completed before the next one is triggered. The previous state transition is deemed complete only when
		// the beforeInit function is exited. Interesting bug fix!!
		Runnable task = () -> {
			//better not be nil
			ChaincodeMessage nextStatemessage = null;
			boolean send = true;

			//Defer
			try {
				// Get the function and args from Payload
				ChaincodeInput input;
				try {
					input = ChaincodeInput.parseFrom(message.getPayload());
				} catch (Exception e) {
					logger.debug(String.format("[%s]Incorrect payload format. Sending %s", shortID(message), ERROR));
					// Send ERROR message to chaincode support and change state
					nextStatemessage = ChaincodeMessage.newBuilder()
							.setType(ERROR)
							.setPayload(message.getPayload())
							.setTxid(message.getTxid())
							.build();
					return;
				}

				// Mark as a transaction (allow put/del state)
				markIsTransaction(message.getTxid(), true);

				// Create the ChaincodeStub which the chaincode can use to callback
				ChaincodeStub stub = new ChaincodeStub(message.getTxid(), this, message.getSecurityContext());

				// Call chaincode's Run
				ByteString response;
				try {
					response = chaincode.runHelper(stub, getFunction(input.getArgsList()), getParameters(input.getArgsList()));
				} catch (Exception e) {
					e.printStackTrace();
					System.err.flush();
					// Send ERROR message to chaincode support and change state
					logger.error(String.format("[%s]Error running chaincode. Transaction execution failed. Sending %s",
							shortID(message), ERROR));
					nextStatemessage = ChaincodeMessage.newBuilder()
							.setType(ERROR)
							.setPayload(message.getPayload())
							.setTxid(message.getTxid())
							.build();
					return;
				} finally {
					deleteIsTransaction(message.getTxid());
				}

				logger.debug(String.format("[%s]Transaction completed. Sending %s",
						shortID(message), COMPLETED));

				// Send COMPLETED message to chaincode support and change state
				Builder builder = ChaincodeMessage.newBuilder()
						.setType(COMPLETED)
						.setTxid(message.getTxid());
				if (response != null) builder.setPayload(response);
				nextStatemessage = builder.build();
			} finally {
				triggerNextState(nextStatemessage, send);
			}
		};

		new Thread(task).start();
	}