-
Notifications
You must be signed in to change notification settings - Fork 432
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
Fix/6790 return accepted for rejected tx added to broadcast #6889
Changes from 19 commits
ca922d9
1e4670a
401e318
13a767a
919bd2d
14e8b79
7936a1e
ca67a97
6d0a22c
7dfbdb6
4757f6f
018afc9
be126f5
b64dd50
3c19462
926c381
f8546dd
c695cc5
8360abc
031d15e
f97394e
a6150f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -505,7 +505,7 @@ public void should_add_underpaid_txs_to_full_TxPool_only_if_local(bool isLocal) | |
AcceptTxResult result = _txPool.SubmitTx(tx, txHandlingOptions); | ||
_txPool.GetPendingTransactionsCount().Should().Be(30); | ||
_txPool.GetOwnPendingTransactions().Length.Should().Be(isLocal ? 1 : 0); | ||
result.ToString().Should().Contain(isLocal ? nameof(AcceptTxResult.FeeTooLowToCompete) : nameof(AcceptTxResult.FeeTooLow)); | ||
result.ToString().Should().Contain(isLocal ? nameof(AcceptTxResult.Accepted) : nameof(AcceptTxResult.FeeTooLow)); | ||
} | ||
|
||
[TestCase(0)] | ||
|
@@ -1381,7 +1381,7 @@ public void should_increase_nonce_when_transaction_not_included_in_txPool_but_br | |
.WithMaxFeePerGas(1) | ||
.WithMaxPriorityFeePerGas(1) | ||
.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; | ||
_txPool.SubmitTx(cheapTx, TxHandlingOptions.PersistentBroadcast).Should().Be(AcceptTxResult.FeeTooLowToCompete); | ||
_txPool.SubmitTx(cheapTx, TxHandlingOptions.PersistentBroadcast).Should().Be(AcceptTxResult.Accepted); | ||
_txPool.GetPendingTransactions().Should().NotContain(cheapTx); | ||
_txPool.GetOwnPendingTransactions().Should().Contain(cheapTx); | ||
peer.Received().SendNewTransaction(cheapTx); | ||
|
@@ -1393,7 +1393,7 @@ public void should_increase_nonce_when_transaction_not_included_in_txPool_but_br | |
.WithMaxFeePerGas(1) | ||
.WithMaxPriorityFeePerGas(1) | ||
.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; | ||
_txPool.SubmitTx(fourthTx, TxHandlingOptions.PersistentBroadcast).Should().Be(AcceptTxResult.FeeTooLowToCompete); | ||
_txPool.SubmitTx(fourthTx, TxHandlingOptions.PersistentBroadcast).Should().Be(AcceptTxResult.Accepted); | ||
_txPool.GetPendingTransactions().Should().NotContain(fourthTx); | ||
_txPool.GetOwnPendingTransactions().Should().Contain(fourthTx); | ||
peer.Received().SendNewTransaction(fourthTx); | ||
|
@@ -1638,6 +1638,50 @@ public void Should_not_add_underpaid_tx_even_if_lower_nonces_are_expensive(int g | |
result.Should().Be(expectedResult ? AcceptTxResult.Accepted : AcceptTxResult.FeeTooLowToCompete); | ||
} | ||
|
||
[TestCase(TxType.Legacy, true)] | ||
[TestCase(TxType.EIP1559, true)] | ||
[TestCase(TxType.Blob, false)] | ||
public void Should_correctly_add_tx_to_local_pool_when_underpaid(TxType txType, bool expectedResult) | ||
{ | ||
// Should only add legacy and 1559 local transactions to local pool when underpaid | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. applied |
||
ISpecProvider specProvider = GetCancunSpecProvider(); | ||
TxPoolConfig txPoolConfig = new TxPoolConfig { Size = 30, PersistentBlobStorageSize = 0 }; | ||
_txPool = CreatePool(txPoolConfig, specProvider); | ||
|
||
Transaction[] transactions = GetTransactions(GetPeers(3), true, false); | ||
|
||
foreach (Address address in transactions.Select(t => t.SenderAddress).Distinct()) | ||
{ | ||
EnsureSenderBalance(address, UInt256.MaxValue); | ||
} | ||
|
||
// setup full tx pool | ||
foreach (Transaction transaction in transactions) | ||
{ | ||
transaction.GasPrice = 10.GWei(); | ||
_txPool.SubmitTx(transaction, TxHandlingOptions.None); | ||
} | ||
|
||
_txPool.GetPendingTransactionsCount().Should().Be(30); | ||
|
||
Transaction testTx = Build.A.Transaction | ||
.WithNonce(0) | ||
.WithType(txType) | ||
.WithShardBlobTxTypeAndFieldsIfBlobTx() | ||
.WithMaxFeePerGas(9.GWei()) | ||
.WithMaxPriorityFeePerGas(9.GWei()) | ||
.WithTo(TestItem.AddressB) | ||
.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; | ||
|
||
EnsureSenderBalance(TestItem.PrivateKeyA.Address, UInt256.MaxValue); | ||
|
||
AcceptTxResult result = _txPool.SubmitTx(testTx, TxHandlingOptions.PersistentBroadcast); | ||
result.Should().Be(expectedResult ? AcceptTxResult.Accepted : AcceptTxResult.FeeTooLowToCompete); | ||
_txPool.GetOwnPendingTransactions().Length.Should().Be(expectedResult ? 1 : 0); | ||
_txPool.GetPendingBlobTransactionsCount().Should().Be(0); | ||
_txPool.GetPendingTransactions().Should().NotContain(testTx); | ||
} | ||
|
||
private IDictionary<ITxPoolPeer, PrivateKey> GetPeers(int limit = 100) | ||
{ | ||
var peers = new Dictionary<ITxPoolPeer, PrivateKey>(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,31 +97,33 @@ public TxBroadcaster(IComparer<Transaction> comparer, | |
// only for testing reasons | ||
internal Transaction[] GetSnapshot() => _persistentTxs.GetSnapshot(); | ||
|
||
public void Broadcast(Transaction tx, bool isPersistent) | ||
public bool Broadcast(Transaction tx, bool isPersistent) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor cosmetic: would be good to rename method, right now we are not calling it if we want to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth to consider before merging |
||
{ | ||
if (isPersistent) | ||
{ | ||
StartBroadcast(tx); | ||
} | ||
else | ||
{ | ||
BroadcastOnce(tx); | ||
return StartBroadcast(tx); | ||
} | ||
|
||
BroadcastOnce(tx); | ||
|
||
return true; | ||
} | ||
|
||
private void StartBroadcast(Transaction tx) | ||
private bool StartBroadcast(Transaction tx) | ||
{ | ||
// broadcast local tx only if MaxFeePerGas is not lower than configurable percent of current base fee | ||
// (70% by default). Otherwise only add to persistent txs and broadcast when tx will be ready for inclusion | ||
if (tx.MaxFeePerGas >= _baseFeeThreshold || tx.IsFree()) | ||
|
||
if (tx is not null | ||
&& (tx.MaxFeePerGas >= _baseFeeThreshold || tx.IsFree()) | ||
&& _persistentTxs.TryInsert(tx.Hash, tx.SupportsBlobs ? new LightTransaction(tx) : tx, out Transaction? removed) | ||
&& removed?.Hash != tx.Hash) | ||
{ | ||
NotifyPeersAboutLocalTx(tx); | ||
return true; | ||
} | ||
|
||
if (tx.Hash is not null) | ||
{ | ||
_persistentTxs.TryInsert(tx.Hash, tx.SupportsBlobs ? new LightTransaction(tx) : tx); | ||
} | ||
return false; | ||
} | ||
|
||
private void BroadcastOnce(Transaction tx) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -450,14 +450,17 @@ private AcceptTxResult AddCore(Transaction tx, TxFilteringState state, bool isPe | |
if (tx.Hash == removed?.Hash) | ||
{ | ||
// it means it was added and immediately evicted - pool was full of better txs | ||
if (isPersistentBroadcast) | ||
if (!isPersistentBroadcast || tx.SupportsBlobs || !_broadcaster.Broadcast(tx, true)) | ||
{ | ||
// we are adding only to persistent broadcast - not good enough for standard pool, | ||
// but can be good enough for TxBroadcaster pool - for local txs only | ||
_broadcaster.Broadcast(tx, isPersistentBroadcast); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what happened to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the if branch now has the opposite condition, if the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if running through all the normal flow here is best choice as this is a special case, when something we are not adding to main pool will have broadcasting, will wait for @marcindsobczak opinion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a good option, we definitely don't want to run through all the normal flow here |
||
Metrics.PendingTransactionsPassedFiltersButCannotCompeteOnFees++; | ||
return AcceptTxResult.FeeTooLowToCompete; | ||
} | ||
else | ||
{ | ||
return AcceptTxResult.Accepted; | ||
} | ||
Metrics.PendingTransactionsPassedFiltersButCannotCompeteOnFees++; | ||
return AcceptTxResult.FeeTooLowToCompete; | ||
} | ||
|
||
relevantPool.UpdateGroup(tx.SenderAddress!, state.SenderAccount, UpdateBucketWithAddedTransaction); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and
[TestCase(TxType.AccessList, true)]
to have all typesThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe better to have TestCaseSource and generate test cases for all enum items, by default with
true
and just have exception for blobs. In that case if we add new tx type we will by default have a test that expectstrue
here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed the test accordingly to check all the values of
TxType
.