2022-01-18 14:40:02 +00:00
|
|
|
# Nimbus
|
2024-02-15 09:57:05 +07:00
|
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
2022-01-18 14:40:02 +00:00
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
|
|
# http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
|
|
# according to those terms.
|
|
|
|
|
|
|
|
## Transaction Pool Item Container & Wrapper
|
|
|
|
## =========================================
|
|
|
|
##
|
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
{.push raises: [].}
|
|
|
|
|
2022-01-18 14:40:02 +00:00
|
|
|
import
|
2024-02-16 16:08:07 +07:00
|
|
|
std/[hashes, times],
|
2024-12-26 17:07:25 +07:00
|
|
|
results,
|
2024-02-16 16:08:07 +07:00
|
|
|
../../utils/utils,
|
2024-12-26 17:07:25 +07:00
|
|
|
../../transaction
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
from ../eip4844 import getTotalBlobGas
|
|
|
|
from eth/common/hashes import hash
|
2022-01-18 14:40:02 +00:00
|
|
|
|
|
|
|
type
|
2024-12-26 17:07:25 +07:00
|
|
|
TxError* = enum
|
|
|
|
txErrorInvalidSignature
|
|
|
|
txErrorItemNotFound
|
|
|
|
txErrorAlreadyKnown
|
|
|
|
txErrorNonceTooSmall
|
|
|
|
txErrorBasicValidation
|
|
|
|
txErrorInvalidBlob
|
|
|
|
txErrorReplacementGasTooLow
|
|
|
|
txErrorReplacementBlobGasTooLow
|
|
|
|
txErrorPoolIsFull
|
|
|
|
txErrorSenderMaxTxs
|
|
|
|
txErrorTxInvalid
|
|
|
|
txErrorChainIdMismatch
|
|
|
|
|
|
|
|
TxItemRef* = ref object
|
|
|
|
ptx : PooledTransaction ## Transaction data
|
|
|
|
id : Hash32 ## Transaction hash
|
|
|
|
time : Time ## Time when added
|
|
|
|
sender: Address ## Sender account address
|
|
|
|
price : GasInt
|
|
|
|
|
|
|
|
TxGasPrice = object
|
|
|
|
maxFee: GasInt
|
|
|
|
tip: GasInt
|
2022-01-18 14:40:02 +00:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Public functions, Constructor
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
proc utcNow*(): Time =
|
|
|
|
getTime().utc.toTime
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
proc new*(T: type TxItemRef;
|
|
|
|
ptx: PooledTransaction,
|
|
|
|
id: Hash32,
|
|
|
|
sender: Address): T =
|
2022-01-18 14:40:02 +00:00
|
|
|
## Create item descriptor.
|
2024-12-26 17:07:25 +07:00
|
|
|
T(
|
|
|
|
ptx : ptx,
|
|
|
|
id : id,
|
|
|
|
time : utcNow(),
|
|
|
|
sender: sender,
|
|
|
|
)
|
2022-01-18 14:40:02 +00:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
2024-12-26 17:07:25 +07:00
|
|
|
# Public functions
|
|
|
|
# -------------------------------------------------------------------------------
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
func tip*(tx: Transaction; baseFee: GasInt): GasInt =
|
|
|
|
## Tip calculator
|
2024-07-31 14:33:30 +07:00
|
|
|
effectiveGasTip(tx, Opt.some(baseFee.u256))
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
func txGasPrice*(tx: Transaction): TxGasPrice =
|
|
|
|
case tx.txType
|
|
|
|
of TxLegacy, TxEip2930:
|
|
|
|
TxGasPrice(
|
|
|
|
maxFee: tx.gasPrice,
|
|
|
|
tip: tx.gasPrice,
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
TxGasPrice(
|
|
|
|
maxFee: tx.maxFeePerGas,
|
|
|
|
tip: tx.maxPriorityFeePerGas,
|
|
|
|
)
|
|
|
|
|
|
|
|
func hash*(item: TxItemRef): Hash =
|
|
|
|
## Needed if `TxItemRef` is used as hash-`Table` index.
|
|
|
|
hash(item.id)
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
template pooledTx*(item: TxItemRef): PooledTransaction =
|
2022-01-18 14:40:02 +00:00
|
|
|
## Getter
|
2024-12-26 17:07:25 +07:00
|
|
|
item.ptx
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
template tx*(item: TxItemRef): Transaction =
|
2022-01-18 14:40:02 +00:00
|
|
|
## Getter
|
2024-12-26 17:07:25 +07:00
|
|
|
item.ptx.tx
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
template id*(item: TxItemRef): Hash32 =
|
2022-01-18 14:40:02 +00:00
|
|
|
## Getter
|
2024-12-26 17:07:25 +07:00
|
|
|
item.id
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
template sender*(item: TxItemRef): Address =
|
2022-01-18 14:40:02 +00:00
|
|
|
## Getter
|
|
|
|
item.sender
|
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
template time*(item: TxItemRef): Time =
|
2022-01-18 14:40:02 +00:00
|
|
|
## Getter
|
2024-12-26 17:07:25 +07:00
|
|
|
item.time
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
template nonce*(item: TxItemRef): AccountNonce =
|
2022-01-18 14:40:02 +00:00
|
|
|
## Getter
|
2024-12-26 17:07:25 +07:00
|
|
|
item.tx.nonce
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
template price*(item: TxItemRef): GasInt =
|
2024-05-15 06:07:59 +03:00
|
|
|
## Getter
|
2024-12-26 17:07:25 +07:00
|
|
|
item.price
|
2024-05-15 06:07:59 +03:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
func calculatePrice*(item: TxItemRef; baseFee: GasInt) =
|
|
|
|
## Profit calculator
|
|
|
|
item.price = item.tx.gasLimit * item.tx.tip(baseFee) + item.tx.getTotalBlobGas
|
2023-10-20 15:30:05 +07:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
func validateTxGasBump*(current: TxItemRef, added: TxItemRef): Result[void, TxError] =
|
|
|
|
func txGasPrice(item: TxItemRef): TxGasPrice =
|
|
|
|
txGasPrice(item.tx)
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
const
|
|
|
|
MIN_GAS_PRICE_BUMP_PERCENT = 10
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
let
|
|
|
|
currentGasPrice = current.txGasPrice
|
|
|
|
newGasPrice = added.txGasPrice
|
|
|
|
minTipCap = currentGasPrice.tip +
|
|
|
|
(currentGasPrice.tip * MIN_GAS_PRICE_BUMP_PERCENT) div 100.GasInt
|
|
|
|
minFeeCap = currentGasPrice.maxFee +
|
|
|
|
(currentGasPrice.maxFee * MIN_GAS_PRICE_BUMP_PERCENT) div 100.GasInt
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
if newGasPrice.tip < minTipCap or newGasPrice.maxFee < minFeeCap:
|
|
|
|
return err(txErrorReplacementGasTooLow)
|
2023-10-20 15:30:05 +07:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
if added.tx.txType == TxEip4844 and current.tx.txType == TxEip4844:
|
|
|
|
let minblobGasFee = current.tx.maxFeePerBlobGas +
|
|
|
|
(current.tx.maxFeePerBlobGas * MIN_GAS_PRICE_BUMP_PERCENT.u256) div 100.u256
|
|
|
|
if added.tx.maxFeePerBlobGas < minblobGasFee:
|
|
|
|
return err(txErrorReplacementBlobGasTooLow)
|
2022-01-18 14:40:02 +00:00
|
|
|
|
2024-12-26 17:07:25 +07:00
|
|
|
ok()
|
2022-01-18 14:40:02 +00:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# End
|
|
|
|
# ------------------------------------------------------------------------------
|