More robust defaultProvider start-up when a backend fails on bootstrap (#3979).
This commit is contained in:
parent
2e5935b91c
commit
984f6fa155
@ -97,12 +97,15 @@ interface Config extends FallbackProviderState {
|
|||||||
_updateNumber: null | Promise<any>;
|
_updateNumber: null | Promise<any>;
|
||||||
_network: null | Network;
|
_network: null | Network;
|
||||||
_totalTime: number;
|
_totalTime: number;
|
||||||
|
_lastFatalError: null | Error;
|
||||||
|
_lastFatalErrorTimestamp: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
blockNumber: -2, requests: 0, lateResponses: 0, errorResponses: 0,
|
blockNumber: -2, requests: 0, lateResponses: 0, errorResponses: 0,
|
||||||
outOfSync: -1, unsupportedEvents: 0, rollingDuration: 0, score: 0,
|
outOfSync: -1, unsupportedEvents: 0, rollingDuration: 0, score: 0,
|
||||||
_network: null, _updateNumber: null, _totalTime: 0
|
_network: null, _updateNumber: null, _totalTime: 0,
|
||||||
|
_lastFatalError: null, _lastFatalErrorTimestamp: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -110,15 +113,22 @@ async function waitForSync(config: Config, blockNumber: number): Promise<void> {
|
|||||||
while (config.blockNumber < 0 || config.blockNumber < blockNumber) {
|
while (config.blockNumber < 0 || config.blockNumber < blockNumber) {
|
||||||
if (!config._updateNumber) {
|
if (!config._updateNumber) {
|
||||||
config._updateNumber = (async () => {
|
config._updateNumber = (async () => {
|
||||||
const blockNumber = await config.provider.getBlockNumber();
|
try {
|
||||||
if (blockNumber > config.blockNumber) {
|
const blockNumber = await config.provider.getBlockNumber();
|
||||||
config.blockNumber = blockNumber;
|
if (blockNumber > config.blockNumber) {
|
||||||
|
config.blockNumber = blockNumber;
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
config.blockNumber = -2;
|
||||||
|
config._lastFatalError = error;
|
||||||
|
config._lastFatalErrorTimestamp = getTime();
|
||||||
}
|
}
|
||||||
config._updateNumber = null;
|
config._updateNumber = null;
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
await config._updateNumber;
|
await config._updateNumber;
|
||||||
config.outOfSync++;
|
config.outOfSync++;
|
||||||
|
if (config._lastFatalError) { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,6 +423,7 @@ export class FallbackProvider extends AbstractProvider {
|
|||||||
allConfigs.sort((a, b) => (b.priority - a.priority));
|
allConfigs.sort((a, b) => (b.priority - a.priority));
|
||||||
|
|
||||||
for (const config of allConfigs) {
|
for (const config of allConfigs) {
|
||||||
|
if (config._lastFatalError) { continue; }
|
||||||
if (configs.indexOf(config) === -1) { return config; }
|
if (configs.indexOf(config) === -1) { return config; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,9 +482,11 @@ export class FallbackProvider extends AbstractProvider {
|
|||||||
if (!initialSync) {
|
if (!initialSync) {
|
||||||
const promises: Array<Promise<any>> = [ ];
|
const promises: Array<Promise<any>> = [ ];
|
||||||
this.#configs.forEach((config) => {
|
this.#configs.forEach((config) => {
|
||||||
promises.push(waitForSync(config, 0));
|
|
||||||
promises.push((async () => {
|
promises.push((async () => {
|
||||||
config._network = await config.provider.getNetwork();
|
await waitForSync(config, 0);
|
||||||
|
if (!config._lastFatalError) {
|
||||||
|
config._network = await config.provider.getNetwork();
|
||||||
|
}
|
||||||
})());
|
})());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -484,6 +497,7 @@ export class FallbackProvider extends AbstractProvider {
|
|||||||
// Check all the networks match
|
// Check all the networks match
|
||||||
let chainId: null | bigint = null;
|
let chainId: null | bigint = null;
|
||||||
for (const config of this.#configs) {
|
for (const config of this.#configs) {
|
||||||
|
if (config._lastFatalError) { continue; }
|
||||||
const network = <Network>(config._network);
|
const network = <Network>(config._network);
|
||||||
if (chainId == null) {
|
if (chainId == null) {
|
||||||
chainId = network.chainId;
|
chainId = network.chainId;
|
||||||
@ -519,7 +533,7 @@ export class FallbackProvider extends AbstractProvider {
|
|||||||
case "getBlockNumber": {
|
case "getBlockNumber": {
|
||||||
// We need to get the bootstrap block height
|
// We need to get the bootstrap block height
|
||||||
if (this.#height === -2) {
|
if (this.#height === -2) {
|
||||||
this.#height = Math.ceil(getNumber(<bigint>getMedian(this.quorum, this.#configs.map((c) => ({
|
this.#height = Math.ceil(getNumber(<bigint>getMedian(this.quorum, this.#configs.filter((c) => (!c._lastFatalError)).map((c) => ({
|
||||||
value: c.blockNumber,
|
value: c.blockNumber,
|
||||||
tag: getNumber(c.blockNumber).toString(),
|
tag: getNumber(c.blockNumber).toString(),
|
||||||
weight: c.weight
|
weight: c.weight
|
||||||
|
Loading…
Reference in New Issue
Block a user