Skip to content

Commit 0335f09

Browse files
authored
Add network rotation on bad sapling root (#557)
1 parent 945d5c8 commit 0335f09

File tree

4 files changed

+60
-7
lines changed

4 files changed

+60
-7
lines changed

scripts/network/network.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ import { Transaction } from '../transaction.js';
3535
*
3636
*/
3737
export class Network {
38+
/**
39+
* @type{boolean}
40+
*/
41+
isRpc;
3842
constructor() {
3943
if (this.constructor === Network) {
4044
throw new Error('Initializing virtual class');
@@ -156,6 +160,7 @@ export class RPCNodeNetwork extends Network {
156160
* @public
157161
*/
158162
this.strUrl = strUrl;
163+
this.isRpc = true;
159164
}
160165
/**
161166
* A Fetch wrapper which uses the current Node's base URL
@@ -393,6 +398,7 @@ export class ExplorerNetwork extends Network {
393398
* @public
394399
*/
395400
this.strUrl = strUrl;
401+
this.isRpc = false;
396402
}
397403

398404
/**

scripts/network/network_manager.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,42 @@ class NetworkManager {
5555
} else {
5656
this.#currentExplorer = found;
5757
}
58+
59+
getEventEmitter().emit(
60+
isRPC ? 'rpc_changed' : 'explorer_changed',
61+
strUrl
62+
);
63+
}
64+
65+
/**
66+
* Changes RPC and explorer to next one
67+
* To be called in case of an error believed to be a network one
68+
* e.g. wrong sapling root
69+
*/
70+
rotateNetworks() {
71+
const currentExplorerIndex = this.#networks.findIndex(
72+
(n) => n === this.#currentExplorer
73+
);
74+
const currentNodeIndex = this.#networks.findIndex(
75+
(n) => n === this.#currentNode
76+
);
77+
const indices = [currentExplorerIndex, currentNodeIndex];
78+
for (let j = 0; j < indices.length; j++) {
79+
for (let i = 1; i < this.#networks.length; i++) {
80+
const isRpc = j === 1;
81+
const index = indices[j];
82+
const tryNetwork =
83+
this.#networks[(index + i) % this.#networks.length];
84+
if (tryNetwork.isRpc === isRpc) {
85+
if (isRpc) {
86+
this.#currentNode = tryNetwork;
87+
} else {
88+
this.#currentExplorer = tryNetwork;
89+
}
90+
break;
91+
}
92+
}
93+
}
5894
}
5995

6096
/**

scripts/settings.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ function subscribeToNetworkEvents() {
203203
getEventEmitter().on('currency-loaded', async (mapCurrencies) => {
204204
await fillCurrencySelect(mapCurrencies);
205205
});
206+
getEventEmitter().on('explorer_changed', (url) => {
207+
// Update the selector UI
208+
doms.domExplorerSelect.value = url;
209+
});
210+
getEventEmitter().on('rpc_changed', (url) => {
211+
// Update the selector UI
212+
doms.domNodeSelect.value = url;
213+
});
206214
}
207215

208216
// --- Settings Functions
@@ -211,27 +219,20 @@ export async function setExplorer(explorer, fSilent = false) {
211219
await database.setSettings({ explorer: explorer.url });
212220
getNetwork().setNetwork(explorer.url, false);
213221

214-
// Update the selector UI
215-
doms.domExplorerSelect.value = explorer.url;
216-
217222
if (!fSilent) {
218223
createAlert(
219224
'success',
220225
tr(ALERTS.SWITCHED_EXPLORERS, [{ explorerName: explorer.name }]),
221226
2250
222227
);
223228
}
224-
getEventEmitter().emit('explorer_changed', explorer.url);
225229
}
226230

227231
export async function setNode(node, fSilent = false) {
228232
getNetwork().setNetwork(node.url, true);
229233
const database = await Database.getInstance();
230234
database.setSettings({ node: node.url });
231235

232-
// Update the selector UI
233-
doms.domNodeSelect.value = node.url;
234-
235236
if (!fSilent)
236237
createAlert(
237238
'success',

scripts/wallet.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,16 @@ export class Wallet {
10621062
);
10631063
// If explorer sapling root is different from ours, there must be a sync error
10641064
if (saplingRoot !== networkSaplingRoot) {
1065+
const db = await Database.getInstance();
1066+
1067+
// Reset shield sync data, it might be corrupted
1068+
await db.setShieldSyncData({
1069+
shieldData: null,
1070+
lastSyncedBlock: null,
1071+
});
1072+
// Try to rotate networks to see if another RPC/explorer has the correct data
1073+
getNetwork().rotateNetworks();
1074+
10651075
createAlert('warning', translation.badSaplingRoot, 5000);
10661076
return false;
10671077
}

0 commit comments

Comments
 (0)