Skip to content

Commit

Permalink
Added timeout to waitForTransaction (#477).
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmoo committed Feb 4, 2020
1 parent 8eb0190 commit bacc440
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/abstract-provider/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ export abstract class Provider implements OnceBlockable {
}

// @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;

Expand Down
3 changes: 2 additions & 1 deletion packages/logger/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ export class Logger {
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;
if (messageDetails.length) {
Expand Down
26 changes: 23 additions & 3 deletions packages/providers/src.ts/base-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
// 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; }

const receipt = await this.getTransactionReceipt(transactionHash);

// Receipt is already good
if (receipt.confirmations >= confirmations) { return receipt; }
if ((receipt ? receipt.confirmations: 0) >= confirmations) { return receipt; }

// 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) => {
if (receipt.confirmations < confirmations) { return; }

if (timer) { clearTimeout(timer); }
if (done) { return; }
done = true;

this.removeListener(transactionHash, handler);
resolve(receipt);
}
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(); }
}
});
}

Expand Down
18 changes: 14 additions & 4 deletions packages/providers/src.ts/fallback-provider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";

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 { deepCopy, defineReadOnly, shallowCopy } from "@ethersproject/properties";
import { BigNumber } from "@ethersproject/bignumber";
Expand Down Expand Up @@ -56,7 +56,7 @@ function median(values: Array<number>): number {

function serialize(value: any): string {
if (value === null) {
return null;
return "null";
} else if (typeof(value) === "number" || typeof(value) === "boolean") {
return JSON.stringify(value);
} else if (typeof(value) === "string") {
Expand Down Expand Up @@ -222,6 +222,8 @@ function getProcessFunc(provider: FallbackProvider, method: string, params: { [
case "getTransaction":
case "getTransactionReceipt":
normalize = function(tx: any): string {
if (tx == null) { return null; }

tx = shallowCopy(tx);
tx.confirmations = -1;
return serialize(tx);
Expand All @@ -233,6 +235,8 @@ function getProcessFunc(provider: FallbackProvider, method: string, params: { [
// We drop the confirmations from transactions as it is approximate
if (params.includeTransactions) {
normalize = function(block: BlockWithTransactions): string {
if (block == null) { return null; }

block = shallowCopy(block);
block.transactions = block.transactions.map((tx) => {
tx = shallowCopy(tx);
Expand All @@ -241,6 +245,11 @@ function getProcessFunc(provider: FallbackProvider, method: string, params: { [
});
return serialize(block);
};
} else {
normalize = function(block: Block): string {
if (block == null) { return null; }
return serialize(block);
}
}
break;

Expand Down Expand Up @@ -460,7 +469,7 @@ export class FallbackProvider extends BaseProvider {
const results = configs.filter((c) => (c.done && c.error == null));
if (results.length >= this.quorum) {
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
Expand All @@ -470,8 +479,9 @@ export class FallbackProvider extends BaseProvider {
return logger.throwError("failed to meet quorum", Logger.errors.SERVER_ERROR, {
method: method,
params: params,
results: configs.map((c) => exposeDebugConfig(c)),
//results: configs.map((c) => c.result),
//errors: configs.map((c) => c.error),
results: configs.map((c) => exposeDebugConfig(c)),
provider: this
});
}
Expand Down

0 comments on commit bacc440

Please sign in to comment.