@qevm/providers 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/alchemy-provider.d.ts +1 -1
- package/lib/alchemy-provider.d.ts.map +1 -1
- package/lib/alchemy-provider.js +29 -53
- package/lib/alchemy-provider.js.map +1 -1
- package/lib/ankr-provider.d.ts +1 -1
- package/lib/ankr-provider.d.ts.map +1 -1
- package/lib/ankr-provider.js +16 -36
- package/lib/ankr-provider.js.map +1 -1
- package/lib/base-provider.d.ts +3 -4
- package/lib/base-provider.d.ts.map +1 -1
- package/lib/base-provider.js +1477 -2132
- package/lib/base-provider.js.map +1 -1
- package/lib/browser-ipc-provider.js +1 -1
- package/lib/browser-ipc-provider.js.map +1 -1
- package/lib/browser-net.js +1 -2
- package/lib/browser-net.js.map +1 -1
- package/lib/browser-ws.js +5 -5
- package/lib/browser-ws.js.map +1 -1
- package/lib/cloudflare-provider.js +20 -83
- package/lib/cloudflare-provider.js.map +1 -1
- package/lib/etherscan-provider.js +237 -357
- package/lib/etherscan-provider.js.map +1 -1
- package/lib/fallback-provider.js +301 -430
- package/lib/fallback-provider.js.map +1 -1
- package/lib/formatter.d.ts +4 -4
- package/lib/formatter.d.ts.map +1 -1
- package/lib/formatter.js +107 -110
- package/lib/formatter.js.map +1 -1
- package/lib/index.js +25 -25
- package/lib/index.js.map +1 -1
- package/lib/infura-provider.d.ts +1 -1
- package/lib/infura-provider.d.ts.map +1 -1
- package/lib/infura-provider.js +34 -58
- package/lib/infura-provider.js.map +1 -1
- package/lib/ipc-provider.js +20 -40
- package/lib/ipc-provider.js.map +1 -1
- package/lib/json-rpc-batch-provider.d.ts +0 -1
- package/lib/json-rpc-batch-provider.d.ts.map +1 -1
- package/lib/json-rpc-batch-provider.js +27 -48
- package/lib/json-rpc-batch-provider.js.map +1 -1
- package/lib/json-rpc-provider.d.ts +1 -1
- package/lib/json-rpc-provider.d.ts.map +1 -1
- package/lib/json-rpc-provider.js +283 -482
- package/lib/json-rpc-provider.js.map +1 -1
- package/lib/nodesmith-provider.js +12 -32
- package/lib/nodesmith-provider.js.map +1 -1
- package/lib/pocket-provider.d.ts +1 -1
- package/lib/pocket-provider.d.ts.map +1 -1
- package/lib/pocket-provider.js +17 -37
- package/lib/pocket-provider.js.map +1 -1
- package/lib/url-json-rpc-provider.d.ts +1 -1
- package/lib/url-json-rpc-provider.d.ts.map +1 -1
- package/lib/url-json-rpc-provider.js +45 -116
- package/lib/url-json-rpc-provider.js.map +1 -1
- package/lib/web3-provider.d.ts +2 -2
- package/lib/web3-provider.d.ts.map +1 -1
- package/lib/web3-provider.js +49 -70
- package/lib/web3-provider.js.map +1 -1
- package/lib/websocket-provider.d.ts +2 -2
- package/lib/websocket-provider.d.ts.map +1 -1
- package/lib/websocket-provider.js +128 -225
- package/lib/websocket-provider.js.map +1 -1
- package/lib/ws.js +1 -1
- package/lib/ws.js.map +1 -1
- package/package.json +17 -14
- package/src.ts/alchemy-provider.ts +1 -1
- package/src.ts/ankr-provider.ts +1 -1
- package/src.ts/base-provider.ts +9 -9
- package/src.ts/etherscan-provider.ts +1 -1
- package/src.ts/fallback-provider.ts +4 -4
- package/src.ts/formatter.ts +2 -2
- package/src.ts/infura-provider.ts +1 -1
- package/src.ts/json-rpc-batch-provider.ts +1 -1
- package/src.ts/json-rpc-provider.ts +3 -3
- package/src.ts/pocket-provider.ts +1 -1
- package/src.ts/url-json-rpc-provider.ts +1 -1
- package/src.ts/websocket-provider.ts +1 -1
package/lib/fallback-provider.js
CHANGED
|
@@ -1,75 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
28
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
-
function step(op) {
|
|
31
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
-
while (_) try {
|
|
33
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
-
switch (op[0]) {
|
|
36
|
-
case 0: case 1: t = op; break;
|
|
37
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
-
default:
|
|
41
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
-
if (t[2]) _.ops.pop();
|
|
46
|
-
_.trys.pop(); continue;
|
|
47
|
-
}
|
|
48
|
-
op = body.call(thisArg, _);
|
|
49
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
3
|
exports.FallbackProvider = void 0;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
4
|
+
const abstract_provider_1 = require("@qevm/abstract-provider");
|
|
5
|
+
const bignumber_1 = require("@qevm/bignumber");
|
|
6
|
+
const bytes_1 = require("@qevm/bytes");
|
|
7
|
+
const properties_1 = require("@ethersproject/properties");
|
|
8
|
+
const random_1 = require("@qevm/random");
|
|
9
|
+
const web_1 = require("@qevm/web");
|
|
10
|
+
const base_provider_1 = require("./base-provider");
|
|
11
|
+
const formatter_1 = require("./formatter");
|
|
12
|
+
const logger_1 = require("@ethersproject/logger");
|
|
13
|
+
const _version_1 = require("./_version");
|
|
14
|
+
const logger = new logger_1.Logger(_version_1.version);
|
|
66
15
|
function now() { return (new Date()).getTime(); }
|
|
67
16
|
// Returns to network as long as all agree, or null if any is null.
|
|
68
17
|
// Throws an error if any two networks do not match.
|
|
69
18
|
function checkNetworks(networks) {
|
|
70
|
-
|
|
71
|
-
for (
|
|
72
|
-
|
|
19
|
+
let result = null;
|
|
20
|
+
for (let i = 0; i < networks.length; i++) {
|
|
21
|
+
const network = networks[i];
|
|
73
22
|
// Null! We do not know our network; bail.
|
|
74
23
|
if (network == null) {
|
|
75
24
|
return null;
|
|
@@ -89,13 +38,13 @@ function checkNetworks(networks) {
|
|
|
89
38
|
}
|
|
90
39
|
function median(values, maxDelta) {
|
|
91
40
|
values = values.slice().sort();
|
|
92
|
-
|
|
41
|
+
const middle = Math.floor(values.length / 2);
|
|
93
42
|
// Odd length; take the middle
|
|
94
43
|
if (values.length % 2) {
|
|
95
44
|
return values[middle];
|
|
96
45
|
}
|
|
97
46
|
// Even length; take the average of the two middle
|
|
98
|
-
|
|
47
|
+
const a = values[middle - 1], b = values[middle];
|
|
99
48
|
if (maxDelta != null && Math.abs(a - b) > maxDelta) {
|
|
100
49
|
return null;
|
|
101
50
|
}
|
|
@@ -115,13 +64,13 @@ function serialize(value) {
|
|
|
115
64
|
return value.toString();
|
|
116
65
|
}
|
|
117
66
|
else if (Array.isArray(value)) {
|
|
118
|
-
return JSON.stringify(value.map(
|
|
67
|
+
return JSON.stringify(value.map((i) => serialize(i)));
|
|
119
68
|
}
|
|
120
69
|
else if (typeof (value) === "object") {
|
|
121
|
-
|
|
70
|
+
const keys = Object.keys(value);
|
|
122
71
|
keys.sort();
|
|
123
|
-
return "{" + keys.map(
|
|
124
|
-
|
|
72
|
+
return "{" + keys.map((key) => {
|
|
73
|
+
let v = value[key];
|
|
125
74
|
if (typeof (v) === "function") {
|
|
126
75
|
v = "[function]";
|
|
127
76
|
}
|
|
@@ -134,12 +83,12 @@ function serialize(value) {
|
|
|
134
83
|
throw new Error("unknown value type: " + typeof (value));
|
|
135
84
|
}
|
|
136
85
|
// Next request ID to use for emitting debug info
|
|
137
|
-
|
|
86
|
+
let nextRid = 1;
|
|
138
87
|
;
|
|
139
88
|
function stall(duration) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
89
|
+
let cancel = null;
|
|
90
|
+
let timer = null;
|
|
91
|
+
let promise = (new Promise((resolve) => {
|
|
143
92
|
cancel = function () {
|
|
144
93
|
if (timer) {
|
|
145
94
|
clearTimeout(timer);
|
|
@@ -149,23 +98,23 @@ function stall(duration) {
|
|
|
149
98
|
};
|
|
150
99
|
timer = setTimeout(cancel, duration);
|
|
151
100
|
}));
|
|
152
|
-
|
|
101
|
+
const wait = (func) => {
|
|
153
102
|
promise = promise.then(func);
|
|
154
103
|
return promise;
|
|
155
104
|
};
|
|
156
105
|
function getPromise() {
|
|
157
106
|
return promise;
|
|
158
107
|
}
|
|
159
|
-
return { cancel
|
|
108
|
+
return { cancel, getPromise, wait };
|
|
160
109
|
}
|
|
161
|
-
|
|
110
|
+
const ForwardErrors = [
|
|
162
111
|
logger_1.Logger.errors.CALL_EXCEPTION,
|
|
163
112
|
logger_1.Logger.errors.INSUFFICIENT_FUNDS,
|
|
164
113
|
logger_1.Logger.errors.NONCE_EXPIRED,
|
|
165
114
|
logger_1.Logger.errors.REPLACEMENT_UNDERPRICED,
|
|
166
115
|
logger_1.Logger.errors.UNPREDICTABLE_GAS_LIMIT
|
|
167
116
|
];
|
|
168
|
-
|
|
117
|
+
const ForwardProperties = [
|
|
169
118
|
"address",
|
|
170
119
|
"args",
|
|
171
120
|
"errorArgs",
|
|
@@ -175,10 +124,10 @@ var ForwardProperties = [
|
|
|
175
124
|
];
|
|
176
125
|
;
|
|
177
126
|
function exposeDebugConfig(config, now) {
|
|
178
|
-
|
|
127
|
+
const result = {
|
|
179
128
|
weight: config.weight
|
|
180
129
|
};
|
|
181
|
-
Object.defineProperty(result, "provider", { get:
|
|
130
|
+
Object.defineProperty(result, "provider", { get: () => config.provider });
|
|
182
131
|
if (config.start) {
|
|
183
132
|
result.start = config.start;
|
|
184
133
|
}
|
|
@@ -198,18 +147,18 @@ function exposeDebugConfig(config, now) {
|
|
|
198
147
|
function normalizedTally(normalize, quorum) {
|
|
199
148
|
return function (configs) {
|
|
200
149
|
// Count the votes for each result
|
|
201
|
-
|
|
202
|
-
configs.forEach(
|
|
203
|
-
|
|
150
|
+
const tally = {};
|
|
151
|
+
configs.forEach((c) => {
|
|
152
|
+
const value = normalize(c.result);
|
|
204
153
|
if (!tally[value]) {
|
|
205
154
|
tally[value] = { count: 0, result: c.result };
|
|
206
155
|
}
|
|
207
156
|
tally[value].count++;
|
|
208
157
|
});
|
|
209
158
|
// Check for a quorum on any given result
|
|
210
|
-
|
|
211
|
-
for (
|
|
212
|
-
|
|
159
|
+
const keys = Object.keys(tally);
|
|
160
|
+
for (let i = 0; i < keys.length; i++) {
|
|
161
|
+
const check = tally[keys[i]];
|
|
213
162
|
if (check.count >= quorum) {
|
|
214
163
|
return check.result;
|
|
215
164
|
}
|
|
@@ -219,7 +168,7 @@ function normalizedTally(normalize, quorum) {
|
|
|
219
168
|
};
|
|
220
169
|
}
|
|
221
170
|
function getProcessFunc(provider, method, params) {
|
|
222
|
-
|
|
171
|
+
let normalize = serialize;
|
|
223
172
|
switch (method) {
|
|
224
173
|
case "getBlockNumber":
|
|
225
174
|
// Return the median value, unless there is (median + 1) is also
|
|
@@ -227,9 +176,9 @@ function getProcessFunc(provider, method, params) {
|
|
|
227
176
|
// is going to be stale soon. In the event of a malicious node,
|
|
228
177
|
// the lie will be true soon enough.
|
|
229
178
|
return function (configs) {
|
|
230
|
-
|
|
179
|
+
const values = configs.map((c) => c.result);
|
|
231
180
|
// Get the median block number
|
|
232
|
-
|
|
181
|
+
let blockNumber = median(configs.map((c) => c.result), 2);
|
|
233
182
|
if (blockNumber == null) {
|
|
234
183
|
return undefined;
|
|
235
184
|
}
|
|
@@ -249,7 +198,7 @@ function getProcessFunc(provider, method, params) {
|
|
|
249
198
|
// but do not average even entries and choose the higher.
|
|
250
199
|
// Malicious actors must compromise 50% of the nodes to lie.
|
|
251
200
|
return function (configs) {
|
|
252
|
-
|
|
201
|
+
const values = configs.map((c) => c.result);
|
|
253
202
|
values.sort();
|
|
254
203
|
return values[Math.floor(values.length / 2)];
|
|
255
204
|
};
|
|
@@ -257,7 +206,7 @@ function getProcessFunc(provider, method, params) {
|
|
|
257
206
|
// Returns the median price. Malicious actors must compromise at
|
|
258
207
|
// least 50% of the nodes to lie (in a meaningful way).
|
|
259
208
|
return function (configs) {
|
|
260
|
-
return median(configs.map(
|
|
209
|
+
return median(configs.map((c) => c.result));
|
|
261
210
|
};
|
|
262
211
|
// No additional normalizing required; serialize is enough
|
|
263
212
|
case "getBalance":
|
|
@@ -289,7 +238,7 @@ function getProcessFunc(provider, method, params) {
|
|
|
289
238
|
return null;
|
|
290
239
|
}
|
|
291
240
|
block = (0, properties_1.shallowCopy)(block);
|
|
292
|
-
block.transactions = block.transactions.map(
|
|
241
|
+
block.transactions = block.transactions.map((tx) => {
|
|
293
242
|
tx = (0, properties_1.shallowCopy)(tx);
|
|
294
243
|
tx.confirmations = -1;
|
|
295
244
|
return tx;
|
|
@@ -315,126 +264,93 @@ function getProcessFunc(provider, method, params) {
|
|
|
315
264
|
}
|
|
316
265
|
// If we are doing a blockTag query, we need to make sure the backend is
|
|
317
266
|
// caught up to the FallbackProvider, before sending a request to it.
|
|
318
|
-
function waitForSync(config, blockNumber) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
return
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
// Try again, next block
|
|
338
|
-
return resolve(undefined);
|
|
339
|
-
}, 0);
|
|
340
|
-
});
|
|
341
|
-
}, { oncePoll: provider })];
|
|
267
|
+
async function waitForSync(config, blockNumber) {
|
|
268
|
+
const provider = (config.provider);
|
|
269
|
+
if ((provider.blockNumber != null && provider.blockNumber >= blockNumber) || blockNumber === -1) {
|
|
270
|
+
return provider;
|
|
271
|
+
}
|
|
272
|
+
return (0, web_1.poll)(() => {
|
|
273
|
+
return new Promise((resolve, reject) => {
|
|
274
|
+
setTimeout(function () {
|
|
275
|
+
// We are synced
|
|
276
|
+
if (provider.blockNumber >= blockNumber) {
|
|
277
|
+
return resolve(provider);
|
|
278
|
+
}
|
|
279
|
+
// We're done; just quit
|
|
280
|
+
if (config.cancelled) {
|
|
281
|
+
return resolve(null);
|
|
282
|
+
}
|
|
283
|
+
// Try again, next block
|
|
284
|
+
return resolve(undefined);
|
|
285
|
+
}, 0);
|
|
342
286
|
});
|
|
343
|
-
});
|
|
287
|
+
}, { oncePoll: provider });
|
|
344
288
|
}
|
|
345
|
-
function getRunner(config, currentBlockNumber, method, params) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
case "getBlockNumber": return [3 /*break*/, 1];
|
|
355
|
-
case "getGasPrice": return [3 /*break*/, 1];
|
|
356
|
-
case "getEtherPrice": return [3 /*break*/, 2];
|
|
357
|
-
case "getBalance": return [3 /*break*/, 3];
|
|
358
|
-
case "getTransactionCount": return [3 /*break*/, 3];
|
|
359
|
-
case "getCode": return [3 /*break*/, 3];
|
|
360
|
-
case "getStorageAt": return [3 /*break*/, 6];
|
|
361
|
-
case "getBlock": return [3 /*break*/, 9];
|
|
362
|
-
case "call": return [3 /*break*/, 12];
|
|
363
|
-
case "estimateGas": return [3 /*break*/, 12];
|
|
364
|
-
case "getTransaction": return [3 /*break*/, 15];
|
|
365
|
-
case "getTransactionReceipt": return [3 /*break*/, 15];
|
|
366
|
-
case "getLogs": return [3 /*break*/, 16];
|
|
367
|
-
}
|
|
368
|
-
return [3 /*break*/, 19];
|
|
369
|
-
case 1: return [2 /*return*/, provider[method]()];
|
|
370
|
-
case 2:
|
|
371
|
-
if (provider.getEtherPrice) {
|
|
372
|
-
return [2 /*return*/, provider.getEtherPrice()];
|
|
373
|
-
}
|
|
374
|
-
return [3 /*break*/, 19];
|
|
375
|
-
case 3:
|
|
376
|
-
if (!(params.blockTag && (0, bytes_1.isHexString)(params.blockTag))) return [3 /*break*/, 5];
|
|
377
|
-
return [4 /*yield*/, waitForSync(config, currentBlockNumber)];
|
|
378
|
-
case 4:
|
|
379
|
-
provider = _b.sent();
|
|
380
|
-
_b.label = 5;
|
|
381
|
-
case 5: return [2 /*return*/, provider[method](params.address, params.blockTag || "latest")];
|
|
382
|
-
case 6:
|
|
383
|
-
if (!(params.blockTag && (0, bytes_1.isHexString)(params.blockTag))) return [3 /*break*/, 8];
|
|
384
|
-
return [4 /*yield*/, waitForSync(config, currentBlockNumber)];
|
|
385
|
-
case 7:
|
|
386
|
-
provider = _b.sent();
|
|
387
|
-
_b.label = 8;
|
|
388
|
-
case 8: return [2 /*return*/, provider.getStorageAt(params.address, params.position, params.blockTag || "latest")];
|
|
389
|
-
case 9:
|
|
390
|
-
if (!(params.blockTag && (0, bytes_1.isHexString)(params.blockTag))) return [3 /*break*/, 11];
|
|
391
|
-
return [4 /*yield*/, waitForSync(config, currentBlockNumber)];
|
|
392
|
-
case 10:
|
|
393
|
-
provider = _b.sent();
|
|
394
|
-
_b.label = 11;
|
|
395
|
-
case 11: return [2 /*return*/, provider[(params.includeTransactions ? "getBlockWithTransactions" : "getBlock")](params.blockTag || params.blockHash)];
|
|
396
|
-
case 12:
|
|
397
|
-
if (!(params.blockTag && (0, bytes_1.isHexString)(params.blockTag))) return [3 /*break*/, 14];
|
|
398
|
-
return [4 /*yield*/, waitForSync(config, currentBlockNumber)];
|
|
399
|
-
case 13:
|
|
400
|
-
provider = _b.sent();
|
|
401
|
-
_b.label = 14;
|
|
402
|
-
case 14:
|
|
403
|
-
if (method === "call" && params.blockTag) {
|
|
404
|
-
return [2 /*return*/, provider[method](params.transaction, params.blockTag)];
|
|
405
|
-
}
|
|
406
|
-
return [2 /*return*/, provider[method](params.transaction)];
|
|
407
|
-
case 15: return [2 /*return*/, provider[method](params.transactionHash)];
|
|
408
|
-
case 16:
|
|
409
|
-
filter = params.filter;
|
|
410
|
-
if (!((filter.fromBlock && (0, bytes_1.isHexString)(filter.fromBlock)) || (filter.toBlock && (0, bytes_1.isHexString)(filter.toBlock)))) return [3 /*break*/, 18];
|
|
411
|
-
return [4 /*yield*/, waitForSync(config, currentBlockNumber)];
|
|
412
|
-
case 17:
|
|
413
|
-
provider = _b.sent();
|
|
414
|
-
_b.label = 18;
|
|
415
|
-
case 18: return [2 /*return*/, provider.getLogs(filter)];
|
|
416
|
-
case 19: return [2 /*return*/, logger.throwError("unknown method error", logger_1.Logger.errors.UNKNOWN_ERROR, {
|
|
417
|
-
method: method,
|
|
418
|
-
params: params
|
|
419
|
-
})];
|
|
289
|
+
async function getRunner(config, currentBlockNumber, method, params) {
|
|
290
|
+
let provider = config.provider;
|
|
291
|
+
switch (method) {
|
|
292
|
+
case "getBlockNumber":
|
|
293
|
+
case "getGasPrice":
|
|
294
|
+
return provider[method]();
|
|
295
|
+
case "getEtherPrice":
|
|
296
|
+
if (provider.getEtherPrice) {
|
|
297
|
+
return provider.getEtherPrice();
|
|
420
298
|
}
|
|
421
|
-
|
|
299
|
+
break;
|
|
300
|
+
case "getBalance":
|
|
301
|
+
case "getTransactionCount":
|
|
302
|
+
case "getCode":
|
|
303
|
+
if (params.blockTag && (0, bytes_1.isHexString)(params.blockTag)) {
|
|
304
|
+
provider = await waitForSync(config, currentBlockNumber);
|
|
305
|
+
}
|
|
306
|
+
return provider[method](params.address, params.blockTag || "latest");
|
|
307
|
+
case "getStorageAt":
|
|
308
|
+
if (params.blockTag && (0, bytes_1.isHexString)(params.blockTag)) {
|
|
309
|
+
provider = await waitForSync(config, currentBlockNumber);
|
|
310
|
+
}
|
|
311
|
+
return provider.getStorageAt(params.address, params.position, params.blockTag || "latest");
|
|
312
|
+
case "getBlock":
|
|
313
|
+
if (params.blockTag && (0, bytes_1.isHexString)(params.blockTag)) {
|
|
314
|
+
provider = await waitForSync(config, currentBlockNumber);
|
|
315
|
+
}
|
|
316
|
+
return provider[(params.includeTransactions ? "getBlockWithTransactions" : "getBlock")](params.blockTag || params.blockHash);
|
|
317
|
+
case "call":
|
|
318
|
+
case "estimateGas":
|
|
319
|
+
if (params.blockTag && (0, bytes_1.isHexString)(params.blockTag)) {
|
|
320
|
+
provider = await waitForSync(config, currentBlockNumber);
|
|
321
|
+
}
|
|
322
|
+
if (method === "call" && params.blockTag) {
|
|
323
|
+
return provider[method](params.transaction, params.blockTag);
|
|
324
|
+
}
|
|
325
|
+
return provider[method](params.transaction);
|
|
326
|
+
case "getTransaction":
|
|
327
|
+
case "getTransactionReceipt":
|
|
328
|
+
return provider[method](params.transactionHash);
|
|
329
|
+
case "getLogs": {
|
|
330
|
+
let filter = params.filter;
|
|
331
|
+
if ((filter.fromBlock && (0, bytes_1.isHexString)(filter.fromBlock)) || (filter.toBlock && (0, bytes_1.isHexString)(filter.toBlock))) {
|
|
332
|
+
provider = await waitForSync(config, currentBlockNumber);
|
|
333
|
+
}
|
|
334
|
+
return provider.getLogs(filter);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return logger.throwError("unknown method error", logger_1.Logger.errors.UNKNOWN_ERROR, {
|
|
338
|
+
method: method,
|
|
339
|
+
params: params
|
|
422
340
|
});
|
|
423
341
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
function FallbackProvider(providers, quorum) {
|
|
427
|
-
var _this = this;
|
|
342
|
+
class FallbackProvider extends base_provider_1.BaseProvider {
|
|
343
|
+
constructor(providers, quorum) {
|
|
428
344
|
if (providers.length === 0) {
|
|
429
345
|
logger.throwArgumentError("missing providers", "providers", providers);
|
|
430
346
|
}
|
|
431
|
-
|
|
347
|
+
const providerConfigs = providers.map((configOrProvider, index) => {
|
|
432
348
|
if (abstract_provider_1.Provider.isProvider(configOrProvider)) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
return Object.freeze({ provider: configOrProvider, weight: 1, stallTimeout
|
|
349
|
+
const stallTimeout = (0, formatter_1.isCommunityResource)(configOrProvider) ? 2000 : 750;
|
|
350
|
+
const priority = 1;
|
|
351
|
+
return Object.freeze({ provider: configOrProvider, weight: 1, stallTimeout, priority });
|
|
436
352
|
}
|
|
437
|
-
|
|
353
|
+
const config = (0, properties_1.shallowCopy)(configOrProvider);
|
|
438
354
|
if (config.priority == null) {
|
|
439
355
|
config.priority = 1;
|
|
440
356
|
}
|
|
@@ -444,13 +360,13 @@ var FallbackProvider = /** @class */ (function (_super) {
|
|
|
444
360
|
if (config.weight == null) {
|
|
445
361
|
config.weight = 1;
|
|
446
362
|
}
|
|
447
|
-
|
|
363
|
+
const weight = config.weight;
|
|
448
364
|
if (weight % 1 || weight > 512 || weight < 1) {
|
|
449
|
-
logger.throwArgumentError("invalid weight; must be integer in [1, 512]",
|
|
365
|
+
logger.throwArgumentError("invalid weight; must be integer in [1, 512]", `providers[${index}].weight`, weight);
|
|
450
366
|
}
|
|
451
367
|
return Object.freeze(config);
|
|
452
368
|
});
|
|
453
|
-
|
|
369
|
+
const total = providerConfigs.reduce((accum, c) => (accum + c.weight), 0);
|
|
454
370
|
if (quorum == null) {
|
|
455
371
|
quorum = total / 2;
|
|
456
372
|
}
|
|
@@ -458,242 +374,197 @@ var FallbackProvider = /** @class */ (function (_super) {
|
|
|
458
374
|
logger.throwArgumentError("quorum will always fail; larger than total weight", "quorum", quorum);
|
|
459
375
|
}
|
|
460
376
|
// Are all providers' networks are known
|
|
461
|
-
|
|
377
|
+
let networkOrReady = checkNetworks(providerConfigs.map((c) => (c.provider).network));
|
|
462
378
|
// Not all networks are known; we must stall
|
|
463
379
|
if (networkOrReady == null) {
|
|
464
|
-
networkOrReady = new Promise(
|
|
465
|
-
setTimeout(
|
|
466
|
-
|
|
380
|
+
networkOrReady = new Promise((resolve, reject) => {
|
|
381
|
+
setTimeout(() => {
|
|
382
|
+
this.detectNetwork().then(resolve, reject);
|
|
467
383
|
}, 0);
|
|
468
384
|
});
|
|
469
385
|
}
|
|
470
|
-
|
|
386
|
+
super(networkOrReady);
|
|
471
387
|
// Preserve a copy, so we do not get mutated
|
|
472
|
-
(0, properties_1.defineReadOnly)(
|
|
473
|
-
(0, properties_1.defineReadOnly)(
|
|
474
|
-
|
|
475
|
-
|
|
388
|
+
(0, properties_1.defineReadOnly)(this, "providerConfigs", Object.freeze(providerConfigs));
|
|
389
|
+
(0, properties_1.defineReadOnly)(this, "quorum", quorum);
|
|
390
|
+
this._highestBlockNumber = -1;
|
|
391
|
+
}
|
|
392
|
+
async detectNetwork() {
|
|
393
|
+
const networks = await Promise.all(this.providerConfigs.map((c) => c.provider.getNetwork()));
|
|
394
|
+
return checkNetworks(networks);
|
|
476
395
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
396
|
+
async perform(method, params) {
|
|
397
|
+
// Sending transactions is special; always broadcast it to all backends
|
|
398
|
+
if (method === "sendTransaction") {
|
|
399
|
+
const results = await Promise.all(this.providerConfigs.map((c) => {
|
|
400
|
+
return c.provider.sendTransaction(params.signedTransaction).then((result) => {
|
|
401
|
+
return result.hash;
|
|
402
|
+
}, (error) => {
|
|
403
|
+
return error;
|
|
404
|
+
});
|
|
405
|
+
}));
|
|
406
|
+
// Any success is good enough (other errors are likely "already seen" errors
|
|
407
|
+
for (let i = 0; i < results.length; i++) {
|
|
408
|
+
const result = results[i];
|
|
409
|
+
if (typeof (result) === "string") {
|
|
410
|
+
return result;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// They were all an error; pick the first error
|
|
414
|
+
throw results[0];
|
|
415
|
+
}
|
|
416
|
+
// We need to make sure we are in sync with our backends, so we need
|
|
417
|
+
// to know this before we can make a lot of calls
|
|
418
|
+
if (this._highestBlockNumber === -1 && method !== "getBlockNumber") {
|
|
419
|
+
await this.getBlockNumber();
|
|
420
|
+
}
|
|
421
|
+
const processFunc = getProcessFunc(this, method, params);
|
|
422
|
+
// Shuffle the providers and then sort them by their priority; we
|
|
423
|
+
// shallowCopy them since we will store the result in them too
|
|
424
|
+
const configs = (0, random_1.shuffled)(this.providerConfigs.map(properties_1.shallowCopy));
|
|
425
|
+
configs.sort((a, b) => (a.priority - b.priority));
|
|
426
|
+
const currentBlockNumber = this._highestBlockNumber;
|
|
427
|
+
let i = 0;
|
|
428
|
+
let first = true;
|
|
429
|
+
while (true) {
|
|
430
|
+
const t0 = now();
|
|
431
|
+
// Compute the inflight weight (exclude anything past)
|
|
432
|
+
let inflightWeight = configs.filter((c) => (c.runner && ((t0 - c.start) < c.stallTimeout)))
|
|
433
|
+
.reduce((accum, c) => (accum + c.weight), 0);
|
|
434
|
+
// Start running enough to meet quorum
|
|
435
|
+
while (inflightWeight < this.quorum && i < configs.length) {
|
|
436
|
+
const config = configs[i++];
|
|
437
|
+
const rid = nextRid++;
|
|
438
|
+
config.start = now();
|
|
439
|
+
config.staller = stall(config.stallTimeout);
|
|
440
|
+
config.staller.wait(() => { config.staller = null; });
|
|
441
|
+
config.runner = getRunner(config, currentBlockNumber, method, params).then((result) => {
|
|
442
|
+
config.done = true;
|
|
443
|
+
config.result = result;
|
|
444
|
+
if (this.listenerCount("debug")) {
|
|
445
|
+
this.emit("debug", {
|
|
446
|
+
action: "request",
|
|
447
|
+
rid: rid,
|
|
448
|
+
backend: exposeDebugConfig(config, now()),
|
|
449
|
+
request: { method: method, params: (0, properties_1.deepCopy)(params) },
|
|
450
|
+
provider: this
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
}, (error) => {
|
|
454
|
+
config.done = true;
|
|
455
|
+
config.error = error;
|
|
456
|
+
if (this.listenerCount("debug")) {
|
|
457
|
+
this.emit("debug", {
|
|
458
|
+
action: "request",
|
|
459
|
+
rid: rid,
|
|
460
|
+
backend: exposeDebugConfig(config, now()),
|
|
461
|
+
request: { method: method, params: (0, properties_1.deepCopy)(params) },
|
|
462
|
+
provider: this
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
if (this.listenerCount("debug")) {
|
|
467
|
+
this.emit("debug", {
|
|
468
|
+
action: "request",
|
|
469
|
+
rid: rid,
|
|
470
|
+
backend: exposeDebugConfig(config, null),
|
|
471
|
+
request: { method: method, params: (0, properties_1.deepCopy)(params) },
|
|
472
|
+
provider: this
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
inflightWeight += config.weight;
|
|
476
|
+
}
|
|
477
|
+
// Wait for anything meaningful to finish or stall out
|
|
478
|
+
const waiting = [];
|
|
479
|
+
configs.forEach((c) => {
|
|
480
|
+
if (c.done || !c.runner) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
waiting.push(c.runner);
|
|
484
|
+
if (c.staller) {
|
|
485
|
+
waiting.push(c.staller.getPromise());
|
|
486
486
|
}
|
|
487
487
|
});
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
}, function (error) {
|
|
502
|
-
return error;
|
|
503
|
-
});
|
|
504
|
-
}))];
|
|
505
|
-
case 1:
|
|
506
|
-
results = _a.sent();
|
|
507
|
-
// Any success is good enough (other errors are likely "already seen" errors
|
|
508
|
-
for (i_1 = 0; i_1 < results.length; i_1++) {
|
|
509
|
-
result = results[i_1];
|
|
510
|
-
if (typeof (result) === "string") {
|
|
511
|
-
return [2 /*return*/, result];
|
|
512
|
-
}
|
|
488
|
+
if (waiting.length) {
|
|
489
|
+
await Promise.race(waiting);
|
|
490
|
+
}
|
|
491
|
+
// Check the quorum and process the results; the process function
|
|
492
|
+
// may additionally decide the quorum is not met
|
|
493
|
+
const results = configs.filter((c) => (c.done && c.error == null));
|
|
494
|
+
if (results.length >= this.quorum) {
|
|
495
|
+
const result = processFunc(results);
|
|
496
|
+
if (result !== undefined) {
|
|
497
|
+
// Shut down any stallers
|
|
498
|
+
configs.forEach(c => {
|
|
499
|
+
if (c.staller) {
|
|
500
|
+
c.staller.cancel();
|
|
513
501
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
i = 0;
|
|
528
|
-
first = true;
|
|
529
|
-
_loop_1 = function () {
|
|
530
|
-
var t0, inflightWeight, _loop_2, waiting, results, result, errors;
|
|
531
|
-
return __generator(this, function (_b) {
|
|
532
|
-
switch (_b.label) {
|
|
533
|
-
case 0:
|
|
534
|
-
t0 = now();
|
|
535
|
-
inflightWeight = configs.filter(function (c) { return (c.runner && ((t0 - c.start) < c.stallTimeout)); })
|
|
536
|
-
.reduce(function (accum, c) { return (accum + c.weight); }, 0);
|
|
537
|
-
_loop_2 = function () {
|
|
538
|
-
var config = configs[i++];
|
|
539
|
-
var rid = nextRid++;
|
|
540
|
-
config.start = now();
|
|
541
|
-
config.staller = stall(config.stallTimeout);
|
|
542
|
-
config.staller.wait(function () { config.staller = null; });
|
|
543
|
-
config.runner = getRunner(config, currentBlockNumber, method, params).then(function (result) {
|
|
544
|
-
config.done = true;
|
|
545
|
-
config.result = result;
|
|
546
|
-
if (_this.listenerCount("debug")) {
|
|
547
|
-
_this.emit("debug", {
|
|
548
|
-
action: "request",
|
|
549
|
-
rid: rid,
|
|
550
|
-
backend: exposeDebugConfig(config, now()),
|
|
551
|
-
request: { method: method, params: (0, properties_1.deepCopy)(params) },
|
|
552
|
-
provider: _this
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
}, function (error) {
|
|
556
|
-
config.done = true;
|
|
557
|
-
config.error = error;
|
|
558
|
-
if (_this.listenerCount("debug")) {
|
|
559
|
-
_this.emit("debug", {
|
|
560
|
-
action: "request",
|
|
561
|
-
rid: rid,
|
|
562
|
-
backend: exposeDebugConfig(config, now()),
|
|
563
|
-
request: { method: method, params: (0, properties_1.deepCopy)(params) },
|
|
564
|
-
provider: _this
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
});
|
|
568
|
-
if (this_1.listenerCount("debug")) {
|
|
569
|
-
this_1.emit("debug", {
|
|
570
|
-
action: "request",
|
|
571
|
-
rid: rid,
|
|
572
|
-
backend: exposeDebugConfig(config, null),
|
|
573
|
-
request: { method: method, params: (0, properties_1.deepCopy)(params) },
|
|
574
|
-
provider: this_1
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
inflightWeight += config.weight;
|
|
578
|
-
};
|
|
579
|
-
// Start running enough to meet quorum
|
|
580
|
-
while (inflightWeight < this_1.quorum && i < configs.length) {
|
|
581
|
-
_loop_2();
|
|
582
|
-
}
|
|
583
|
-
waiting = [];
|
|
584
|
-
configs.forEach(function (c) {
|
|
585
|
-
if (c.done || !c.runner) {
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
waiting.push(c.runner);
|
|
589
|
-
if (c.staller) {
|
|
590
|
-
waiting.push(c.staller.getPromise());
|
|
591
|
-
}
|
|
592
|
-
});
|
|
593
|
-
if (!waiting.length) return [3 /*break*/, 2];
|
|
594
|
-
return [4 /*yield*/, Promise.race(waiting)];
|
|
595
|
-
case 1:
|
|
596
|
-
_b.sent();
|
|
597
|
-
_b.label = 2;
|
|
598
|
-
case 2:
|
|
599
|
-
results = configs.filter(function (c) { return (c.done && c.error == null); });
|
|
600
|
-
if (!(results.length >= this_1.quorum)) return [3 /*break*/, 5];
|
|
601
|
-
result = processFunc(results);
|
|
602
|
-
if (result !== undefined) {
|
|
603
|
-
// Shut down any stallers
|
|
604
|
-
configs.forEach(function (c) {
|
|
605
|
-
if (c.staller) {
|
|
606
|
-
c.staller.cancel();
|
|
607
|
-
}
|
|
608
|
-
c.cancelled = true;
|
|
609
|
-
});
|
|
610
|
-
return [2 /*return*/, { value: result }];
|
|
611
|
-
}
|
|
612
|
-
if (!!first) return [3 /*break*/, 4];
|
|
613
|
-
return [4 /*yield*/, stall(100).getPromise()];
|
|
614
|
-
case 3:
|
|
615
|
-
_b.sent();
|
|
616
|
-
_b.label = 4;
|
|
617
|
-
case 4:
|
|
618
|
-
first = false;
|
|
619
|
-
_b.label = 5;
|
|
620
|
-
case 5:
|
|
621
|
-
errors = configs.reduce(function (accum, c) {
|
|
622
|
-
if (!c.done || c.error == null) {
|
|
623
|
-
return accum;
|
|
624
|
-
}
|
|
625
|
-
var code = (c.error).code;
|
|
626
|
-
if (ForwardErrors.indexOf(code) >= 0) {
|
|
627
|
-
if (!accum[code]) {
|
|
628
|
-
accum[code] = { error: c.error, weight: 0 };
|
|
629
|
-
}
|
|
630
|
-
accum[code].weight += c.weight;
|
|
631
|
-
}
|
|
632
|
-
return accum;
|
|
633
|
-
}, ({}));
|
|
634
|
-
Object.keys(errors).forEach(function (errorCode) {
|
|
635
|
-
var tally = errors[errorCode];
|
|
636
|
-
if (tally.weight < _this.quorum) {
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
// Shut down any stallers
|
|
640
|
-
configs.forEach(function (c) {
|
|
641
|
-
if (c.staller) {
|
|
642
|
-
c.staller.cancel();
|
|
643
|
-
}
|
|
644
|
-
c.cancelled = true;
|
|
645
|
-
});
|
|
646
|
-
var e = (tally.error);
|
|
647
|
-
var props = {};
|
|
648
|
-
ForwardProperties.forEach(function (name) {
|
|
649
|
-
if (e[name] == null) {
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
props[name] = e[name];
|
|
653
|
-
});
|
|
654
|
-
logger.throwError(e.reason || e.message, errorCode, props);
|
|
655
|
-
});
|
|
656
|
-
// All configs have run to completion; we will never get more data
|
|
657
|
-
if (configs.filter(function (c) { return !c.done; }).length === 0) {
|
|
658
|
-
return [2 /*return*/, "break"];
|
|
659
|
-
}
|
|
660
|
-
return [2 /*return*/];
|
|
661
|
-
}
|
|
662
|
-
});
|
|
663
|
-
};
|
|
664
|
-
this_1 = this;
|
|
665
|
-
_a.label = 5;
|
|
666
|
-
case 5:
|
|
667
|
-
if (!true) return [3 /*break*/, 7];
|
|
668
|
-
return [5 /*yield**/, _loop_1()];
|
|
669
|
-
case 6:
|
|
670
|
-
state_1 = _a.sent();
|
|
671
|
-
if (typeof state_1 === "object")
|
|
672
|
-
return [2 /*return*/, state_1.value];
|
|
673
|
-
if (state_1 === "break")
|
|
674
|
-
return [3 /*break*/, 7];
|
|
675
|
-
return [3 /*break*/, 5];
|
|
676
|
-
case 7:
|
|
677
|
-
// Shut down any stallers; shouldn't be any
|
|
678
|
-
configs.forEach(function (c) {
|
|
679
|
-
if (c.staller) {
|
|
680
|
-
c.staller.cancel();
|
|
681
|
-
}
|
|
682
|
-
c.cancelled = true;
|
|
683
|
-
});
|
|
684
|
-
return [2 /*return*/, logger.throwError("failed to meet quorum", logger_1.Logger.errors.SERVER_ERROR, {
|
|
685
|
-
method: method,
|
|
686
|
-
params: params,
|
|
687
|
-
//results: configs.map((c) => c.result),
|
|
688
|
-
//errors: configs.map((c) => c.error),
|
|
689
|
-
results: configs.map(function (c) { return exposeDebugConfig(c); }),
|
|
690
|
-
provider: this
|
|
691
|
-
})];
|
|
502
|
+
c.cancelled = true;
|
|
503
|
+
});
|
|
504
|
+
return result;
|
|
505
|
+
}
|
|
506
|
+
if (!first) {
|
|
507
|
+
await stall(100).getPromise();
|
|
508
|
+
}
|
|
509
|
+
first = false;
|
|
510
|
+
}
|
|
511
|
+
// No result, check for errors that should be forwarded
|
|
512
|
+
const errors = configs.reduce((accum, c) => {
|
|
513
|
+
if (!c.done || c.error == null) {
|
|
514
|
+
return accum;
|
|
692
515
|
}
|
|
516
|
+
const code = (c.error).code;
|
|
517
|
+
if (ForwardErrors.indexOf(code) >= 0) {
|
|
518
|
+
if (!accum[code]) {
|
|
519
|
+
accum[code] = { error: c.error, weight: 0 };
|
|
520
|
+
}
|
|
521
|
+
accum[code].weight += c.weight;
|
|
522
|
+
}
|
|
523
|
+
return accum;
|
|
524
|
+
}, ({}));
|
|
525
|
+
Object.keys(errors).forEach((errorCode) => {
|
|
526
|
+
const tally = errors[errorCode];
|
|
527
|
+
if (tally.weight < this.quorum) {
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
// Shut down any stallers
|
|
531
|
+
configs.forEach(c => {
|
|
532
|
+
if (c.staller) {
|
|
533
|
+
c.staller.cancel();
|
|
534
|
+
}
|
|
535
|
+
c.cancelled = true;
|
|
536
|
+
});
|
|
537
|
+
const e = (tally.error);
|
|
538
|
+
const props = {};
|
|
539
|
+
ForwardProperties.forEach((name) => {
|
|
540
|
+
if (e[name] == null) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
props[name] = e[name];
|
|
544
|
+
});
|
|
545
|
+
logger.throwError(e.reason || e.message, errorCode, props);
|
|
693
546
|
});
|
|
547
|
+
// All configs have run to completion; we will never get more data
|
|
548
|
+
if (configs.filter((c) => !c.done).length === 0) {
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
// Shut down any stallers; shouldn't be any
|
|
553
|
+
configs.forEach(c => {
|
|
554
|
+
if (c.staller) {
|
|
555
|
+
c.staller.cancel();
|
|
556
|
+
}
|
|
557
|
+
c.cancelled = true;
|
|
694
558
|
});
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
559
|
+
return logger.throwError("failed to meet quorum", logger_1.Logger.errors.SERVER_ERROR, {
|
|
560
|
+
method: method,
|
|
561
|
+
params: params,
|
|
562
|
+
//results: configs.map((c) => c.result),
|
|
563
|
+
//errors: configs.map((c) => c.error),
|
|
564
|
+
results: configs.map((c) => exposeDebugConfig(c)),
|
|
565
|
+
provider: this
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}
|
|
698
569
|
exports.FallbackProvider = FallbackProvider;
|
|
699
570
|
//# sourceMappingURL=fallback-provider.js.map
|