Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eth: do not add failed tx to localTxTracker #31202

Merged
merged 6 commits into from
Mar 1, 2025

Conversation

laggu
Copy link
Contributor

@laggu laggu commented Feb 18, 2025

check if tx is successful before add tx to localTxTracker.

As localTxTracker keep tx and tries to add the tx to txpool, it can make failed rpc tx to success in some case
which is confused for developer.


example

rpc failed due to insufficient funds for gas.
developer might think the tx was not accepted by node but the tx is in localTxTracker
after developer send eth to the address for gas, the tx in localTxTracker will be in block

@MariusVanDerWijden
Copy link
Member

WDYT about doing it like this:

	if err := b.eth.txPool.Add([]*types.Transaction{signedTx}, false)[0]; err != nil {
	    return err
	}
	if locals := b.eth.localTxTracker; locals != nil {
		locals.Track(signedTx)
	}
	return nil

@rjl493456442
Copy link
Member

rjl493456442 commented Feb 18, 2025

Thanks for catching it.

Unfortunately it's a bit more complicated. The error could occur in several different circumstances,
e.g. invalid gas limit, low gas price, already known transaction and so on.

We should prevent tracking invalid transactions, like with invalid gas limit. But for the transactions
with low gas price, they should be tracked and be resubmitted later.

@holiman
Copy link
Contributor

holiman commented Feb 18, 2025 via email

@MariusVanDerWijden
Copy link
Member

Yep sorry, I checked it again and I agree with Martin. In the case of an underpriced transaction, the tx should still be added to the locals tracker. Maybe we should return a special error in that case to make the user aware that the transaction had a runtime error but is still being tracked

@laggu
Copy link
Contributor Author

laggu commented Feb 19, 2025

Afaicr, the localstracker doesn't track invalid txs, already. I think this PR basically makes the localstracker totally moot/unused. Seems wrong to me

I might be wrong but I cannot find localstracker checking if tx is invalid from below file
https://github.com/ethereum/go-ethereum/blob/dab746b3efb24954a9d556e910a53fe527846bf4/core/txpool/locals/tx_tracker.go

@laggu
Copy link
Contributor Author

laggu commented Feb 21, 2025

Yep sorry, I checked it again and I agree with Martin. In the case of an underpriced transaction, the tx should still be added to the locals tracker. Maybe we should return a special error in that case to make the user aware that the transaction had a runtime error but is still being tracked

As a web3 developer, speical state that a transaction returns error but it can be added to a block in the future is very confusing
error is an error. I think web3 developer should handle error case (include underpriced transaction)

@rjl493456442
Copy link
Member

@MariusVanDerWijden PTAL

Copy link
Member

@MariusVanDerWijden MariusVanDerWijden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes LGTM

@@ -88,6 +88,11 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) {
if tx.Type() == types.BlobTxType {
continue
}
// Ignore the transactions which are failed for fundamental
// validation such as invalid parameters.
if tracker.pool.ValidateTxBasics(tx) != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should maybe add tracing log here, so we can see why a transaction was not tracked

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of log do you prefer? Info or Debug?

I am a bit concerned the Info logs might be overwhelming for certain types of node, e.g. rpc node.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug

// available slot), an error will be returned to the user. However, locally
// submitted transactions may be resubmitted later via the local tracker, which
// could cause confusion that a previously "rejected" transaction is later
// accepted.
return b.eth.txPool.Add([]*types.Transaction{signedTx}, false)[0]
Copy link
Contributor

@fjl fjl Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So let's not return the error here!
We should instead return the error from locals.Track if there is one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems it's getting difficult to know a transaction has error or not...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. As localTxPool feature can be disabled by --txpool.nolocals flag
please return error like now when the flag is on

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -88,6 +88,11 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) {
if tx.Type() == types.BlobTxType {
continue
}
// Ignore the transactions which are failed for fundamental
// validation such as invalid parameters.
if tracker.pool.ValidateTxBasics(tx) != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tx can stay local tx pool forever
seems it need more logic like retry count

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local transactions won’t remain stuck in the transaction pool indefinitely.

If a transaction fails stateful checks—such as the pool being full or the gas price being too low to replace an existing transaction—it will be resubmitted. However, we know that the state of the tx pool will change over time, meaning the locally tracked transaction may or may not be accepted quickly.

If the transaction has a relatively low gas price (but still higher than the minimum enforced by the node operator), it may remain stuck. This aligns with the original behavior of retaining local transactions. The only way to unblock it is by replacing it with a transaction that has a higher gas price.

Additionally, resubmitting the transaction every minute is not CPU-intensive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I was concerned is not cpu but memory.
It can cause memory leak as tx can reamin localTxTracker in some case

Attackers can use it to stop nodes by OOM killed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local tracker only takes care the transactions submitted via the RPC endpoints, not the ones from the p2p network.

The node operators are supposed to take care of the node by themselves and can disable the local notion with public endpoints, e.g. infura node.

@fjl fjl added this to the 1.15.4 milestone Feb 28, 2025
@fjl fjl merged commit ebc3232 into ethereum:master Mar 1, 2025
1 of 2 checks passed
@laggu laggu deleted the local-tx-tracker branch March 3, 2025 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants