Added timeout to waitForTransaction (#477).
This commit is contained in:
parent
8eb0190d5e
commit
bacc440397
@ -259,7 +259,7 @@ export abstract class Provider implements OnceBlockable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: This *could* be implemented here, but would pull in events...
|
// @TODO: This *could* be implemented here, but would pull in events...
|
||||||
abstract waitForTransaction(transactionHash: string, timeout?: number): Promise<TransactionReceipt>;
|
abstract waitForTransaction(transactionHash: string, confirmations?: number, timeout?: number): Promise<TransactionReceipt>;
|
||||||
|
|
||||||
readonly _isProvider: boolean;
|
readonly _isProvider: boolean;
|
||||||
|
|
||||||
|
@ -193,7 +193,8 @@ export class Logger {
|
|||||||
messageDetails.push(key + "=" + JSON.stringify(params[key].toString()));
|
messageDetails.push(key + "=" + JSON.stringify(params[key].toString()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
messageDetails.push("version=" + this.version);
|
messageDetails.push(`code=${ code }`);
|
||||||
|
messageDetails.push(`version=${ this.version }`);
|
||||||
|
|
||||||
const reason = message;
|
const reason = message;
|
||||||
if (messageDetails.length) {
|
if (messageDetails.length) {
|
||||||
|
@ -444,22 +444,42 @@ export class BaseProvider extends Provider {
|
|||||||
// @TODO: Add .poller which must be an event emitter with a 'start', 'stop' and 'block' event;
|
// @TODO: Add .poller which must be an event emitter with a 'start', 'stop' and 'block' event;
|
||||||
// this will be used once we move to the WebSocket or other alternatives to polling
|
// this will be used once we move to the WebSocket or other alternatives to polling
|
||||||
|
|
||||||
async waitForTransaction(transactionHash: string, confirmations?: number): Promise<TransactionReceipt> {
|
async waitForTransaction(transactionHash: string, confirmations?: number, timeout?: number): Promise<TransactionReceipt> {
|
||||||
if (confirmations == null) { confirmations = 1; }
|
if (confirmations == null) { confirmations = 1; }
|
||||||
|
|
||||||
const receipt = await this.getTransactionReceipt(transactionHash);
|
const receipt = await this.getTransactionReceipt(transactionHash);
|
||||||
|
|
||||||
// Receipt is already good
|
// Receipt is already good
|
||||||
if (receipt.confirmations >= confirmations) { return receipt; }
|
if ((receipt ? receipt.confirmations: 0) >= confirmations) { return receipt; }
|
||||||
|
|
||||||
// Poll until the receipt is good...
|
// Poll until the receipt is good...
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
let timer: NodeJS.Timer = null;
|
||||||
|
let done = false;
|
||||||
|
|
||||||
const handler = (receipt: TransactionReceipt) => {
|
const handler = (receipt: TransactionReceipt) => {
|
||||||
if (receipt.confirmations < confirmations) { return; }
|
if (receipt.confirmations < confirmations) { return; }
|
||||||
|
|
||||||
|
if (timer) { clearTimeout(timer); }
|
||||||
|
if (done) { return; }
|
||||||
|
done = true;
|
||||||
|
|
||||||
this.removeListener(transactionHash, handler);
|
this.removeListener(transactionHash, handler);
|
||||||
resolve(receipt);
|
resolve(receipt);
|
||||||
}
|
}
|
||||||
this.on(transactionHash, handler);
|
this.on(transactionHash, handler);
|
||||||
|
|
||||||
|
if (typeof(timeout) === "number" && timeout > 0) {
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
if (done) { return; }
|
||||||
|
timer = null;
|
||||||
|
done = true;
|
||||||
|
|
||||||
|
this.removeListener(transactionHash, handler);
|
||||||
|
reject(logger.makeError("timeout exceeded", Logger.errors.TIMEOUT, { timeout: timeout }));
|
||||||
|
}, timeout);
|
||||||
|
if (timer.unref) { timer.unref(); }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import { Network } from "@ethersproject/networks";
|
import { Network } from "@ethersproject/networks";
|
||||||
import { BlockWithTransactions, Provider } from "@ethersproject/abstract-provider";
|
import { Block, BlockWithTransactions, Provider } from "@ethersproject/abstract-provider";
|
||||||
import { shuffled } from "@ethersproject/random";
|
import { shuffled } from "@ethersproject/random";
|
||||||
import { deepCopy, defineReadOnly, shallowCopy } from "@ethersproject/properties";
|
import { deepCopy, defineReadOnly, shallowCopy } from "@ethersproject/properties";
|
||||||
import { BigNumber } from "@ethersproject/bignumber";
|
import { BigNumber } from "@ethersproject/bignumber";
|
||||||
@ -56,7 +56,7 @@ function median(values: Array<number>): number {
|
|||||||
|
|
||||||
function serialize(value: any): string {
|
function serialize(value: any): string {
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
return null;
|
return "null";
|
||||||
} else if (typeof(value) === "number" || typeof(value) === "boolean") {
|
} else if (typeof(value) === "number" || typeof(value) === "boolean") {
|
||||||
return JSON.stringify(value);
|
return JSON.stringify(value);
|
||||||
} else if (typeof(value) === "string") {
|
} else if (typeof(value) === "string") {
|
||||||
@ -222,6 +222,8 @@ function getProcessFunc(provider: FallbackProvider, method: string, params: { [
|
|||||||
case "getTransaction":
|
case "getTransaction":
|
||||||
case "getTransactionReceipt":
|
case "getTransactionReceipt":
|
||||||
normalize = function(tx: any): string {
|
normalize = function(tx: any): string {
|
||||||
|
if (tx == null) { return null; }
|
||||||
|
|
||||||
tx = shallowCopy(tx);
|
tx = shallowCopy(tx);
|
||||||
tx.confirmations = -1;
|
tx.confirmations = -1;
|
||||||
return serialize(tx);
|
return serialize(tx);
|
||||||
@ -233,6 +235,8 @@ function getProcessFunc(provider: FallbackProvider, method: string, params: { [
|
|||||||
// We drop the confirmations from transactions as it is approximate
|
// We drop the confirmations from transactions as it is approximate
|
||||||
if (params.includeTransactions) {
|
if (params.includeTransactions) {
|
||||||
normalize = function(block: BlockWithTransactions): string {
|
normalize = function(block: BlockWithTransactions): string {
|
||||||
|
if (block == null) { return null; }
|
||||||
|
|
||||||
block = shallowCopy(block);
|
block = shallowCopy(block);
|
||||||
block.transactions = block.transactions.map((tx) => {
|
block.transactions = block.transactions.map((tx) => {
|
||||||
tx = shallowCopy(tx);
|
tx = shallowCopy(tx);
|
||||||
@ -241,6 +245,11 @@ function getProcessFunc(provider: FallbackProvider, method: string, params: { [
|
|||||||
});
|
});
|
||||||
return serialize(block);
|
return serialize(block);
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
normalize = function(block: Block): string {
|
||||||
|
if (block == null) { return null; }
|
||||||
|
return serialize(block);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -460,7 +469,7 @@ export class FallbackProvider extends BaseProvider {
|
|||||||
const results = configs.filter((c) => (c.done && c.error == null));
|
const results = configs.filter((c) => (c.done && c.error == null));
|
||||||
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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// All configs have run to completion; we will never get more data
|
// All configs have run to completion; we will never get more data
|
||||||
@ -470,8 +479,9 @@ export class FallbackProvider extends BaseProvider {
|
|||||||
return logger.throwError("failed to meet quorum", Logger.errors.SERVER_ERROR, {
|
return logger.throwError("failed to meet quorum", Logger.errors.SERVER_ERROR, {
|
||||||
method: method,
|
method: method,
|
||||||
params: params,
|
params: params,
|
||||||
results: configs.map((c) => exposeDebugConfig(c)),
|
//results: configs.map((c) => c.result),
|
||||||
//errors: configs.map((c) => c.error),
|
//errors: configs.map((c) => c.error),
|
||||||
|
results: configs.map((c) => exposeDebugConfig(c)),
|
||||||
provider: this
|
provider: this
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user