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.
86 lines
2.9 KiB
TypeScript
86 lines
2.9 KiB
TypeScript
/**
|
|
* Makes a post to a node to receive the timestamp info. If non-existant, returns -1
|
|
* @param snode Snode to send request to
|
|
* @returns timestamp of the response from snode
|
|
*/
|
|
|
|
import { isNumber } from 'lodash';
|
|
import { Snode } from '../../../data/data';
|
|
import { doSnodeBatchRequest } from './batchRequest';
|
|
import { NetworkTimeSubRequest } from './SnodeRequestTypes';
|
|
|
|
function getNetworkTimeSubRequests(): Array<NetworkTimeSubRequest> {
|
|
const request: NetworkTimeSubRequest = { method: 'info', params: {} };
|
|
|
|
return [request];
|
|
}
|
|
|
|
const getNetworkTime = async (snode: Snode): Promise<string | number> => {
|
|
const subRequests = getNetworkTimeSubRequests();
|
|
const result = await doSnodeBatchRequest(subRequests, snode, 4000, null);
|
|
if (!result || !result.length) {
|
|
window?.log?.warn(`getNetworkTime on ${snode.ip}:${snode.port} returned falsish value`, result);
|
|
throw new Error('getNetworkTime: Invalid result');
|
|
}
|
|
|
|
const firstResult = result[0];
|
|
|
|
if (firstResult.code !== 200) {
|
|
window?.log?.warn('Status is not 200 for getNetworkTime but: ', firstResult.code);
|
|
throw new Error('getNetworkTime: Invalid status code');
|
|
}
|
|
|
|
const timestamp = firstResult?.body?.timestamp;
|
|
if (!timestamp) {
|
|
throw new Error(`getNetworkTime returned invalid timestamp: ${timestamp}`);
|
|
}
|
|
GetNetworkTime.handleTimestampOffsetFromNetwork('getNetworkTime', timestamp);
|
|
return timestamp;
|
|
};
|
|
|
|
let latestTimestampOffset = Number.MAX_SAFE_INTEGER;
|
|
|
|
function handleTimestampOffsetFromNetwork(_request: string, snodeTimestamp: number) {
|
|
if (snodeTimestamp && isNumber(snodeTimestamp) && snodeTimestamp > 1609419600 * 1000) {
|
|
// first january 2021. Arbitrary, just want to make sure the return timestamp is somehow valid and not some crazy low value
|
|
const now = Date.now();
|
|
if (latestTimestampOffset === Number.MAX_SAFE_INTEGER) {
|
|
window?.log?.info(`first timestamp offset received: ${now - snodeTimestamp}ms`);
|
|
}
|
|
latestTimestampOffset = now - snodeTimestamp;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function has no use to be called except during tests.
|
|
* @returns the current offset we have with the rest of the network.
|
|
*/
|
|
function getLatestTimestampOffset() {
|
|
if (latestTimestampOffset === Number.MAX_SAFE_INTEGER) {
|
|
window.log.debug('latestTimestampOffset is not set yet');
|
|
return 0;
|
|
}
|
|
// window.log.info('latestTimestampOffset is ', latestTimestampOffset);
|
|
|
|
return latestTimestampOffset;
|
|
}
|
|
|
|
function getNowWithNetworkOffset() {
|
|
// make sure to call exports here, as we stub the exported one for testing.
|
|
return Date.now() - GetNetworkTime.getLatestTimestampOffset();
|
|
}
|
|
|
|
function getNowWithNetworkOffsetSeconds() {
|
|
// make sure to call exports here, as we stub the exported one for testing.
|
|
|
|
return Math.floor(GetNetworkTime.getNowWithNetworkOffset() / 1000);
|
|
}
|
|
|
|
export const GetNetworkTime = {
|
|
getNetworkTime,
|
|
handleTimestampOffsetFromNetwork,
|
|
getNowWithNetworkOffsetSeconds,
|
|
getLatestTimestampOffset,
|
|
getNowWithNetworkOffset,
|
|
};
|