예제 #1
0
    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);
    }
}
예제 #2
0
    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);
    }
예제 #3
0
    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));
    }
예제 #4
0
        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> >();
        }
예제 #5
0
        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>));
        }