hardhat 2.20.0 → 2.21.0-dev.0
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/internal/core/jsonrpc/types/input/blockTag.d.ts +3 -3
- package/internal/core/jsonrpc/types/input/filterRequest.d.ts +6 -6
- package/internal/core/providers/construction.d.ts.map +1 -1
- package/internal/core/providers/construction.js +28 -4
- package/internal/core/providers/construction.js.map +1 -1
- package/internal/core/providers/http.d.ts +2 -0
- package/internal/core/providers/http.d.ts.map +1 -1
- package/internal/core/providers/http.js +2 -1
- package/internal/core/providers/http.js.map +1 -1
- package/internal/core/runtime-environment.d.ts.map +1 -1
- package/internal/core/runtime-environment.js.map +1 -1
- package/internal/hardhat-network/jsonrpc/client.d.ts +0 -2
- package/internal/hardhat-network/jsonrpc/client.d.ts.map +1 -1
- package/internal/hardhat-network/jsonrpc/client.js +0 -16
- package/internal/hardhat-network/jsonrpc/client.js.map +1 -1
- package/internal/hardhat-network/jsonrpc/handler.js +9 -1
- package/internal/hardhat-network/jsonrpc/handler.js.map +1 -1
- package/internal/hardhat-network/provider/BlockchainData.d.ts +5 -5
- package/internal/hardhat-network/provider/BlockchainData.d.ts.map +1 -1
- package/internal/hardhat-network/provider/BlockchainData.js +10 -10
- package/internal/hardhat-network/provider/BlockchainData.js.map +1 -1
- package/internal/hardhat-network/provider/HardhatBlockchain.d.ts +0 -7
- package/internal/hardhat-network/provider/HardhatBlockchain.d.ts.map +1 -1
- package/internal/hardhat-network/provider/HardhatBlockchain.js +2 -14
- package/internal/hardhat-network/provider/HardhatBlockchain.js.map +1 -1
- package/internal/hardhat-network/provider/TxPool.d.ts +3 -2
- package/internal/hardhat-network/provider/TxPool.d.ts.map +1 -1
- package/internal/hardhat-network/provider/TxPool.js +16 -16
- package/internal/hardhat-network/provider/TxPool.js.map +1 -1
- package/internal/hardhat-network/provider/ethereumjs-workarounds.js +1 -1
- package/internal/hardhat-network/provider/ethereumjs-workarounds.js.map +1 -1
- package/internal/hardhat-network/provider/filter.d.ts +6 -5
- package/internal/hardhat-network/provider/filter.d.ts.map +1 -1
- package/internal/hardhat-network/provider/filter.js +2 -2
- package/internal/hardhat-network/provider/filter.js.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts +0 -7
- package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js +4 -21
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkStateManager.d.ts +13 -19
- package/internal/hardhat-network/provider/fork/ForkStateManager.d.ts.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkStateManager.js +61 -59
- package/internal/hardhat-network/provider/fork/ForkStateManager.js.map +1 -1
- package/internal/hardhat-network/provider/fork/rpcToBlockData.d.ts.map +1 -1
- package/internal/hardhat-network/provider/fork/rpcToBlockData.js +0 -3
- package/internal/hardhat-network/provider/fork/rpcToBlockData.js.map +1 -1
- package/internal/hardhat-network/provider/fork/rpcToTxData.d.ts +2 -2
- package/internal/hardhat-network/provider/fork/rpcToTxData.d.ts.map +1 -1
- package/internal/hardhat-network/provider/fork/rpcToTxData.js +1 -1
- package/internal/hardhat-network/provider/fork/rpcToTxData.js.map +1 -1
- package/internal/hardhat-network/provider/modules/base.js +4 -4
- package/internal/hardhat-network/provider/modules/base.js.map +1 -1
- package/internal/hardhat-network/provider/modules/eth.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/eth.js +9 -16
- package/internal/hardhat-network/provider/modules/eth.js.map +1 -1
- package/internal/hardhat-network/provider/modules/logger.d.ts +6 -84
- package/internal/hardhat-network/provider/modules/logger.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/logger.js +3 -530
- package/internal/hardhat-network/provider/modules/logger.js.map +1 -1
- package/internal/hardhat-network/provider/node-types.d.ts +2 -65
- package/internal/hardhat-network/provider/node-types.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node-types.js +0 -5
- package/internal/hardhat-network/provider/node-types.js.map +1 -1
- package/internal/hardhat-network/provider/node.d.ts +2 -6
- package/internal/hardhat-network/provider/node.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node.js +79 -148
- package/internal/hardhat-network/provider/node.js.map +1 -1
- package/internal/hardhat-network/provider/output.d.ts +0 -14
- package/internal/hardhat-network/provider/output.d.ts.map +1 -1
- package/internal/hardhat-network/provider/output.js +0 -264
- package/internal/hardhat-network/provider/output.js.map +1 -1
- package/internal/hardhat-network/provider/provider.d.ts +26 -25
- package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
- package/internal/hardhat-network/provider/provider.js +342 -186
- package/internal/hardhat-network/provider/provider.js.map +1 -1
- package/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.d.ts +10 -8
- package/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.d.ts.map +1 -1
- package/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.js +9 -9
- package/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.js.map +1 -1
- package/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.d.ts +10 -8
- package/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.d.ts.map +1 -1
- package/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.js +9 -9
- package/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.js.map +1 -1
- package/internal/hardhat-network/provider/transactions/FakeSenderTransaction.d.ts +10 -9
- package/internal/hardhat-network/provider/transactions/FakeSenderTransaction.d.ts.map +1 -1
- package/internal/hardhat-network/provider/transactions/FakeSenderTransaction.js +7 -6
- package/internal/hardhat-network/provider/transactions/FakeSenderTransaction.js.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.d.ts +6 -5
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.d.ts.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.js +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.js.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.d.ts +5 -4
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.d.ts.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.js +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.js.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.d.ts +8 -7
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.d.ts.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.js +2 -2
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.js.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.d.ts +8 -7
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.d.ts.map +1 -1
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.js +2 -2
- package/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.js.map +1 -1
- package/internal/hardhat-network/provider/types/HardhatBlockchainInterface.d.ts +5 -4
- package/internal/hardhat-network/provider/types/HardhatBlockchainInterface.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/convertToEdr.d.ts +14 -0
- package/internal/hardhat-network/provider/utils/convertToEdr.d.ts.map +1 -0
- package/internal/hardhat-network/provider/utils/convertToEdr.js +191 -0
- package/internal/hardhat-network/provider/utils/convertToEdr.js.map +1 -0
- package/internal/hardhat-network/provider/utils/getCurrentTimestamp.d.ts +0 -1
- package/internal/hardhat-network/provider/utils/getCurrentTimestamp.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/getCurrentTimestamp.js +1 -5
- package/internal/hardhat-network/provider/utils/getCurrentTimestamp.js.map +1 -1
- package/internal/hardhat-network/provider/utils/makeCommon.d.ts +1 -1
- package/internal/hardhat-network/provider/utils/makeCommon.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/makeCommon.js +1 -3
- package/internal/hardhat-network/provider/utils/makeCommon.js.map +1 -1
- package/internal/hardhat-network/provider/utils/makeFakeSignature.d.ts +2 -2
- package/internal/hardhat-network/provider/utils/makeFakeSignature.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/makeFakeSignature.js +1 -15
- package/internal/hardhat-network/provider/utils/makeFakeSignature.js.map +1 -1
- package/internal/hardhat-network/provider/utils/makeForkClient.d.ts +10 -1
- package/internal/hardhat-network/provider/utils/makeForkClient.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/makeForkClient.js +38 -18
- package/internal/hardhat-network/provider/utils/makeForkClient.js.map +1 -1
- package/internal/hardhat-network/provider/utils/makeStateTrie.js +2 -2
- package/internal/hardhat-network/provider/utils/makeStateTrie.js.map +1 -1
- package/internal/hardhat-network/provider/utils/putGenesisBlock.d.ts +3 -1
- package/internal/hardhat-network/provider/utils/putGenesisBlock.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/putGenesisBlock.js +2 -6
- package/internal/hardhat-network/provider/utils/putGenesisBlock.js.map +1 -1
- package/internal/hardhat-network/provider/utils/random.d.ts +1 -0
- package/internal/hardhat-network/provider/utils/random.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/random.js +7 -1
- package/internal/hardhat-network/provider/utils/random.js.map +1 -1
- package/internal/hardhat-network/provider/utils/reorgs-protection.d.ts +1 -1
- package/internal/hardhat-network/provider/utils/reorgs-protection.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/reorgs-protection.js +5 -5
- package/internal/hardhat-network/provider/utils/reorgs-protection.js.map +1 -1
- package/internal/hardhat-network/provider/vm/exit.d.ts +22 -0
- package/internal/hardhat-network/provider/vm/exit.d.ts.map +1 -0
- package/internal/hardhat-network/provider/vm/exit.js +93 -0
- package/internal/hardhat-network/provider/vm/exit.js.map +1 -0
- package/internal/hardhat-network/provider/vm/minimal-vm.d.ts +29 -0
- package/internal/hardhat-network/provider/vm/minimal-vm.d.ts.map +1 -0
- package/internal/hardhat-network/provider/vm/minimal-vm.js +46 -0
- package/internal/hardhat-network/provider/vm/minimal-vm.js.map +1 -0
- package/internal/hardhat-network/provider/vm/proxy-vm.d.ts +36 -0
- package/internal/hardhat-network/provider/vm/proxy-vm.d.ts.map +1 -0
- package/internal/hardhat-network/provider/vm/proxy-vm.js +73 -0
- package/internal/hardhat-network/provider/vm/proxy-vm.js.map +1 -0
- package/internal/hardhat-network/provider/vm/types.d.ts +27 -0
- package/internal/hardhat-network/provider/vm/types.d.ts.map +1 -0
- package/internal/hardhat-network/provider/vm/types.js +3 -0
- package/internal/hardhat-network/provider/vm/types.js.map +1 -0
- package/internal/hardhat-network/stack-traces/consoleLogger.d.ts +6 -0
- package/internal/hardhat-network/stack-traces/consoleLogger.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/consoleLogger.js +33 -16
- package/internal/hardhat-network/stack-traces/consoleLogger.js.map +1 -1
- package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts +1 -2
- package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/contracts-identifier.js +6 -7
- package/internal/hardhat-network/stack-traces/contracts-identifier.js.map +1 -1
- package/internal/hardhat-network/stack-traces/debug.js +6 -6
- package/internal/hardhat-network/stack-traces/debug.js.map +1 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.js +13 -7
- package/internal/hardhat-network/stack-traces/error-inferrer.js.map +1 -1
- package/internal/hardhat-network/stack-traces/message-trace.d.ts +8 -3
- package/internal/hardhat-network/stack-traces/message-trace.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/message-trace.js +22 -1
- package/internal/hardhat-network/stack-traces/message-trace.js.map +1 -1
- package/internal/hardhat-network/stack-traces/model.d.ts +8 -0
- package/internal/hardhat-network/stack-traces/model.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/model.js +52 -0
- package/internal/hardhat-network/stack-traces/model.js.map +1 -1
- package/internal/hardhat-network/stack-traces/opcodes.d.ts +1 -0
- package/internal/hardhat-network/stack-traces/opcodes.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/opcodes.js +5 -1
- package/internal/hardhat-network/stack-traces/opcodes.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.js +2 -2
- package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidityTracer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/solidityTracer.js +5 -5
- package/internal/hardhat-network/stack-traces/solidityTracer.js.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-debug-tracer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-debug-tracer.js +28 -34
- package/internal/hardhat-network/stack-traces/vm-debug-tracer.js.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts +7 -0
- package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-trace-decoder.js +69 -2
- package/internal/hardhat-network/stack-traces/vm-trace-decoder.js.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-tracer.d.ts +7 -12
- package/internal/hardhat-network/stack-traces/vm-tracer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-tracer.js +46 -65
- package/internal/hardhat-network/stack-traces/vm-tracer.js.map +1 -1
- package/internal/util/date.d.ts +1 -0
- package/internal/util/date.d.ts.map +1 -1
- package/internal/util/date.js +5 -1
- package/internal/util/date.js.map +1 -1
- package/internal/util/hardforks.d.ts +2 -0
- package/internal/util/hardforks.d.ts.map +1 -1
- package/internal/util/hardforks.js +27 -1
- package/internal/util/hardforks.js.map +1 -1
- package/package.json +18 -16
- package/src/internal/core/providers/construction.ts +7 -9
- package/src/internal/core/providers/http.ts +3 -1
- package/src/internal/core/runtime-environment.ts +2 -1
- package/src/internal/hardhat-network/jsonrpc/client.ts +1 -28
- package/src/internal/hardhat-network/jsonrpc/handler.ts +9 -1
- package/src/internal/hardhat-network/provider/modules/logger.ts +6 -801
- package/src/internal/hardhat-network/provider/node-types.ts +2 -89
- package/src/internal/hardhat-network/provider/output.ts +0 -352
- package/src/internal/hardhat-network/provider/provider.ts +482 -263
- package/src/internal/hardhat-network/provider/utils/convertToEdr.ts +228 -0
- package/src/internal/hardhat-network/provider/utils/getCurrentTimestamp.ts +0 -4
- package/src/internal/hardhat-network/provider/utils/makeCommon.ts +1 -12
- package/src/internal/hardhat-network/provider/utils/makeForkClient.ts +63 -24
- package/src/internal/hardhat-network/provider/utils/random.ts +8 -1
- package/src/internal/hardhat-network/provider/utils/reorgs-protection.ts +5 -5
- package/src/internal/hardhat-network/provider/vm/exit.ts +101 -0
- package/src/internal/hardhat-network/provider/vm/minimal-vm.ts +101 -0
- package/src/internal/hardhat-network/provider/vm/types.ts +31 -0
- package/src/internal/hardhat-network/stack-traces/consoleLogger.ts +40 -21
- package/src/internal/hardhat-network/stack-traces/contracts-identifier.ts +10 -12
- package/src/internal/hardhat-network/stack-traces/debug.ts +6 -6
- package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +15 -8
- package/src/internal/hardhat-network/stack-traces/message-trace.ts +40 -4
- package/src/internal/hardhat-network/stack-traces/model.ts +61 -0
- package/src/internal/hardhat-network/stack-traces/opcodes.ts +4 -0
- package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +2 -2
- package/src/internal/hardhat-network/stack-traces/solidityTracer.ts +6 -5
- package/src/internal/hardhat-network/stack-traces/vm-trace-decoder.ts +113 -4
- package/src/internal/hardhat-network/stack-traces/vm-tracer.ts +67 -95
- package/src/internal/util/date.ts +4 -0
- package/src/internal/util/hardforks.ts +52 -0
- package/src/internal/hardhat-network/provider/BlockchainBase.ts +0 -185
- package/src/internal/hardhat-network/provider/BlockchainData.ts +0 -261
- package/src/internal/hardhat-network/provider/HardhatBlockchain.ts +0 -140
- package/src/internal/hardhat-network/provider/PoolState.ts +0 -48
- package/src/internal/hardhat-network/provider/TransactionQueue.ts +0 -158
- package/src/internal/hardhat-network/provider/TxPool.ts +0 -715
- package/src/internal/hardhat-network/provider/ethereumjs-workarounds.ts +0 -21
- package/src/internal/hardhat-network/provider/filter.ts +0 -142
- package/src/internal/hardhat-network/provider/fork/ForkBlockchain.ts +0 -433
- package/src/internal/hardhat-network/provider/fork/ForkStateManager.ts +0 -480
- package/src/internal/hardhat-network/provider/fork/rpcToBlockData.ts +0 -35
- package/src/internal/hardhat-network/provider/fork/rpcToTxData.ts +0 -44
- package/src/internal/hardhat-network/provider/modules/base.ts +0 -156
- package/src/internal/hardhat-network/provider/modules/debug.ts +0 -104
- package/src/internal/hardhat-network/provider/modules/eth.ts +0 -1781
- package/src/internal/hardhat-network/provider/modules/evm.ts +0 -249
- package/src/internal/hardhat-network/provider/modules/hardhat.ts +0 -481
- package/src/internal/hardhat-network/provider/modules/net.ts +0 -60
- package/src/internal/hardhat-network/provider/modules/personal.ts +0 -40
- package/src/internal/hardhat-network/provider/modules/web3.ts +0 -49
- package/src/internal/hardhat-network/provider/node.ts +0 -2993
- package/src/internal/hardhat-network/provider/transactions/FakeSenderAccessListEIP2930Transaction.ts +0 -226
- package/src/internal/hardhat-network/provider/transactions/FakeSenderEIP1559Transaction.ts +0 -224
- package/src/internal/hardhat-network/provider/transactions/FakeSenderTransaction.ts +0 -216
- package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP1559Transaction.ts +0 -143
- package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidEIP2930Transaction.ts +0 -144
- package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidTransaction.ts +0 -171
- package/src/internal/hardhat-network/provider/transactions/ReadOnlyValidUnknownTypeTransaction.ts +0 -169
- package/src/internal/hardhat-network/provider/types/HardhatBlockchainInterface.ts +0 -25
- package/src/internal/hardhat-network/provider/utils/makeFakeSignature.ts +0 -60
- package/src/internal/hardhat-network/provider/utils/makeStateTrie.ts +0 -29
- package/src/internal/hardhat-network/provider/utils/putGenesisBlock.ts +0 -61
- package/src/internal/hardhat-network/provider/utils/reorganizeTransactionsLists.ts +0 -45
- package/src/internal/hardhat-network/provider/utils/txMapToArray.ts +0 -7
- package/src/internal/hardhat-network/stack-traces/vm-debug-tracer.ts +0 -630
|
@@ -1,715 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Common,
|
|
3
|
-
StateManagerInterface,
|
|
4
|
-
} from "@nomicfoundation/ethereumjs-common";
|
|
5
|
-
import {
|
|
6
|
-
TransactionFactory,
|
|
7
|
-
TypedTransaction,
|
|
8
|
-
} from "@nomicfoundation/ethereumjs-tx";
|
|
9
|
-
import {
|
|
10
|
-
Address,
|
|
11
|
-
bytesToHex as bufferToHex,
|
|
12
|
-
equalsBytes,
|
|
13
|
-
toBytes,
|
|
14
|
-
} from "@nomicfoundation/ethereumjs-util";
|
|
15
|
-
import { List as ImmutableList, Record as ImmutableRecord } from "immutable";
|
|
16
|
-
|
|
17
|
-
import { InvalidInputError } from "../../core/providers/errors";
|
|
18
|
-
import * as BigIntUtils from "../../util/bigint";
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
AddressToTransactions,
|
|
22
|
-
makePoolState,
|
|
23
|
-
makeSerializedTransaction,
|
|
24
|
-
OrderedTransaction,
|
|
25
|
-
PoolState,
|
|
26
|
-
SenderTransactions,
|
|
27
|
-
SerializedTransaction,
|
|
28
|
-
} from "./PoolState";
|
|
29
|
-
import { FakeSenderAccessListEIP2930Transaction } from "./transactions/FakeSenderAccessListEIP2930Transaction";
|
|
30
|
-
import { FakeSenderTransaction } from "./transactions/FakeSenderTransaction";
|
|
31
|
-
import { reorganizeTransactionsLists } from "./utils/reorganizeTransactionsLists";
|
|
32
|
-
import { FakeSenderEIP1559Transaction } from "./transactions/FakeSenderEIP1559Transaction";
|
|
33
|
-
|
|
34
|
-
/* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
|
|
35
|
-
|
|
36
|
-
export function serializeTransaction(
|
|
37
|
-
tx: OrderedTransaction
|
|
38
|
-
): SerializedTransaction {
|
|
39
|
-
const rlpSerialization = bufferToHex(tx.data.serialize());
|
|
40
|
-
const isFake =
|
|
41
|
-
tx.data instanceof FakeSenderTransaction ||
|
|
42
|
-
tx.data instanceof FakeSenderAccessListEIP2930Transaction ||
|
|
43
|
-
tx.data instanceof FakeSenderEIP1559Transaction;
|
|
44
|
-
return makeSerializedTransaction({
|
|
45
|
-
orderId: tx.orderId,
|
|
46
|
-
fakeFrom: isFake ? tx.data.getSenderAddress().toString() : undefined,
|
|
47
|
-
data: rlpSerialization,
|
|
48
|
-
txType: tx.data.type,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function deserializeTransaction(
|
|
53
|
-
tx: SerializedTransaction,
|
|
54
|
-
common: Common
|
|
55
|
-
): OrderedTransaction {
|
|
56
|
-
const rlpSerialization = tx.get("data");
|
|
57
|
-
const fakeFrom = tx.get("fakeFrom");
|
|
58
|
-
|
|
59
|
-
let data;
|
|
60
|
-
if (fakeFrom !== undefined) {
|
|
61
|
-
const sender = Address.fromString(fakeFrom);
|
|
62
|
-
const serialization = toBytes(rlpSerialization);
|
|
63
|
-
|
|
64
|
-
if (tx.get("txType") === 1) {
|
|
65
|
-
data =
|
|
66
|
-
FakeSenderAccessListEIP2930Transaction.fromSenderAndRlpSerializedTx(
|
|
67
|
-
sender,
|
|
68
|
-
serialization,
|
|
69
|
-
{ common }
|
|
70
|
-
);
|
|
71
|
-
} else if (tx.get("txType") === 2) {
|
|
72
|
-
data = FakeSenderEIP1559Transaction.fromSenderAndRlpSerializedTx(
|
|
73
|
-
sender,
|
|
74
|
-
serialization,
|
|
75
|
-
{ common }
|
|
76
|
-
);
|
|
77
|
-
} else {
|
|
78
|
-
data = FakeSenderTransaction.fromSenderAndRlpSerializedTx(
|
|
79
|
-
sender,
|
|
80
|
-
serialization,
|
|
81
|
-
{ common }
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
data = TransactionFactory.fromSerializedData(toBytes(rlpSerialization), {
|
|
86
|
-
common,
|
|
87
|
-
allowUnlimitedInitCodeSize: true,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return {
|
|
92
|
-
orderId: tx.get("orderId"),
|
|
93
|
-
data,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export class TxPool {
|
|
98
|
-
private _state: ImmutableRecord<PoolState>;
|
|
99
|
-
private _snapshotIdToState = new Map<number, ImmutableRecord<PoolState>>();
|
|
100
|
-
private _nextSnapshotId = 0;
|
|
101
|
-
private _nextOrderId = 0;
|
|
102
|
-
|
|
103
|
-
private readonly _deserializeTransaction: (
|
|
104
|
-
tx: SerializedTransaction
|
|
105
|
-
) => OrderedTransaction;
|
|
106
|
-
|
|
107
|
-
constructor(
|
|
108
|
-
private readonly _stateManager: StateManagerInterface,
|
|
109
|
-
blockGasLimit: bigint,
|
|
110
|
-
common: Common
|
|
111
|
-
) {
|
|
112
|
-
this._state = makePoolState({
|
|
113
|
-
blockGasLimit: BigIntUtils.toHex(blockGasLimit),
|
|
114
|
-
});
|
|
115
|
-
this._deserializeTransaction = (tx) => deserializeTransaction(tx, common);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
public async addTransaction(tx: TypedTransaction) {
|
|
119
|
-
const senderAddress = this._getSenderAddress(tx);
|
|
120
|
-
const nextConfirmedNonce = await this._getNextConfirmedNonce(senderAddress);
|
|
121
|
-
const nextPendingNonce = await this.getNextPendingNonce(senderAddress);
|
|
122
|
-
|
|
123
|
-
await this._validateTransaction(tx, senderAddress, nextConfirmedNonce);
|
|
124
|
-
|
|
125
|
-
const txNonce = tx.nonce;
|
|
126
|
-
|
|
127
|
-
if (txNonce > nextPendingNonce) {
|
|
128
|
-
this._addQueuedTransaction(tx);
|
|
129
|
-
} else {
|
|
130
|
-
this._addPendingTransaction(tx);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Remove transaction with the given hash from the mempool. Returns true
|
|
136
|
-
* if a transaction was removed, false otherwise.
|
|
137
|
-
*/
|
|
138
|
-
public removeTransaction(txHash: Buffer): boolean {
|
|
139
|
-
const tx = this.getTransactionByHash(txHash);
|
|
140
|
-
|
|
141
|
-
if (tx === undefined) {
|
|
142
|
-
// transaction doesn't exist in the mempool
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
this._deleteTransactionByHash(txHash);
|
|
147
|
-
|
|
148
|
-
const serializedTx = serializeTransaction(tx);
|
|
149
|
-
const senderAddress = this._getSenderAddress(tx.data).toString();
|
|
150
|
-
|
|
151
|
-
const pendingForAddress =
|
|
152
|
-
this._getPendingForAddress(senderAddress) ??
|
|
153
|
-
ImmutableList<SerializedTransaction>();
|
|
154
|
-
const queuedForAddress =
|
|
155
|
-
this._getQueuedForAddress(senderAddress) ??
|
|
156
|
-
ImmutableList<SerializedTransaction>();
|
|
157
|
-
|
|
158
|
-
// if the tx to remove is in the pending state, remove it
|
|
159
|
-
// and move the following transactions to the queued list
|
|
160
|
-
const indexOfPendingTx = pendingForAddress.indexOf(serializedTx);
|
|
161
|
-
if (indexOfPendingTx !== -1) {
|
|
162
|
-
const newPendingForAddress = pendingForAddress.splice(
|
|
163
|
-
indexOfPendingTx,
|
|
164
|
-
pendingForAddress.size
|
|
165
|
-
);
|
|
166
|
-
const newQueuedForAddress = queuedForAddress.concat(
|
|
167
|
-
pendingForAddress.slice(indexOfPendingTx + 1)
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
this._setPendingForAddress(senderAddress, newPendingForAddress);
|
|
171
|
-
this._setQueuedForAddress(senderAddress, newQueuedForAddress);
|
|
172
|
-
return true;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// if the tx is in the queued state, we just remove it
|
|
176
|
-
const indexOfQueuedTx = queuedForAddress.indexOf(serializedTx);
|
|
177
|
-
if (indexOfQueuedTx !== -1) {
|
|
178
|
-
const newQueuedForAddress = queuedForAddress.splice(indexOfQueuedTx, 1);
|
|
179
|
-
this._setQueuedForAddress(senderAddress, newQueuedForAddress);
|
|
180
|
-
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
throw new Error("Tx should have existed in the pending or queued lists");
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
public snapshot(): number {
|
|
188
|
-
const id = this._nextSnapshotId++;
|
|
189
|
-
this._snapshotIdToState.set(id, this._state);
|
|
190
|
-
return id;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
public revert(snapshotId: number) {
|
|
194
|
-
const state = this._snapshotIdToState.get(snapshotId);
|
|
195
|
-
if (state === undefined) {
|
|
196
|
-
throw new Error("There's no snapshot with such ID");
|
|
197
|
-
}
|
|
198
|
-
this._state = state;
|
|
199
|
-
|
|
200
|
-
this._removeSnapshotsAfter(snapshotId);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
public getTransactionByHash(hash: Buffer): OrderedTransaction | undefined {
|
|
204
|
-
const tx = this._getTransactionsByHash().get(bufferToHex(hash));
|
|
205
|
-
if (tx !== undefined) {
|
|
206
|
-
return this._deserializeTransaction(tx);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return undefined;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
public hasPendingTransactions(): boolean {
|
|
213
|
-
const pendingMap = this._getPending();
|
|
214
|
-
return pendingMap.some((senderPendingTxs) => !senderPendingTxs.isEmpty());
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
public hasQueuedTransactions(): boolean {
|
|
218
|
-
const queuedMap = this._getQueued();
|
|
219
|
-
return queuedMap.some((senderQueuedTxs) => !senderQueuedTxs.isEmpty());
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
public isEmpty(): boolean {
|
|
223
|
-
return !(this.hasPendingTransactions() || this.hasQueuedTransactions());
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
public getPendingTransactions(): Map<string, OrderedTransaction[]> {
|
|
227
|
-
const deserializedImmutableMap = this._getPending()
|
|
228
|
-
.filter((txs) => txs.size > 0)
|
|
229
|
-
.map(
|
|
230
|
-
(txs) =>
|
|
231
|
-
txs.map(this._deserializeTransaction).toJS() as OrderedTransaction[]
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
return new Map(deserializedImmutableMap.entries());
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
public getQueuedTransactions(): Map<string, OrderedTransaction[]> {
|
|
238
|
-
const deserializedImmutableMap = this._getQueued()
|
|
239
|
-
.filter((txs) => txs.size > 0)
|
|
240
|
-
.map(
|
|
241
|
-
(txs) =>
|
|
242
|
-
txs.map(this._deserializeTransaction).toJS() as OrderedTransaction[]
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
return new Map(deserializedImmutableMap.entries());
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Returns the next available nonce for an address, taking into account
|
|
250
|
-
* its pending transactions.
|
|
251
|
-
*/
|
|
252
|
-
public async getNextPendingNonce(accountAddress: Address): Promise<bigint> {
|
|
253
|
-
const pendingTxs = this._getPendingForAddress(accountAddress.toString());
|
|
254
|
-
const lastPendingTx = pendingTxs?.last(undefined);
|
|
255
|
-
|
|
256
|
-
if (lastPendingTx === undefined) {
|
|
257
|
-
return this._getNextConfirmedNonce(accountAddress);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const lastPendingTxNonce =
|
|
261
|
-
this._deserializeTransaction(lastPendingTx).data.nonce;
|
|
262
|
-
return lastPendingTxNonce + 1n;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
public getBlockGasLimit(): bigint {
|
|
266
|
-
return BigInt(this._state.get("blockGasLimit"));
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
public setBlockGasLimit(newLimit: bigint | number) {
|
|
270
|
-
if (typeof newLimit === "number") {
|
|
271
|
-
newLimit = BigInt(newLimit);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
this._setBlockGasLimit(newLimit);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Updates the pending and queued list of all addresses
|
|
279
|
-
*/
|
|
280
|
-
public async updatePendingAndQueued() {
|
|
281
|
-
let newPending = this._getPending();
|
|
282
|
-
|
|
283
|
-
// update pending transactions
|
|
284
|
-
for (const [address, txs] of newPending) {
|
|
285
|
-
const senderAccount = await this._stateManager.getAccount(
|
|
286
|
-
Address.fromString(address)
|
|
287
|
-
);
|
|
288
|
-
const senderNonce = senderAccount?.nonce ?? 0n;
|
|
289
|
-
const senderBalance = senderAccount?.balance ?? 0n;
|
|
290
|
-
|
|
291
|
-
let moveToQueued = false;
|
|
292
|
-
for (const tx of txs) {
|
|
293
|
-
const deserializedTx = this._deserializeTransaction(tx);
|
|
294
|
-
|
|
295
|
-
if (moveToQueued) {
|
|
296
|
-
newPending = this._removeTx(newPending, address, deserializedTx);
|
|
297
|
-
|
|
298
|
-
const queued = this._getQueuedForAddress(address) ?? ImmutableList();
|
|
299
|
-
this._setQueuedForAddress(address, queued.push(tx));
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
const txNonce = deserializedTx.data.nonce;
|
|
304
|
-
|
|
305
|
-
if (
|
|
306
|
-
!this._isTxValid(deserializedTx, txNonce, senderNonce, senderBalance)
|
|
307
|
-
) {
|
|
308
|
-
newPending = this._removeTx(newPending, address, deserializedTx);
|
|
309
|
-
|
|
310
|
-
// if we are dropping a pending transaction with a valid nonce,
|
|
311
|
-
// then we move all the following txs to the queued list
|
|
312
|
-
if (txNonce >= senderNonce) {
|
|
313
|
-
moveToQueued = true;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
this._setPending(newPending);
|
|
319
|
-
|
|
320
|
-
// update queued addresses
|
|
321
|
-
let newQueued = this._getQueued();
|
|
322
|
-
for (const [address, txs] of newQueued) {
|
|
323
|
-
const senderAccount = await this._stateManager.getAccount(
|
|
324
|
-
Address.fromString(address)
|
|
325
|
-
);
|
|
326
|
-
const senderNonce = senderAccount?.nonce ?? 0n;
|
|
327
|
-
const senderBalance = senderAccount?.balance ?? 0n;
|
|
328
|
-
|
|
329
|
-
for (const tx of txs) {
|
|
330
|
-
const deserializedTx = this._deserializeTransaction(tx);
|
|
331
|
-
const txNonce = deserializedTx.data.nonce;
|
|
332
|
-
|
|
333
|
-
if (
|
|
334
|
-
!this._isTxValid(deserializedTx, txNonce, senderNonce, senderBalance)
|
|
335
|
-
) {
|
|
336
|
-
newQueued = this._removeTx(newQueued, address, deserializedTx);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
this._setQueued(newQueued);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
private _getSenderAddress(tx: TypedTransaction): Address {
|
|
344
|
-
try {
|
|
345
|
-
return tx.getSenderAddress(); // verifies signature
|
|
346
|
-
} catch (e: any) {
|
|
347
|
-
if (!tx.isSigned()) {
|
|
348
|
-
throw new InvalidInputError("Invalid Signature");
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
throw new InvalidInputError(e.message);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
private _removeSnapshotsAfter(snapshotId: number): void {
|
|
356
|
-
const snapshotIds = [...this._snapshotIdToState.keys()].filter(
|
|
357
|
-
(x) => x >= snapshotId
|
|
358
|
-
);
|
|
359
|
-
|
|
360
|
-
for (const id of snapshotIds) {
|
|
361
|
-
this._snapshotIdToState.delete(id);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
private _removeTx(
|
|
366
|
-
map: AddressToTransactions,
|
|
367
|
-
address: string,
|
|
368
|
-
deserializedTX: OrderedTransaction
|
|
369
|
-
) {
|
|
370
|
-
const accountTxs = map.get(address);
|
|
371
|
-
if (accountTxs === undefined) {
|
|
372
|
-
throw new Error(
|
|
373
|
-
"Trying to remove a transaction from list that doesn't exist, this should never happen"
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
this._deleteTransactionByHash(deserializedTX.data.hash());
|
|
378
|
-
|
|
379
|
-
const indexOfTx = accountTxs.indexOf(serializeTransaction(deserializedTX));
|
|
380
|
-
return map.set(address, accountTxs.remove(indexOfTx));
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
private _addPendingTransaction(tx: TypedTransaction) {
|
|
384
|
-
const orderedTx = {
|
|
385
|
-
orderId: this._nextOrderId++,
|
|
386
|
-
data: tx,
|
|
387
|
-
};
|
|
388
|
-
const serializedTx = serializeTransaction(orderedTx);
|
|
389
|
-
|
|
390
|
-
const hexSenderAddress = tx.getSenderAddress().toString();
|
|
391
|
-
const accountTransactions: SenderTransactions =
|
|
392
|
-
this._getPendingForAddress(hexSenderAddress) ?? ImmutableList();
|
|
393
|
-
|
|
394
|
-
const replaced = this._replacePendingTx(hexSenderAddress, orderedTx);
|
|
395
|
-
if (!replaced) {
|
|
396
|
-
const { newPending, newQueued } = reorganizeTransactionsLists(
|
|
397
|
-
accountTransactions.push(serializedTx),
|
|
398
|
-
this._getQueuedForAddress(hexSenderAddress) ?? ImmutableList(),
|
|
399
|
-
(stx) => this._deserializeTransaction(stx).data.nonce
|
|
400
|
-
);
|
|
401
|
-
|
|
402
|
-
this._setPendingForAddress(hexSenderAddress, newPending);
|
|
403
|
-
this._setQueuedForAddress(hexSenderAddress, newQueued);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
this._setTransactionByHash(bufferToHex(tx.hash()), serializedTx);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
private _addQueuedTransaction(tx: TypedTransaction) {
|
|
410
|
-
const orderedTx = {
|
|
411
|
-
orderId: this._nextOrderId++,
|
|
412
|
-
data: tx,
|
|
413
|
-
};
|
|
414
|
-
const serializedTx = serializeTransaction(orderedTx);
|
|
415
|
-
|
|
416
|
-
const hexSenderAddress = tx.getSenderAddress().toString();
|
|
417
|
-
const accountTransactions: SenderTransactions =
|
|
418
|
-
this._getQueuedForAddress(hexSenderAddress) ?? ImmutableList();
|
|
419
|
-
|
|
420
|
-
const replaced = this._replaceQueuedTx(hexSenderAddress, orderedTx);
|
|
421
|
-
if (!replaced) {
|
|
422
|
-
this._setQueuedForAddress(
|
|
423
|
-
hexSenderAddress,
|
|
424
|
-
accountTransactions.push(serializedTx)
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
this._setTransactionByHash(bufferToHex(tx.hash()), serializedTx);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
private async _validateTransaction(
|
|
432
|
-
tx: TypedTransaction,
|
|
433
|
-
senderAddress: Address,
|
|
434
|
-
senderNonce: bigint
|
|
435
|
-
) {
|
|
436
|
-
if (this._knownTransaction(tx)) {
|
|
437
|
-
throw new InvalidInputError(
|
|
438
|
-
`Known transaction: ${bufferToHex(tx.hash())}`
|
|
439
|
-
);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
const txNonce = tx.nonce;
|
|
443
|
-
|
|
444
|
-
// Geth returns this error if trying to create a contract and no data is provided
|
|
445
|
-
if (tx.to === undefined && tx.data.length === 0) {
|
|
446
|
-
throw new InvalidInputError(
|
|
447
|
-
"contract creation without any data provided"
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
const senderAccount = await this._stateManager.getAccount(senderAddress);
|
|
452
|
-
const senderBalance = senderAccount?.balance ?? 0n;
|
|
453
|
-
|
|
454
|
-
const maxFee = "gasPrice" in tx ? tx.gasPrice : tx.maxFeePerGas;
|
|
455
|
-
const txMaxUpfrontCost = tx.gasLimit * maxFee + tx.value;
|
|
456
|
-
|
|
457
|
-
if (txMaxUpfrontCost > senderBalance) {
|
|
458
|
-
throw new InvalidInputError(
|
|
459
|
-
`sender doesn't have enough funds to send tx. The max upfront cost is: ${txMaxUpfrontCost.toString()}` +
|
|
460
|
-
` and the sender's account only has: ${senderBalance.toString()}`
|
|
461
|
-
);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if (txNonce < senderNonce) {
|
|
465
|
-
throw new InvalidInputError(
|
|
466
|
-
`Nonce too low. Expected nonce to be at least ${senderNonce.toString()} but got ${txNonce.toString()}.`
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
const gasLimit = tx.gasLimit;
|
|
471
|
-
const baseFee = tx.getBaseFee();
|
|
472
|
-
|
|
473
|
-
if (gasLimit < baseFee) {
|
|
474
|
-
throw new InvalidInputError(
|
|
475
|
-
`Transaction requires at least ${baseFee.toString()} gas but got ${gasLimit.toString()}`
|
|
476
|
-
);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
const blockGasLimit = this.getBlockGasLimit();
|
|
480
|
-
|
|
481
|
-
if (gasLimit > blockGasLimit) {
|
|
482
|
-
throw new InvalidInputError(
|
|
483
|
-
`Transaction gas limit is ${gasLimit.toString()} and exceeds block gas limit of ${blockGasLimit.toString()}`
|
|
484
|
-
);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
private _knownTransaction(tx: TypedTransaction): boolean {
|
|
489
|
-
const senderAddress = tx.getSenderAddress().toString();
|
|
490
|
-
return (
|
|
491
|
-
this._transactionExists(tx, this._getPendingForAddress(senderAddress)) ||
|
|
492
|
-
this._transactionExists(tx, this._getQueuedForAddress(senderAddress))
|
|
493
|
-
);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
private _transactionExists(
|
|
497
|
-
tx: TypedTransaction,
|
|
498
|
-
txList: SenderTransactions | undefined
|
|
499
|
-
) {
|
|
500
|
-
const existingTx = txList?.find((etx) =>
|
|
501
|
-
equalsBytes(this._deserializeTransaction(etx).data.hash(), tx.hash())
|
|
502
|
-
);
|
|
503
|
-
return existingTx !== undefined;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
private _getTransactionsByHash() {
|
|
507
|
-
return this._state.get("hashToTransaction");
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
private _getPending() {
|
|
511
|
-
return this._state.get("pendingTransactions");
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
private _getQueued() {
|
|
515
|
-
return this._state.get("queuedTransactions");
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
private _getPendingForAddress(address: string) {
|
|
519
|
-
return this._getPending().get(address);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
private _getQueuedForAddress(address: string) {
|
|
523
|
-
return this._getQueued().get(address);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
private _setTransactionByHash(
|
|
527
|
-
hash: string,
|
|
528
|
-
transaction: SerializedTransaction
|
|
529
|
-
) {
|
|
530
|
-
this._state = this._state.set(
|
|
531
|
-
"hashToTransaction",
|
|
532
|
-
this._getTransactionsByHash().set(hash, transaction)
|
|
533
|
-
);
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
private _setPending(transactions: AddressToTransactions) {
|
|
537
|
-
this._state = this._state.set("pendingTransactions", transactions);
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
private _setQueued(transactions: AddressToTransactions) {
|
|
541
|
-
this._state = this._state.set("queuedTransactions", transactions);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
private _setPendingForAddress(
|
|
545
|
-
address: string,
|
|
546
|
-
transactions: SenderTransactions
|
|
547
|
-
) {
|
|
548
|
-
this._state = this._state.set(
|
|
549
|
-
"pendingTransactions",
|
|
550
|
-
this._getPending().set(address, transactions)
|
|
551
|
-
);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
private _setQueuedForAddress(
|
|
555
|
-
address: string,
|
|
556
|
-
transactions: SenderTransactions
|
|
557
|
-
) {
|
|
558
|
-
this._state = this._state.set(
|
|
559
|
-
"queuedTransactions",
|
|
560
|
-
this._getQueued().set(address, transactions)
|
|
561
|
-
);
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
private _setBlockGasLimit(newLimit: bigint) {
|
|
565
|
-
this._state = this._state.set("blockGasLimit", BigIntUtils.toHex(newLimit));
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
private _deleteTransactionByHash(hash: Uint8Array) {
|
|
569
|
-
this._state = this._state.set(
|
|
570
|
-
"hashToTransaction",
|
|
571
|
-
this._getTransactionsByHash().delete(bufferToHex(hash))
|
|
572
|
-
);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
private _isTxValid(
|
|
576
|
-
tx: OrderedTransaction,
|
|
577
|
-
txNonce: bigint,
|
|
578
|
-
senderNonce: bigint,
|
|
579
|
-
senderBalance: bigint
|
|
580
|
-
): boolean {
|
|
581
|
-
const txGasLimit = tx.data.gasLimit;
|
|
582
|
-
|
|
583
|
-
return (
|
|
584
|
-
txGasLimit <= this.getBlockGasLimit() &&
|
|
585
|
-
txNonce >= senderNonce &&
|
|
586
|
-
tx.data.getUpfrontCost() <= senderBalance
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
/**
|
|
591
|
-
* Returns the next available nonce for an address, ignoring its
|
|
592
|
-
* pending transactions.
|
|
593
|
-
*/
|
|
594
|
-
private async _getNextConfirmedNonce(
|
|
595
|
-
accountAddress: Address
|
|
596
|
-
): Promise<bigint> {
|
|
597
|
-
const account = await this._stateManager.getAccount(accountAddress);
|
|
598
|
-
return account?.nonce ?? 0n;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* Checks if some pending tx with the same nonce as `newTx` exists.
|
|
603
|
-
* If it exists, it replaces it with `newTx` and returns true.
|
|
604
|
-
* Otherwise returns false.
|
|
605
|
-
*/
|
|
606
|
-
private _replacePendingTx(
|
|
607
|
-
accountAddress: string,
|
|
608
|
-
newTx: OrderedTransaction
|
|
609
|
-
): boolean {
|
|
610
|
-
const pendingTxs = this._getPendingForAddress(accountAddress);
|
|
611
|
-
const newPendingTxs = this._replaceTx(pendingTxs, newTx);
|
|
612
|
-
|
|
613
|
-
if (newPendingTxs !== undefined) {
|
|
614
|
-
this._setPendingForAddress(accountAddress, newPendingTxs);
|
|
615
|
-
return true;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
return false;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
/**
|
|
622
|
-
* Checks if some queued tx with the same nonce as `newTx` exists.
|
|
623
|
-
* If it exists, it replaces it with `newTx` and returns true.
|
|
624
|
-
* Otherwise returns false.
|
|
625
|
-
*/
|
|
626
|
-
private _replaceQueuedTx(
|
|
627
|
-
accountAddress: string,
|
|
628
|
-
newTx: OrderedTransaction
|
|
629
|
-
): boolean {
|
|
630
|
-
const queuedTxs = this._getQueuedForAddress(accountAddress);
|
|
631
|
-
const newQueuedTxs = this._replaceTx(queuedTxs, newTx);
|
|
632
|
-
|
|
633
|
-
if (newQueuedTxs !== undefined) {
|
|
634
|
-
this._setQueuedForAddress(accountAddress, newQueuedTxs);
|
|
635
|
-
return true;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
return false;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
private _replaceTx(
|
|
642
|
-
txs: SenderTransactions | undefined,
|
|
643
|
-
newTx: OrderedTransaction
|
|
644
|
-
): SenderTransactions | undefined {
|
|
645
|
-
if (txs === undefined) {
|
|
646
|
-
return;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
const existingTxEntry = txs.findEntry(
|
|
650
|
-
(tx) => this._deserializeTransaction(tx).data.nonce === newTx.data.nonce
|
|
651
|
-
);
|
|
652
|
-
|
|
653
|
-
if (existingTxEntry === undefined) {
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
const [existingTxIndex, existingTx] = existingTxEntry;
|
|
658
|
-
|
|
659
|
-
const deserializedExistingTx = this._deserializeTransaction(existingTx);
|
|
660
|
-
|
|
661
|
-
const currentMaxFeePerGas =
|
|
662
|
-
"gasPrice" in deserializedExistingTx.data
|
|
663
|
-
? deserializedExistingTx.data.gasPrice
|
|
664
|
-
: deserializedExistingTx.data.maxFeePerGas;
|
|
665
|
-
|
|
666
|
-
const currentPriorityFeePerGas =
|
|
667
|
-
"gasPrice" in deserializedExistingTx.data
|
|
668
|
-
? deserializedExistingTx.data.gasPrice
|
|
669
|
-
: deserializedExistingTx.data.maxPriorityFeePerGas;
|
|
670
|
-
|
|
671
|
-
const newMaxFeePerGas =
|
|
672
|
-
"gasPrice" in newTx.data ? newTx.data.gasPrice : newTx.data.maxFeePerGas;
|
|
673
|
-
|
|
674
|
-
const newPriorityFeePerGas =
|
|
675
|
-
"gasPrice" in newTx.data
|
|
676
|
-
? newTx.data.gasPrice
|
|
677
|
-
: newTx.data.maxPriorityFeePerGas;
|
|
678
|
-
|
|
679
|
-
const minNewMaxFeePerGas = this._getMinNewFeePrice(currentMaxFeePerGas);
|
|
680
|
-
|
|
681
|
-
const minNewPriorityFeePerGas = this._getMinNewFeePrice(
|
|
682
|
-
currentPriorityFeePerGas
|
|
683
|
-
);
|
|
684
|
-
|
|
685
|
-
if (newMaxFeePerGas < minNewMaxFeePerGas) {
|
|
686
|
-
throw new InvalidInputError(
|
|
687
|
-
`Replacement transaction underpriced. A gasPrice/maxFeePerGas of at least ${minNewMaxFeePerGas.toString()} is necessary to replace the existing transaction with nonce ${newTx.data.nonce.toString()}.`
|
|
688
|
-
);
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
if (newPriorityFeePerGas < minNewPriorityFeePerGas) {
|
|
692
|
-
throw new InvalidInputError(
|
|
693
|
-
`Replacement transaction underpriced. A gasPrice/maxPriorityFeePerGas of at least ${minNewPriorityFeePerGas.toString()} is necessary to replace the existing transaction with nonce ${newTx.data.nonce.toString()}.`
|
|
694
|
-
);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
const newTxs = txs.set(existingTxIndex, serializeTransaction(newTx));
|
|
698
|
-
|
|
699
|
-
this._deleteTransactionByHash(deserializedExistingTx.data.hash());
|
|
700
|
-
|
|
701
|
-
return newTxs;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
private _getMinNewFeePrice(feePrice: bigint): bigint {
|
|
705
|
-
let minNewPriorityFee = feePrice * 110n;
|
|
706
|
-
|
|
707
|
-
if (minNewPriorityFee % 100n === 0n) {
|
|
708
|
-
minNewPriorityFee = minNewPriorityFee / 100n;
|
|
709
|
-
} else {
|
|
710
|
-
minNewPriorityFee = minNewPriorityFee / 100n + 1n;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
return minNewPriorityFee;
|
|
714
|
-
}
|
|
715
|
-
}
|