Fix median calculation for large block number deltas across FallbackProvider backends.
This commit is contained in:
parent
8cf4b3cf45
commit
fca5ccbc20
@ -40,18 +40,23 @@ function checkNetworks(networks: Array<Network>): Network {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function median(values: Array<number>): number {
|
function median(values: Array<number>, maxDelta?: number): number {
|
||||||
values = values.slice().sort();
|
values = values.slice().sort();
|
||||||
const middle = Math.floor(values.length / 2);
|
const middle = Math.floor(values.length / 2);
|
||||||
|
|
||||||
// Odd length; take the middle
|
// Odd length; take the middle
|
||||||
if (values.length % 2) {
|
if (values.length % 2) {
|
||||||
return values[middle];
|
return values[middle];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even length; take the average of the two middle
|
// Even length; take the average of the two middle
|
||||||
const a = values[middle - 1], b = values[middle];
|
const a = values[middle - 1], b = values[middle];
|
||||||
return (a + b) / 2;
|
|
||||||
|
if (maxDelta != null && Math.abs(a - b) > maxDelta) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (a + b) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
function serialize(value: any): string {
|
function serialize(value: any): string {
|
||||||
@ -178,7 +183,10 @@ function getProcessFunc(provider: FallbackProvider, method: string, params: { [
|
|||||||
const values = configs.map((c) => c.result);
|
const values = configs.map((c) => c.result);
|
||||||
|
|
||||||
// Get the median block number
|
// Get the median block number
|
||||||
let blockNumber = Math.ceil(median(configs.map((c) => c.result)));
|
let blockNumber = median(configs.map((c) => c.result), 2);
|
||||||
|
if (blockNumber == null) { return undefined; }
|
||||||
|
|
||||||
|
blockNumber = Math.ceil(blockNumber);
|
||||||
|
|
||||||
// If the next block height is present, its prolly safe to use
|
// If the next block height is present, its prolly safe to use
|
||||||
if (values.indexOf(blockNumber + 1) >= 0) { blockNumber++; }
|
if (values.indexOf(blockNumber + 1) >= 0) { blockNumber++; }
|
||||||
@ -391,6 +399,7 @@ export class FallbackProvider extends BaseProvider {
|
|||||||
configs.sort((a, b) => (a.priority - b.priority));
|
configs.sort((a, b) => (a.priority - b.priority));
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
let first = true;
|
||||||
while (true) {
|
while (true) {
|
||||||
const t0 = now();
|
const t0 = now();
|
||||||
|
|
||||||
@ -470,6 +479,8 @@ export class FallbackProvider extends BaseProvider {
|
|||||||
if (results.length >= this.quorum) {
|
if (results.length >= this.quorum) {
|
||||||
const result = processFunc(results);
|
const result = processFunc(results);
|
||||||
if (result !== undefined) { return result; }
|
if (result !== undefined) { return result; }
|
||||||
|
if (!first) { await stall(100); }
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All configs have run to completion; we will never get more data
|
// All configs have run to completion; we will never get more data
|
||||||
|
Loading…
Reference in New Issue
Block a user