Skip to content

Commit

Permalink
Merge pull request #1504 from myxmaster/fix-connection-issues
Browse files Browse the repository at this point in the history
Fix node connection issues
  • Loading branch information
kaloudis committed Aug 4, 2023
2 parents 4c0b2ad + 4f65d0f commit bb7e660
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 97 deletions.
69 changes: 36 additions & 33 deletions backends/Eclair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ import Base64Utils from './../utils/Base64Utils';
import { Hash as sha256Hash } from 'fast-sha256';

// keep track of all active calls so we can cancel when appropriate
const calls: any = {};
const calls = new Map<string, Promise<any>>();

export default class Eclair {
clearCachedCalls = () => calls.clear();

api = (method: string, params: any = {}) => {
const { password, certVerification, enableTor } = stores.settingsStore;
let { url } = stores.settingsStore;

const id: string = method + JSON.stringify(params);
if (calls[id]) {
return calls[id];
if (calls.has(id)) {
return calls.get(id);
}

url = url.slice(-1) === '/' ? url : url + '/';
Expand All @@ -28,48 +30,49 @@ export default class Eclair {
const body = querystring.stringify(params);

if (enableTor === true) {
calls[id] = doTorRequest(
url + method,
RequestMethod.POST,
body,
headers
calls.set(
id,
doTorRequest(url + method, RequestMethod.POST, body, headers)
);
} else {
calls[id] = ReactNativeBlobUtil.config({
trusty: !certVerification
})
.fetch('POST', url + method, headers, body)
.then((response: any) => {
delete calls[id];
calls.set(
id,
ReactNativeBlobUtil.config({
trusty: !certVerification
})
.fetch('POST', url + method, headers, body)
.then((response: any) => {
calls.delete(id);

const status = response.info().status;
if (status < 300) {
return response.json();
} else {
let errorInfo;
try {
errorInfo = response.json();
} catch (err) {
throw new Error(
'response was (' +
status +
')' +
response.text()
);
const status = response.info().status;
if (status < 300) {
return response.json();
} else {
let errorInfo;
try {
errorInfo = response.json();
} catch (err) {
throw new Error(
'response was (' +
status +
')' +
response.text()
);
}
throw new Error(errorInfo.error);
}
throw new Error(errorInfo.error);
}
});
})
);
}
setTimeout(
(id: string) => {
delete calls[id];
calls.delete(id);
},
9000,
id
);

return calls[id];
return calls.get(id);
};

getTransactions = () =>
Expand Down
87 changes: 51 additions & 36 deletions backends/LND.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ interface Headers {
}

// keep track of all active calls so we can cancel when appropriate
const calls: any = {};
const calls = new Map<string, Promise<any>>();

export default class LND {
torSocksPort?: number = undefined;

clearCachedCalls = () => calls.clear();

restReq = async (
headers: Headers | any,
url: string,
Expand All @@ -29,49 +33,60 @@ export default class LND {
// use body data as an identifier too, we don't want to cancel when we
// are making multiples calls to get all the node names, for example
const id = data ? `${url}${JSON.stringify(data)}` : url;
if (calls[id]) {
return calls[id];
if (calls.has(id)) {
return calls.get(id);
}
// API is a bit of a mess but
// If tor enabled in setting, start up the daemon here
if (useTor === true) {
calls[id] = doTorRequest(
url,
method as RequestMethod,
JSON.stringify(data),
headers
).then((response: any) => {
delete calls[id];
return response;
});
calls.set(
id,
doTorRequest(
url,
method as RequestMethod,
JSON.stringify(data),
headers
).then((response: any) => {
calls.delete(id);
return response;
})
);
} else {
calls[id] = ReactNativeBlobUtil.config({
trusty: !certVerification
})
.fetch(method, url, headers, data ? JSON.stringify(data) : data)
.then((response: any) => {
delete calls[id];
if (response.info().status < 300) {
// handle ws responses
if (response.data.includes('\n')) {
const split = response.data.split('\n');
const length = split.length;
// last instance is empty
return JSON.parse(split[length - 2]);
calls.set(
id,
ReactNativeBlobUtil.config({
trusty: !certVerification
})
.fetch(
method,
url,
headers,
data ? JSON.stringify(data) : data
)
.then((response: any) => {
calls.delete(id);
if (response.info().status < 300) {
// handle ws responses
if (response.data.includes('\n')) {
const split = response.data.split('\n');
const length = split.length;
// last instance is empty
return JSON.parse(split[length - 2]);
}
return response.json();
} else {
const errorInfo = response.json();
throw new Error(
(errorInfo.error && errorInfo.error.message) ||
errorInfo.message ||
errorInfo.error
);
}
return response.json();
} else {
const errorInfo = response.json();
throw new Error(
(errorInfo.error && errorInfo.error.message) ||
errorInfo.message ||
errorInfo.error
);
}
});
})
);
}

return await calls[id];
return await calls.get(id);
};

supports = (minVersion: string, eosVersion?: string) => {
Expand Down
61 changes: 33 additions & 28 deletions backends/Spark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ import TransactionRequest from './../models/TransactionRequest';
import OpenChannelRequest from './../models/OpenChannelRequest';

// keep track of all active calls so we can cancel when appropriate
const calls: any = {};
const calls = new Map<string, Promise<any>>();

export default class Spark {
clearCachedCalls = () => calls.clear();

rpc = (rpcmethod: string, param = {}, range: any = null) => {
const { accessKey, certVerification, enableTor } = stores.settingsStore;
let { url } = stores.settingsStore;

const id = rpcmethod + JSON.stringify(param) + JSON.stringify(range);
if (calls[id]) {
return calls[id];
if (calls.has(id)) {
return calls.get(id);
}

url = url.slice(-4) === '/rpc' ? url : url + '/rpc';
Expand All @@ -26,35 +28,38 @@ export default class Spark {
const body = JSON.stringify({ method: rpcmethod, params: param });

if (enableTor === true) {
calls[id] = doTorRequest(url, RequestMethod.POST, body, headers);
calls.set(id, doTorRequest(url, RequestMethod.POST, body, headers));
} else {
calls[id] = ReactNativeBlobUtil.config({
trusty: !certVerification
})
.fetch('POST', url, headers, body)
.then((response: any) => {
delete calls[id];
const status = response.info().status;
if (status < 300) {
return response.json();
} else {
let errorInfo;
try {
errorInfo = response.json();
} catch (err) {
throw new Error(
'response was (' +
status +
')' +
response.text()
);
calls.set(
id,
ReactNativeBlobUtil.config({
trusty: !certVerification
})
.fetch('POST', url, headers, body)
.then((response: any) => {
calls.delete(id);
const status = response.info().status;
if (status < 300) {
return response.json();
} else {
let errorInfo;
try {
errorInfo = response.json();
} catch (err) {
throw new Error(
'response was (' +
status +
')' +
response.text()
);
}
throw new Error(errorInfo.message);
}
throw new Error(errorInfo.message);
}
});
})
);
}

return calls[id];
return calls.get(id);
};

getTransactions = () =>
Expand Down
9 changes: 9 additions & 0 deletions stores/NodeInfoStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,18 @@ export default class NodeInfoStore {
this.loading = true;
};

private currentRequest: any;

@action
public getNodeInfo = () => {
this.errorMsg = '';
this.loading = true;
const currentRequest = (this.currentRequest = {});
BackendUtils.getMyNodeInfo()
.then((data: any) => {
if (this.currentRequest !== currentRequest) {
return;
}
const nodeInfo = new NodeInfo(data);
this.nodeInfo = nodeInfo;
this.testnet = nodeInfo.isTestNet;
Expand All @@ -52,6 +58,9 @@ export default class NodeInfoStore {
this.error = false;
})
.catch((error: any) => {
if (this.currentRequest !== currentRequest) {
return;
}
// handle error
this.errorMsg = ErrorUtils.errorToUserFriendly(
error.toString()
Expand Down
1 change: 1 addition & 0 deletions stores/SettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,7 @@ export default class SettingsStore {
if (status) {
this.error = false;
this.errorMsg = '';
BackendUtils.clearCachedCalls();
}
this.connecting = status;
return this.connecting;
Expand Down
2 changes: 2 additions & 0 deletions utils/BackendUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class BackendUtils {
checkPerms = () => this.call('checkPerms');
isConnected = (...args: any[]) => this.call('isConnected', args);
disconnect = (...args: any[]) => this.call('disconnect', args);

clearCachedCalls = (...args: any[]) => this.call('clearCachedCalls', args);
}

const backendUtils = new BackendUtils();
Expand Down

0 comments on commit bb7e660

Please sign in to comment.