public void should_pick_tx_with_lowest_nonce_from_bucket() { _txPoolConfig = new TxPoolConfig() { PeerNotificationThreshold = 5 }; _broadcaster = new TxBroadcaster(_comparer, TimerFactory.Default, _txPoolConfig, _headInfo, _logManager); _headInfo.CurrentBaseFee.Returns(0.GWei()); const int addedTxsCount = 5; Transaction[] transactions = new Transaction[addedTxsCount]; for (int i = 0; i < addedTxsCount; i++) { transactions[i] = Build.A.Transaction .WithNonce((UInt256)i) .WithGasPrice(i.GWei()) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA) .TestObject; _broadcaster.Broadcast(transactions[i], true); } _broadcaster.GetSnapshot().Length.Should().Be(addedTxsCount); IList <Transaction> pickedTxs = _broadcaster.GetPersistentTxsToSend(); pickedTxs.Count.Should().Be(1); List <Transaction> expectedTxs = new() { transactions[0] }; expectedTxs.Should().BeEquivalentTo(pickedTxs); } }
public void should_pick_best_persistent_txs_to_broadcast(int threshold) { _txPoolConfig = new TxPoolConfig() { PeerNotificationThreshold = threshold }; _broadcaster = new TxBroadcaster(_comparer, TimerFactory.Default, _txPoolConfig, _headInfo, _logManager); _headInfo.CurrentBaseFee.Returns(0.GWei()); int addedTxsCount = TestItem.PrivateKeys.Length; Transaction[] transactions = new Transaction[addedTxsCount]; for (int i = 0; i < addedTxsCount; i++) { transactions[i] = Build.A.Transaction .WithGasPrice(i.GWei()) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeys[i]) .TestObject; _broadcaster.Broadcast(transactions[i], true); } _broadcaster.GetSnapshot().Length.Should().Be(addedTxsCount); List <Transaction> pickedTxs = _broadcaster.GetPersistentTxsToSend().ToList(); int expectedCount = threshold <= 0 ? 0 : addedTxsCount; pickedTxs.Count.Should().Be(expectedCount); }
public void should_not_pick_1559_txs_with_MaxFeePerGas_lower_than_CurrentBaseFee(int threshold) { _txPoolConfig = new TxPoolConfig() { PeerNotificationThreshold = threshold }; _broadcaster = new TxBroadcaster(_comparer, TimerFactory.Default, _txPoolConfig, _headInfo, _logManager); const int currentBaseFeeInGwei = 250; _headInfo.CurrentBaseFee.Returns(currentBaseFeeInGwei.GWei()); Block headBlock = Build.A.Block .WithNumber(RopstenSpecProvider.LondonBlockNumber) .WithBaseFeePerGas(currentBaseFeeInGwei.GWei()) .TestObject; _blockTree.Head.Returns(headBlock); int addedTxsCount = TestItem.PrivateKeys.Length; Transaction[] transactions = new Transaction[addedTxsCount]; for (int i = 0; i < addedTxsCount; i++) { transactions[i] = Build.A.Transaction .WithType(TxType.EIP1559) .WithMaxFeePerGas(i.GWei()) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeys[i]) .TestObject; _broadcaster.Broadcast(transactions[i], true); } _broadcaster.GetSnapshot().Length.Should().Be(addedTxsCount); IList <Transaction> pickedTxs = _broadcaster.GetPersistentTxsToSend(); int expectedCount = Math.Min(addedTxsCount * threshold / 100 + 1, addedTxsCount - currentBaseFeeInGwei); pickedTxs.Count.Should().Be(expectedCount); List <Transaction> expectedTxs = new(); for (int i = 1; i <= expectedCount; i++) { expectedTxs.Add(transactions[addedTxsCount - i]); } expectedTxs.Should().BeEquivalentTo(pickedTxs, o => o.Excluding(transaction => transaction.MaxFeePerGas)); }
public TxCompletion( BlockChain <TAction> blockChain, TxFetcher txFetcher, TxBroadcaster txBroadcaster) { _txSyncTasks = new ConcurrentDictionary <TPeer, Task>(); _requiredTxIds = new ConcurrentDictionary <TPeer, ConcurrentBag <TxId> >(); _cancellationTokenSource = new CancellationTokenSource(); _blockChain = blockChain; _txFetcher = txFetcher; _txBroadcaster = txBroadcaster; TxReceived = new AsyncAutoResetEvent(); _logger = Log.ForContext <TxCompletion <TPeer, TAction> >(); }
public TxCompletion( BlockChain <TAction> blockChain, TxFetcher txFetcher, TxBroadcaster txBroadcaster) { _cancellationTokenSource = new CancellationTokenSource(); _blockChain = blockChain; _txFetcher = txFetcher; _txBroadcaster = txBroadcaster; TxReceived = new AsyncAutoResetEvent(); _logger = Log .ForContext <TxCompletion <TPeer, TAction> >() .ForContext("Source", nameof(TxCompletion <TPeer, TAction>)); }