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.
81 lines
2.3 KiB
TypeScript
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}`
|
|
);
|
|
}
|