Skip to content

Commit

Permalink
Fix median calculation for large block number deltas across FallbackP…
Browse files Browse the repository at this point in the history
…rovider backends.
  • Loading branch information
ricmoo committed Apr 23, 2020
1 parent 8cf4b3c commit fca5ccb
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions packages/providers/src.ts/fallback-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,23 @@ function checkNetworks(networks: Array<Network>): Network {
return result;
}

function median(values: Array<number>): number {
values = values.slice().sort();
const middle = Math.floor(values.length / 2);
function median(values: Array<number>, maxDelta?: number): number {
values = values.slice().sort();
const middle = Math.floor(values.length / 2);

// Odd length; take the middle
if (values.length % 2) {
return values[middle];
}
// Odd length; take the middle
if (values.length % 2) {
return values[middle];
}

// Even length; take the average of the two middle
const a = values[middle - 1], b = values[middle];

// Even length; take the average of the two 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 {
Expand Down Expand Up @@ -178,7 +183,10 @@ function getProcessFunc(provider: FallbackProvider, method: string, params: { [
const values = configs.map((c) => c.result);

// 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 (values.indexOf(blockNumber + 1) >= 0) { blockNumber++; }
Expand Down Expand Up @@ -391,6 +399,7 @@ export class FallbackProvider extends BaseProvider {
configs.sort((a, b) => (a.priority - b.priority));

let i = 0;
let first = true;
while (true) {
const t0 = now();

Expand Down Expand Up @@ -470,6 +479,8 @@ export class FallbackProvider extends BaseProvider {
if (results.length >= this.quorum) {
const result = processFunc(results);
if (result !== undefined) { return result; }
if (!first) { await stall(100); }
first = false;
}

// All configs have run to completion; we will never get more data
Expand Down

0 comments on commit fca5ccb

Please sign in to comment.