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.
		
		
		
		
		
			
		
			
				
	
	
		
			79 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.7 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/types';
 | |
| import { NetworkTimeSubRequest } from './SnodeRequestTypes';
 | |
| import { doSnodeBatchRequest } from './batchRequest';
 | |
| 
 | |
| 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();
 | |
| }
 | |
| 
 | |
| export const GetNetworkTime = {
 | |
|   getNetworkTime,
 | |
|   handleTimestampOffsetFromNetwork,
 | |
|   getLatestTimestampOffset,
 | |
|   getNowWithNetworkOffset,
 | |
| };
 |