You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/session/sending/LokiMessageApi.ts

81 lines
2.3 KiB
TypeScript

import _ from 'lodash';
import { storeOnNode } from '../snode_api/SNodeAPI';
import { getSwarmFor } from '../snode_api/snodePool';
import { firstTrue } from '../utils/Promise';
const DEFAULT_CONNECTIONS = 3;
/**
* Refactor note: We should really clean this up ... it's very messy
*
* We need to split it into 2 sends:
* - Snodes
* - Open Groups
*
* Mikunj:
* Temporarily i've made it so `MessageSender` handles open group sends and calls this function for regular sends.
*/
export async function sendMessage(
pubKey: string,
data: Uint8Array,
messageTimeStamp: number,
ttl: number,
options: {
isPublic?: boolean;
} = {}
): Promise<void> {
const { isPublic = false } = options;
if (isPublic) {
window?.log?.warn('this sendMessage() should not be called anymore with an open group message');
return;
}
const data64 = window.dcodeIO.ByteBuffer.wrap(data).toString('base64');
// Using timestamp as a unique identifier
const swarm = await getSwarmFor(pubKey);
// send parameters
const params = {
pubKey,
ttl: `${ttl}`,
timestamp: `${messageTimeStamp}`,
data: data64,
};
const usedNodes = _.slice(swarm, 0, DEFAULT_CONNECTIONS);
const promises = usedNodes.map(async usedNode => {
// TODO: Revert back to using snode address instead of IP
// No pRetry here as if this is a bad path it will be handled and retried in lokiOnionFetch.
// the only case we could care about a retry would be when the usedNode is not correct,
// but considering we trigger this request with a few snode in //, this should be fine.
const successfulSend = await storeOnNode(usedNode, params);
if (successfulSend) {
return usedNode;
}
// should we mark snode as bad if it can't store our message?
return undefined;
});
let snode;
try {
snode = await firstTrue(promises);
} catch (e) {
const snodeStr = snode ? `${snode.ip}:${snode.port}` : 'null';
window?.log?.warn(
`loki_message:::sendMessage - ${e.code} ${e.message} to ${pubKey} via snode:${snodeStr}`
);
throw e;
}
if (!usedNodes || usedNodes.length === 0) {
throw new window.textsecure.EmptySwarmError(pubKey, 'Ran out of swarm nodes to query');
}
window?.log?.info(
`loki_message:::sendMessage - Successfully stored message to ${pubKey} via ${snode.ip}:${snode.port}`
);
}