Skip to content

Commit 89015a7

Browse files
committed
Try new ExtendedNonceManager
1 parent e1eeddd commit 89015a7

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

packages/package-utils/ExtendedNonceManager.js

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const { NonceManager } = require("@ethersproject/experimental");
2+
const { parseTransaction } = require("ethers/lib/utils");
23

34
class ExtendedNonceManager extends NonceManager {
45
constructor(signer) {
@@ -9,8 +10,23 @@ class ExtendedNonceManager extends NonceManager {
910
Object.keys(this.signedTransactions).map(async (txHash) => {
1011
const nodeTx = await this.signer.provider.getTransaction(txHash);
1112
if (!nodeTx) {
12-
this.signer.provider.sendTransaction(this.signedTransactions[txHash]);
13-
return;
13+
const txCount = await this.signer.getTransactionCount("pending");
14+
const parsedTransaction = parseTransaction(this.signedTransactions[txHash]);
15+
if (parsedTransaction.nonce < txCount) {
16+
// It's not been mined, but it's been replaced by another tx.
17+
// Resend, with a new nonce
18+
delete this.signedTransactions[txHash];
19+
this.sendTransaction({
20+
from: parsedTransaction.from,
21+
to: parsedTransaction.to,
22+
value: parsedTransaction.value,
23+
data: parsedTransaction.data,
24+
});
25+
} else {
26+
// No reason to think it's been replaced, so rebroadcast.
27+
this.signer.provider.sendTransaction(this.signedTransactions[txHash]);
28+
return;
29+
}
1430
}
1531
if (nodeTx.blockNumber) {
1632
// It's been mined, so forget it.
@@ -22,29 +38,18 @@ class ExtendedNonceManager extends NonceManager {
2238
}
2339

2440
async sendTransaction(transactionRequest) {
25-
// What nonce are we going to attach to this?
26-
// Definitely not any we've sent and are pending
27-
// const pendingNonces = Object.keys(this.signedTransactions).map((txhash) => this.signedTransactions[txhash].nonce);
28-
29-
// At least whatever the endpoint says, or whatever we've already sent if higher
30-
let nonce = await this.signer.getTransactionCount();
31-
32-
// Note the order we did the above two lines in - if a tx is mined between these two lines,
33-
// and got removed by the `on block` handler above, by doing it in this order we won't be tripped up
34-
// And we'll skip any nonces we've already used
35-
while (
36-
Object.keys(this.signedTransactions)
37-
.map((txhash) => this.signedTransactions[txhash].nonce)
38-
.includes(nonce)
39-
) {
40-
nonce += 1;
41+
try {
42+
const populatedTransaction = await this.populateTransaction(transactionRequest);
43+
const signedTransaction = await this.signTransaction(populatedTransaction);
44+
const response = super.sendTransaction(transactionRequest);
45+
const tx = await response;
46+
this.signedTransactions[tx.hash] = signedTransaction;
47+
return response;
48+
} catch (e) {
49+
const txCount = await this.signer.getTransactionCount("pending");
50+
this.setTransactionCount(txCount);
51+
return this.sendTransaction(transactionRequest);
4152
}
42-
transactionRequest.nonce = nonce; // eslint-disable-line no-param-reassign
43-
this.nonce = nonce + 1;
44-
const response = super.sendTransaction(transactionRequest);
45-
const tx = await response;
46-
this.signedTransactions[tx.hash] = transactionRequest;
47-
return response;
4853
}
4954
}
5055

0 commit comments

Comments
 (0)