Skip to content
This repository has been archived by the owner on Feb 17, 2025. It is now read-only.

New gas price estimation + HashDB + Fork ID 5 SMC #2196

Merged
merged 44 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
238841b
wip
Psykepro May 23, 2023
6b25dea
update executor proto (#2122)
ToniRamirezM May 25, 2023
db73917
new smc
ARR552 Jun 12, 2023
8231e94
smc docker image
ARR552 Jun 12, 2023
e037fb1
merging feature/HashDB
Psykepro Jun 12, 2023
0d2e667
Merge branch 'feature/#2180_update_smc' into feature/new-gas-price-es…
Psykepro Jun 13, 2023
005bfcc
wip
Psykepro Jun 15, 2023
104809e
fixing comments.
Psykepro Jun 19, 2023
42dd793
Merge branch 'develop' into feature/new-gas-price-estimation
Psykepro Jun 19, 2023
652f87c
improve: adding missing safe check for L2 Min Gas Price.
Psykepro Jun 19, 2023
a33bfc4
fix: fixing eth-CallEcrecoverInvalidSignature.json 'expectedOldStateR…
Psykepro Jun 20, 2023
f9d7f11
improve: adding missing check in finalizer for old txs.
Psykepro Jun 20, 2023
238dd02
Merge branch 'develop' into feature/new-gas-price-estimation
Psykepro Jun 20, 2023
b4bd054
Optimize trace (#2183) (#2206)
ToniRamirezM Jun 20, 2023
fd98a0d
New image with geth1.12.0
ARR552 Jun 20, 2023
a7bcfce
Merge branch 'feature/#2180_update_smc' into feature/new-gas-price-es…
Psykepro Jun 20, 2023
cb67baa
geth1.11.5
ARR552 Jun 20, 2023
6caabaa
Merge branch 'feature/#2180_update_smc' into feature/new-gas-price-es…
Psykepro Jun 20, 2023
f83ab0c
fix: fixing contract addresses in configs.
Psykepro Jun 20, 2023
f9ac9e5
changing zkevm-mock-l1-network image to hermeznetwork/geth-zkevm-cont…
Psykepro Jun 21, 2023
f793599
Fix/group8 (#2211)
ToniRamirezM Jun 21, 2023
52ae6c0
smc
ARR552 Jun 21, 2023
277cada
genBlockNumb
ARR552 Jun 21, 2023
c44883f
use forkID while encoding/decoding txs (#2219)
ToniRamirezM Jun 23, 2023
6eca7e0
Add effective_gas_price to receipt (#2222)
ToniRamirezM Jun 26, 2023
0097eb9
merge develop
ToniRamirezM Jun 27, 2023
77cc055
fix sql
ToniRamirezM Jun 27, 2023
4fbb91a
fix sql
ToniRamirezM Jun 27, 2023
9fb166f
fix
ToniRamirezM Jun 27, 2023
2c6cd24
fix
ToniRamirezM Jun 27, 2023
ebfbb51
fix helper
ToniRamirezM Jun 27, 2023
6e39665
fix sql
ToniRamirezM Jun 27, 2023
3454ca8
change sql
ToniRamirezM Jun 27, 2023
f63c4d9
update prover image
ToniRamirezM Jun 27, 2023
dd8a654
update prover image
ToniRamirezM Jun 28, 2023
7037bb4
effective gas price comparation (#2234)
ToniRamirezM Jun 29, 2023
837f81c
solve conflicts
ToniRamirezM Jun 29, 2023
7eee697
fix conflicts
ToniRamirezM Jun 29, 2023
c190c7e
fix conflicts
ToniRamirezM Jun 29, 2023
e69a85c
make factors floats
ToniRamirezM Jun 30, 2023
2d866e3
fix gasprice
ToniRamirezM Jun 30, 2023
3a28e89
fix gasprice
ToniRamirezM Jun 30, 2023
22648f1
Merge branch 'develop' into feature/new-gas-price-estimation
ToniRamirezM Jun 30, 2023
e8a5389
merge develop and fix conflicts
ToniRamirezM Jun 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
wip
Signed-off-by: Nikolay Nedkov <nikolai_nedkov@yahoo.com>
  • Loading branch information
Psykepro committed May 23, 2023
commit 238841bfcf011699565e6b43fb985579f88d58c3
15 changes: 7 additions & 8 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
executorpb "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor/pb"
"github.com/0xPolygonHermez/zkevm-node/synchronizer"
"github.com/ethereum/go-ethereum/common"
"github.com/jackc/pgx/v4/pgxpool"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -169,7 +168,7 @@ func start(cliCtx *cli.Context) error {
log.Fatal(err)
}
if poolInstance == nil {
poolInstance = createPool(c.Pool, c.NetworkConfig.L2BridgeAddr, l2ChainID, st, eventLog)
poolInstance = createPool(c.Pool, l2ChainID, st, eventLog)
}
seq := createSequencer(*c, poolInstance, ethTxManagerStorage, st, eventLog)
go seq.Start(ctx)
Expand All @@ -181,7 +180,7 @@ func start(cliCtx *cli.Context) error {
log.Fatal(err)
}
if poolInstance == nil {
poolInstance = createPool(c.Pool, c.NetworkConfig.L2BridgeAddr, l2ChainID, st, eventLog)
poolInstance = createPool(c.Pool, l2ChainID, st, eventLog)
}
seqSender := createSequenceSender(*c, poolInstance, ethTxManagerStorage, st, eventLog)
go seqSender.Start(ctx)
Expand All @@ -193,7 +192,7 @@ func start(cliCtx *cli.Context) error {
log.Fatal(err)
}
if poolInstance == nil {
poolInstance = createPool(c.Pool, c.NetworkConfig.L2BridgeAddr, l2ChainID, st, eventLog)
poolInstance = createPool(c.Pool, l2ChainID, st, eventLog)
}
if c.RPC.EnableL2SuggestedGasPricePolling {
// Needed for rejecting transactions with too low gas price
Expand All @@ -212,7 +211,7 @@ func start(cliCtx *cli.Context) error {
log.Fatal(err)
}
if poolInstance == nil {
poolInstance = createPool(c.Pool, c.NetworkConfig.L2BridgeAddr, l2ChainID, st, eventLog)
poolInstance = createPool(c.Pool, l2ChainID, st, eventLog)
}
go runSynchronizer(*c, etherman, etm, st, poolInstance)
case ETHTXMANAGER:
Expand All @@ -232,7 +231,7 @@ func start(cliCtx *cli.Context) error {
log.Fatal(err)
}
if poolInstance == nil {
poolInstance = createPool(c.Pool, c.NetworkConfig.L2BridgeAddr, l2ChainID, st, eventLog)
poolInstance = createPool(c.Pool, l2ChainID, st, eventLog)
}
go runL2GasPriceSuggester(c.L2GasPriceSuggester, st, poolInstance, etherman)
}
Expand Down Expand Up @@ -422,13 +421,13 @@ func newState(ctx context.Context, c *config.Config, l2ChainID uint64, forkIDInt
return st
}

func createPool(cfgPool pool.Config, l2BridgeAddr common.Address, l2ChainID uint64, st *state.State, eventLog *event.EventLog) *pool.Pool {
func createPool(cfgPool pool.Config, l2ChainID uint64, st *state.State, eventLog *event.EventLog) *pool.Pool {
runPoolMigrations(cfgPool.DB)
poolStorage, err := pgpoolstorage.NewPostgresPoolStorage(cfgPool.DB)
if err != nil {
log.Fatal(err)
}
poolInstance := pool.NewPool(cfgPool, poolStorage, st, l2BridgeAddr, l2ChainID, eventLog)
poolInstance := pool.NewPool(cfgPool, poolStorage, st, l2ChainID, eventLog)
return poolInstance
}

Expand Down
5 changes: 5 additions & 0 deletions db/migrations/pool/0009.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- +migrate Up
ALTER TABLE pool.transaction ADD COLUMN break_even_gas_price DECIMAL(78, 0);

-- +migrate Down
ALTER TABLE pool.transaction DROP COLUMN break_even_gas_price;
22 changes: 22 additions & 0 deletions gasprice/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,26 @@ type Config struct {
Percentile int `mapstructure:"Percentile"`
UpdatePeriod types.Duration `mapstructure:"UpdatePeriod"`
Factor float64 `mapstructure:"Factor"`

// BreakEvenGasPriceCalcCfg is the configuration for the break even gas price calculation
BreakEvenGasPriceCalcCfg BreakEvenGasPriceCalculationCfg `mapstructure:"BreakEvenGasPriceCalculationCfg"`
}

// BreakEvenGasPriceCalculationCfg has parameters for the gas price calculation.
// TODO: Add config tests
type BreakEvenGasPriceCalculationCfg struct {
// L1GasPricePercentageForL2MinPrice is the percentage of the L1 gas price that will be used as the L2 min gas price
L1GasPricePercentageForL2MinPrice uint64 `mapstructure:"L1GasPricePercentageForL2MinPrice"`

// ByteGasCost is the gas cost per byte
ByteGasCost uint64 `mapstructure:"ByteGasCost"`

// MarginFactorPercentage is the margin factor percentage to be added to the L2 min gas price
MarginFactorPercentage uint64 `mapstructure:"MarginFactorPercentage"`

// TxPriceGuaranteePeriod is the period of time that the gas price will be guaranteed
TxPriceGuaranteePeriod types.Duration `mapstructure:"TxPriceGuaranteePeriod"`

// MaxBreakEvenGasPriceDeviationPercentage is the max allowed deviation percentage BreakEvenGasPrice on re-calculation
MaxBreakEvenGasPriceDeviationPercentage float64 `mapstructure:"MaxBreakEvenGasPriceDeviationPercentage"`
}
1 change: 1 addition & 0 deletions jsonrpc/types/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ type StateInterface interface {
GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error)
GetVerifiedBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VerifiedBatch, error)
GetExitRootByGlobalExitRoot(ctx context.Context, ger common.Hash, dbTx pgx.Tx) (*state.GlobalExitRoot, error)
PreProcessTransaction(ctx context.Context, tx *types.Transaction, dbTx pgx.Tx) (*state.ProcessBatchResponse, error)
}
19 changes: 19 additions & 0 deletions pool/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,23 @@ type Config struct {

// PollMinAllowedGasPriceInterval is the interval to poll the suggested min gas price for a tx
PollMinAllowedGasPriceInterval types.Duration `mapstructure:"PollMinAllowedGasPriceInterval"`

// GasPriceEstimationCfg is the configuration for the gas price estimation
GasPriceEstimationCfg GasPriceEstimationConfig `mapstructure:"GasPriceEstimationConfig"`
}

// GasPriceEstimationConfig has parameters for the gas price calculation.
// TODO: Add config tests
type GasPriceEstimationConfig struct {
// L1GasPricePercentageForL2MinPrice is the percentage of the L1 gas price that will be used as the L2 min gas price
L1GasPricePercentageForL2MinPrice uint64 `mapstructure:"L1GasPricePercentageForL2MinPrice"`

// ByteGasCost is the gas cost per byte
ByteGasCost uint64 `mapstructure:"ByteGasCost"`

// MarginFactorPercentage is the margin factor percentage to be added to the L2 min gas price
MarginFactorPercentage uint64 `mapstructure:"MarginFactorPercentage"`

// TxPriceGuaranteePeriod is the period of time that the gas price will be guaranteed
TxPriceGuaranteePeriod types.Duration `mapstructure:"TxPriceGuaranteePeriod"`
}
11 changes: 7 additions & 4 deletions pool/pgpoolstorage/pgpoolstorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@ func (p *PostgresPoolStorage) AddTx(ctx context.Context, tx pool.Transaction) er
received_at,
from_address,
is_wip,
ip
ip,
break_even_gas_price
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)
ON CONFLICT (hash) DO UPDATE SET
encoded = $2,
decoded = $3,
Expand All @@ -94,7 +95,8 @@ func (p *PostgresPoolStorage) AddTx(ctx context.Context, tx pool.Transaction) er
received_at = $15,
from_address = $16,
is_wip = $17,
ip = $18
ip = $18,
break_even_gas_price = $19
`

// Get FromAddress from the JSON data
Expand Down Expand Up @@ -122,7 +124,8 @@ func (p *PostgresPoolStorage) AddTx(ctx context.Context, tx pool.Transaction) er
tx.ReceivedAt,
fromAddress,
tx.IsWIP,
tx.IP); err != nil {
tx.IP,
tx.BreakEvenGasPrice); err != nil {
return err
}
return nil
Expand Down
76 changes: 63 additions & 13 deletions pool/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ var (
ErrReplaceUnderpriced = errors.New("replacement transaction underpriced")
)

const (
signatureBytesLength = 65
effectivePercentageBytesLength = 1
txDataBytesLength = signatureBytesLength + effectivePercentageBytesLength
)

// Pool is an implementation of the Pool interface
// that uses a postgres database to store the data
type Pool struct {
Expand All @@ -42,17 +48,19 @@ type Pool struct {
minSuggestedGasPrice *big.Int
minSuggestedGasPriceMux *sync.RWMutex
eventLog *event.EventLog
totalBytesGasCost uint64
}

type preExecutionResponse struct {
usedZkCounters state.ZKCounters
isOOC bool
isOOG bool
isReverted bool
txResponse *state.ProcessTransactionResponse
}

// NewPool creates and initializes an instance of Pool
func NewPool(cfg Config, s storage, st stateInterface, l2BridgeAddr common.Address, chainID uint64, eventLog *event.EventLog) *Pool {
func NewPool(cfg Config, s storage, st stateInterface, chainID uint64, eventLog *event.EventLog) *Pool {
p := &Pool{
cfg: cfg,
storage: s,
Expand All @@ -61,6 +69,7 @@ func NewPool(cfg Config, s storage, st stateInterface, l2BridgeAddr common.Addre
blockedAddresses: sync.Map{},
minSuggestedGasPriceMux: new(sync.RWMutex),
eventLog: eventLog,
totalBytesGasCost: txDataBytesLength * cfg.GasPriceEstimationCfg.ByteGasCost,
}

p.refreshBlockedAddresses()
Expand Down Expand Up @@ -121,8 +130,7 @@ func (p *Pool) StartPollingMinSuggestedGasPrice(ctx context.Context) {

// AddTx adds a transaction to the pool with the pending state
func (p *Pool) AddTx(ctx context.Context, tx types.Transaction, ip string) error {
poolTx := NewTransaction(tx, ip, false, p)
if err := p.validateTx(ctx, *poolTx); err != nil {
if err := p.validateTx(ctx, tx); err != nil {
return err
}

Expand All @@ -131,11 +139,10 @@ func (p *Pool) AddTx(ctx context.Context, tx types.Transaction, ip string) error

// StoreTx adds a transaction to the pool with the pending state
func (p *Pool) StoreTx(ctx context.Context, tx types.Transaction, ip string, isWIP bool) error {
poolTx := NewTransaction(tx, ip, isWIP, p)
// Execute transaction to calculate its zkCounters
preExecutionResponse, err := p.PreExecuteTx(ctx, tx)
preExecutionResponse, err := p.preExecuteTx(ctx, tx)
if err != nil {
log.Debugf("PreExecuteTx error (this can be ignored): %v", err)
log.Debugf("preExecuteTx error (this can be ignored): %v", err)
}

if preExecutionResponse.isOOC {
Expand Down Expand Up @@ -172,15 +179,23 @@ func (p *Pool) StoreTx(ctx context.Context, tx types.Transaction, ip string, isW
}
}

breakEvenGasPrice, err := p.estimateTxBreakEvenGasPrice(ctx, preExecutionResponse)
if err != nil {
err = fmt.Errorf("error estimating break even gas price. err: %w", err)
log.Error(err)
return err
}
poolTx := NewTransaction(tx, ip, isWIP, breakEvenGasPrice)
poolTx.ZKCounters = preExecutionResponse.usedZkCounters

return p.storage.AddTx(ctx, *poolTx)
}

// PreExecuteTx executes a transaction to calculate its zkCounters
func (p *Pool) PreExecuteTx(ctx context.Context, tx types.Transaction) (preExecutionResponse, error) {
// preExecuteTx executes a transaction to calculate its zkCounters
func (p *Pool) preExecuteTx(ctx context.Context, tx types.Transaction) (preExecutionResponse, error) {
response := preExecutionResponse{usedZkCounters: state.ZKCounters{}, isOOC: false, isOOG: false, isReverted: false}

// TODO: Add effectivePercentage = 0xFF to the request (factor of 1) when gRPC message is updated
processBatchResponse, err := p.state.PreProcessTransaction(ctx, &tx, nil)
if err != nil {
return response, err
Expand All @@ -192,6 +207,7 @@ func (p *Pool) PreExecuteTx(ctx context.Context, tx types.Transaction) (preExecu
response.isOOC = executor.IsROMOutOfCountersError(executor.RomErrorCode(errorToCheck))
response.isOOG = errors.Is(errorToCheck, runtime.ErrOutOfGas)
response.usedZkCounters = processBatchResponse.UsedZkCounters
response.txResponse = processBatchResponse.Responses[0]
}

return response, nil
Expand Down Expand Up @@ -253,7 +269,7 @@ func (p *Pool) IsTxPending(ctx context.Context, hash common.Hash) (bool, error)
return p.storage.IsTxPending(ctx, hash)
}

func (p *Pool) validateTx(ctx context.Context, poolTx Transaction) error {
func (p *Pool) validateTx(ctx context.Context, poolTx types.Transaction) error {
// check chain id
txChainID := poolTx.ChainId().Uint64()
if txChainID != p.chainID && txChainID != 0 {
Expand Down Expand Up @@ -284,10 +300,10 @@ func (p *Pool) validateTx(ctx context.Context, poolTx Transaction) error {
return ErrNegativeValue
}
// Make sure the transaction is signed properly.
if err := state.CheckSignature(poolTx.Transaction); err != nil {
if err := state.CheckSignature(poolTx); err != nil {
return ErrInvalidSender
}
from, err := state.GetSender(poolTx.Transaction)
from, err := state.GetSender(poolTx)
if err != nil {
return ErrInvalidSender
}
Expand Down Expand Up @@ -324,7 +340,7 @@ func (p *Pool) validateTx(ctx context.Context, poolTx Transaction) error {
}

// Ensure the transaction has more gas than the basic poolTx fee.
intrGas, err := IntrinsicGas(poolTx.Transaction)
intrGas, err := IntrinsicGas(poolTx)
if err != nil {
return err
}
Expand Down Expand Up @@ -362,7 +378,7 @@ func (p *Pool) validateTx(ctx context.Context, poolTx Transaction) error {
}

// Executor field size requirements check
if err := p.checkTxFieldCompatibilityWithExecutor(ctx, poolTx.Transaction); err != nil {
if err := p.checkTxFieldCompatibilityWithExecutor(ctx, poolTx); err != nil {
return err
}

Expand Down Expand Up @@ -440,6 +456,40 @@ func (p *Pool) UpdateTxWIPStatus(ctx context.Context, hash common.Hash, isWIP bo
return p.storage.UpdateTxWIPStatus(ctx, hash, isWIP)
}

func (p *Pool) estimateTxBreakEvenGasPrice(ctx context.Context, preExecutionResp preExecutionResponse) (uint64, error) {
gasUsed := preExecutionResp.txResponse.GasUsed
l1GasPrice, l2MinGasPrice, err := p.getL1GasPriceAndL2MinGasPrice(ctx)
if err != nil {
return 0, err
}
if l1GasPrice == 0 || l2MinGasPrice == 0 {
return 0, fmt.Errorf("failed to get L1 Gas Price and L2 Min Gas Price")

}
totalTxPrice := (gasUsed * l2MinGasPrice) + (p.totalBytesGasCost * l1GasPrice)
breakEvenGasPrice := ((totalTxPrice / gasUsed) * p.cfg.GasPriceEstimationCfg.MarginFactorPercentage) / 100

return breakEvenGasPrice, nil
}

func (p *Pool) getL1GasPriceAndL2MinGasPrice(ctx context.Context) (l1GasPrice uint64, l2MinGasPrice uint64, err error) {
// Get L1 Gas Price
l1GasPrice, err = p.GetGasPrice(ctx)
if err != nil {
log.Warn(fmt.Sprintf("Failed to get L1 gas price: %v", err))
return 0, 0, err
}
if l1GasPrice == 0 {
log.Warn("Received L1 gas price 0. Skipping estimation...")
return 0, 0, errors.New("received L1 gas price 0")
}

// Calculate L2 Min Gas Price
l2MinGasPrice = (l1GasPrice * p.cfg.GasPriceEstimationCfg.L1GasPricePercentageForL2MinPrice) / 100

return l1GasPrice, l2MinGasPrice, nil
}

const (
txDataNonZeroGas uint64 = 16
txGasContractCreation uint64 = 53000
Expand Down
6 changes: 3 additions & 3 deletions pool/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func Test_AddTx_OversizedData(t *testing.T) {
require.NoError(t, err)

const chainID = 2576980377
p := pool.NewPool(cfg, s, st, common.Address{}, chainID, eventLog)
p := pool.NewPool(cfg, s, st, chainID, eventLog)

b := make([]byte, cfg.MaxTxBytesSize+1)
to := common.HexToAddress(operations.DefaultSequencerAddress)
Expand Down Expand Up @@ -647,7 +647,7 @@ func Test_SetAndGetGasPrice(t *testing.T) {
require.NoError(t, err)
eventLog := event.NewEventLog(event.Config{}, eventStorage)

p := pool.NewPool(cfg, s, nil, common.Address{}, chainID.Uint64(), eventLog)
p := pool.NewPool(cfg, s, nil, chainID.Uint64(), eventLog)

nBig, err := rand.Int(rand.Reader, big.NewInt(0).SetUint64(math.MaxUint64))
require.NoError(t, err)
Expand Down Expand Up @@ -1384,7 +1384,7 @@ func Test_BlockedAddress(t *testing.T) {
}

func setupPool(t *testing.T, cfg pool.Config, s *pgpoolstorage.PostgresPoolStorage, st *state.State, chainID uint64, ctx context.Context, eventLog *event.EventLog) *pool.Pool {
p := pool.NewPool(cfg, s, st, l2BridgeAddr, chainID, eventLog)
p := pool.NewPool(cfg, s, st, chainID, eventLog)

err := p.SetGasPrice(ctx, gasPrice.Uint64())
require.NoError(t, err)
Expand Down
14 changes: 8 additions & 6 deletions pool/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,18 @@ type Transaction struct {
IsWIP bool
IP string
FailedReason *string
BreakEvenGasPrice uint64
}

// NewTransaction creates a new transaction
func NewTransaction(tx types.Transaction, ip string, isWIP bool, p *Pool) *Transaction {
func NewTransaction(tx types.Transaction, ip string, isWIP bool, breakEvenGasPrice uint64) *Transaction {
poolTx := Transaction{
Transaction: tx,
Status: TxStatusPending,
ReceivedAt: time.Now(),
IsWIP: isWIP,
IP: ip,
Transaction: tx,
Status: TxStatusPending,
ReceivedAt: time.Now(),
IsWIP: isWIP,
IP: ip,
BreakEvenGasPrice: breakEvenGasPrice,
}

return &poolTx
Expand Down
Loading