Skip to content

Commit

Permalink
Fix/eth subscription base fee per gas missing (#3810)
Browse files Browse the repository at this point in the history
* Added missing parameter.

* Added test.

* Deleted unnecessary comment.

* Refactored code.

* Refactor API

* cleanup

* API fix

Co-authored-by: lukasz.rozmej <lukasz.rozmej@gmail.com>
  • Loading branch information
kjazgar and LukaszRozmej authored Feb 11, 2022
1 parent e99aa63 commit 66d4268
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 28 deletions.
3 changes: 2 additions & 1 deletion src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ public virtual async Task Execute(CancellationToken cancellationToken)
_api.TxPool,
_api.ReceiptStorage,
_api.FilterStore,
_api.EthSyncingInfo!);
_api.EthSyncingInfo!,
_api.SpecProvider);

SubscriptionManager subscriptionManager = new(subscriptionFactory, _api.LogManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Receipts;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.Core.Test.Builders;
using Nethermind.Db;
using Nethermind.Db.Blooms;
Expand Down Expand Up @@ -57,6 +58,7 @@ public class SubscribeModuleTests
private ISubscriptionManager _subscriptionManager;
private IJsonRpcDuplexClient _jsonRpcDuplexClient;
private IJsonSerializer _jsonSerializer;
private ISpecProvider _specProvider;

[SetUp]
public void Setup()
Expand All @@ -65,6 +67,7 @@ public void Setup()
_blockTree = Substitute.For<IBlockTree>();
_txPool = Substitute.For<ITxPool>();
_receiptStorage = Substitute.For<IReceiptStorage>();
_specProvider = Substitute.For<ISpecProvider>();
_filterStore = new FilterStore();
_jsonRpcDuplexClient = Substitute.For<IJsonRpcDuplexClient>();
_jsonSerializer = new EthereumJsonSerializer();
Expand All @@ -75,7 +78,8 @@ public void Setup()
_txPool,
_receiptStorage,
_filterStore,
new EthSyncingInfo(_blockTree));
new EthSyncingInfo(_blockTree),
_specProvider);

_subscriptionManager = new SubscriptionManager(
subscriptionFactory,
Expand All @@ -93,7 +97,7 @@ public void Setup()

private JsonRpcResult GetBlockAddedToMainResult(BlockReplacementEventArgs blockReplacementEventArgs, out string subscriptionId, Filter filter = null)
{
NewHeadSubscription newHeadSubscription = new(_jsonRpcDuplexClient, _blockTree, _logManager, filter);
NewHeadSubscription newHeadSubscription = new(_jsonRpcDuplexClient, _blockTree, _logManager, _specProvider, filter);

JsonRpcResult jsonRpcResult = new();

Expand Down Expand Up @@ -244,7 +248,7 @@ public void NewHeadSubscription_on_BlockAddedToMain_event2()
IncludeTransactions = true
};

JsonRpcResult jsonRpcResult = GetBlockAddedToMainResult(blockReplacementEventArgs, out var subscriptionId, filter);
JsonRpcResult jsonRpcResult = GetBlockAddedToMainResult(blockReplacementEventArgs, out string subscriptionId, filter);

jsonRpcResult.Response.Should().NotBeNull();
string serialized = _jsonSerializer.Serialize(jsonRpcResult.Response);
Expand All @@ -258,7 +262,7 @@ public void NewHeadSubscription_on_BlockAddedToMain_event()
Block block = Build.A.Block.WithDifficulty(1991).WithExtraData(new byte[] {3, 5, 8}).TestObject;
BlockReplacementEventArgs blockReplacementEventArgs = new(block);

JsonRpcResult jsonRpcResult = GetBlockAddedToMainResult(blockReplacementEventArgs, out var subscriptionId);
JsonRpcResult jsonRpcResult = GetBlockAddedToMainResult(blockReplacementEventArgs, out string subscriptionId);

jsonRpcResult.Response.Should().NotBeNull();
string serialized = _jsonSerializer.Serialize(jsonRpcResult.Response);
Expand All @@ -283,16 +287,17 @@ public void NewHeadSubscription_should_send_notifications_when_adding_multiple_b
MemDb headersDb = new();
MemDb blocksInfosDb = new();
ChainLevelInfoRepository chainLevelInfoRepository = new(blocksInfosDb);
MainnetSpecProvider specProvider = MainnetSpecProvider.Instance;
BlockTree blockTree = new(
blocksDb,
headersDb,
blocksInfosDb,
chainLevelInfoRepository,
MainnetSpecProvider.Instance,
specProvider,
NullBloomStorage.Instance,
LimboLogs.Instance);

NewHeadSubscription newHeadSubscription = new(_jsonRpcDuplexClient, blockTree, _logManager);
NewHeadSubscription newHeadSubscription = new(_jsonRpcDuplexClient, blockTree, _logManager, specProvider);
ConcurrentQueue<JsonRpcResult> jsonRpcResult = new();

Block block0 = Build.A.Block.Genesis.WithTotalDifficulty(0L).TestObject;
Expand Down Expand Up @@ -339,16 +344,17 @@ public void NewHeadSubscription_should_send_notifications_in_order()
MemDb headersDb = new();
MemDb blocksInfosDb = new();
ChainLevelInfoRepository chainLevelInfoRepository = new(blocksInfosDb);
MainnetSpecProvider specProvider = MainnetSpecProvider.Instance;
BlockTree blockTree = new(
blocksDb,
headersDb,
blocksInfosDb,
chainLevelInfoRepository,
MainnetSpecProvider.Instance,
specProvider,
NullBloomStorage.Instance,
LimboLogs.Instance);

NewHeadSubscription newHeadSubscription = new(_jsonRpcDuplexClient, blockTree, _logManager);
NewHeadSubscription newHeadSubscription = new(_jsonRpcDuplexClient, blockTree, _logManager, specProvider);
ConcurrentQueue<JsonRpcResult> jsonRpcResult = new();

Block block0 = Build.A.Block.Genesis.WithDifficulty(0).WithTotalDifficulty(0L).TestObject;
Expand Down Expand Up @@ -783,6 +789,21 @@ public void NewPendingTransactionsSubscription_on_NewPending_with_includeTransac
expectedResult.Should().Be(serialized);
}

[Test]
public void NewHeadSubscription_with_baseFeePerGas_test()
{
_specProvider.GetSpec(Arg.Any<long>()).IsEip1559Enabled.Returns(true);
Block block = Build.A.Block.Genesis.WithTotalDifficulty(0L).WithBaseFeePerGas(10000).TestObject;
BlockReplacementEventArgs blockReplacementEventArgs = new(block);
JsonRpcResult jsonRpcResult = GetBlockAddedToMainResult(blockReplacementEventArgs, out string subscriptionId);

jsonRpcResult.Response.Should().NotBeNull();
string serialized = _jsonSerializer.Serialize(jsonRpcResult.Response);
var expectedResult = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"" + subscriptionId + "\",\"result\":{\"author\":\"0x0000000000000000000000000000000000000000\",\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0xb3157bcccab04639f6393042690a6c9862deebe88c781f911e8dfd265531e9ff\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"totalDifficulty\":\"0x0\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x2710\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]}}}";
expectedResult.Should().Be(serialized);

}

[Test]
public void DroppedPendingTransactionsSubscription_creating_result()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ protected BlockForRpc()

}

public BlockForRpc(Block block, bool includeFullTransactionData, ISpecProvider? specProvider = null)
public BlockForRpc(Block block, bool includeFullTransactionData, ISpecProvider specProvider)
{
_isAuRaBlock = block.Header.AuRaSignature != null;
Author = block.Author ?? block.Beneficiary;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
// along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.
//

using System;
using Nethermind.JsonRpc.Modules.Eth;

namespace Nethermind.JsonRpc.Modules.Subscribe
Expand All @@ -24,6 +23,6 @@ public interface ISubscriptionManager
{
string AddSubscription(IJsonRpcDuplexClient jsonRpcDuplexClient, SubscriptionType subscriptionType, Filter? filter = null);
bool RemoveSubscription(IJsonRpcDuplexClient jsonRpcDuplexClient, string subscriptionId);
void RemoveClientSubscriptions(object? sender, EventArgs e);
void RemoveClientSubscriptions(IJsonRpcDuplexClient jsonRpcDuplexClient);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Threading.Tasks;
using Nethermind.Blockchain;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.JsonRpc.Modules.Eth;
using Nethermind.Logging;

Expand All @@ -28,14 +29,16 @@ public class NewHeadSubscription : Subscription
{
private readonly IBlockTree _blockTree;
private readonly bool _includeTransactions;
private readonly ISpecProvider _specProvider;


public NewHeadSubscription(IJsonRpcDuplexClient jsonRpcDuplexClient, IBlockTree? blockTree, ILogManager? logManager, Filter? filter = null)
public NewHeadSubscription(IJsonRpcDuplexClient jsonRpcDuplexClient, IBlockTree? blockTree, ILogManager? logManager, ISpecProvider specProvider, Filter? filter = null)
: base(jsonRpcDuplexClient)
{
_blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
_logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
_includeTransactions = filter?.IncludeTransactions ?? false;
_specProvider = specProvider;

_blockTree.BlockAddedToMain += OnBlockAddedToMain;
if(_logger.IsTrace) _logger.Trace($"NewHeads subscription {Id} will track BlockAddedToMain");
Expand All @@ -45,7 +48,7 @@ private void OnBlockAddedToMain(object? sender, BlockReplacementEventArgs e)
{
ScheduleAction(() =>
{
JsonRpcResult result = CreateSubscriptionMessage(new BlockForRpc(e.Block, _includeTransactions));
JsonRpcResult result = CreateSubscriptionMessage(new BlockForRpc(e.Block, _includeTransactions, _specProvider));
JsonRpcDuplexClient.SendJsonRpcResult(result);
if(_logger.IsTrace) _logger.Trace($"NewHeads subscription {Id} printed new block");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ public SubscribeRpcModule(ISubscriptionManager subscriptionManager)
{
_subscriptionManager = subscriptionManager ?? throw new ArgumentNullException(nameof(subscriptionManager));
}



public ResultWrapper<string> eth_subscribe(string subscriptionName, Filter arguments = null)
{
if (Enum.TryParse(typeof(SubscriptionType), subscriptionName, true, out var subscriptionType))
Expand All @@ -38,7 +37,6 @@ public ResultWrapper<string> eth_subscribe(string subscriptionName, Filter argum
}
return ResultWrapper<string>.Fail($"Wrong subscription type: {subscriptionName}.");
}


public ResultWrapper<bool> eth_unsubscribe(string subscriptionId)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ protected Subscription(IJsonRpcDuplexClient jsonRpcDuplexClient)
public string Id { get; }
public abstract SubscriptionType Type { get; }
public IJsonRpcDuplexClient JsonRpcDuplexClient { get; }

private Channel<Action> SendChannel { get; } = Channel.CreateUnbounded<Action>(new UnboundedChannelOptions() { SingleReader = true });

public virtual void Dispose()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Nethermind.Blockchain;
using Nethermind.Blockchain.Filters;
using Nethermind.Blockchain.Receipts;
using Nethermind.Core.Specs;
using Nethermind.Facade.Eth;
using Nethermind.JsonRpc.Modules.Eth;
using Nethermind.Logging;
Expand All @@ -34,28 +35,31 @@ public class SubscriptionFactory : ISubscriptionFactory
private readonly IReceiptStorage _receiptStorage;
private readonly IFilterStore _filterStore;
private readonly IEthSyncingInfo _ethSyncingInfo;
private readonly ISpecProvider _specProvider;

public SubscriptionFactory(
ILogManager? logManager,
IBlockTree? blockTree,
ITxPool? txPool,
IReceiptStorage? receiptStorage,
IFilterStore? filterStore,
IEthSyncingInfo ethSyncingInfo)
IEthSyncingInfo ethSyncingInfo,
ISpecProvider specProvider)
{
_logManager = logManager ?? throw new ArgumentNullException(nameof(logManager));
_blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
_txPool = txPool ?? throw new ArgumentNullException(nameof(txPool));
_receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
_filterStore = filterStore ?? throw new ArgumentNullException(nameof(filterStore));
_ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo));
_specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
}
public Subscription CreateSubscription(IJsonRpcDuplexClient jsonRpcDuplexClient, SubscriptionType subscriptionType, Filter? filter)
{
switch (subscriptionType)
{
case SubscriptionType.NewHeads:
return new NewHeadSubscription(jsonRpcDuplexClient, _blockTree, _logManager, filter);
return new NewHeadSubscription(jsonRpcDuplexClient, _blockTree, _logManager, _specProvider, filter);
case SubscriptionType.Logs:
return new LogsSubscription(jsonRpcDuplexClient, _receiptStorage, _filterStore, _blockTree, _logManager, filter);
case SubscriptionType.NewPendingTransactions:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,18 @@ private void AddToDictionary(Subscription subscription)

private void AddOrUpdateClientsBag(Subscription subscription)
{
void OnJsonRpcDuplexClientClosed(object? sender, EventArgs e)
{
IJsonRpcDuplexClient jsonRpcDuplexClient = (IJsonRpcDuplexClient)sender;
RemoveClientSubscriptions(jsonRpcDuplexClient!);
jsonRpcDuplexClient.Closed -= OnJsonRpcDuplexClientClosed;
}

_subscriptionsByJsonRpcClient.AddOrUpdate(subscription.JsonRpcDuplexClient.Id,
k =>
{
if (_logger.IsTrace) _logger.Trace($"Created client's subscriptions bag and added client's first subscription {subscription.Id} to it.");
subscription.JsonRpcDuplexClient.Closed += RemoveClientSubscriptions;
subscription.JsonRpcDuplexClient.Closed += OnJsonRpcDuplexClientClosed;
return new HashSet<Subscription>() {subscription};
},
(k, b) =>
Expand Down Expand Up @@ -111,17 +118,15 @@ private void RemoveFromDictionary(string subscriptionId)
else if (_logger.IsDebug) _logger.Debug($"Failed trying to remove subscription {subscriptionId} from dictionary _subscriptions.");
}

public void RemoveClientSubscriptions(object? sender, EventArgs e)
public void RemoveClientSubscriptions(IJsonRpcDuplexClient jsonRpcDuplexClient)
{
IJsonRpcDuplexClient jsonRpcDuplexClient = (IJsonRpcDuplexClient)sender;

if (jsonRpcDuplexClient != null
&& _subscriptionsByJsonRpcClient.TryRemove(jsonRpcDuplexClient.Id, out var subscriptionsBag))
string clientId = jsonRpcDuplexClient.Id;
if (_subscriptionsByJsonRpcClient.TryRemove(clientId, out HashSet<Subscription> subscriptionsBag))
{
DisposeAndRemoveFromDictionary(subscriptionsBag);
if (_logger.IsTrace) _logger.Trace($"Client {jsonRpcDuplexClient.Id} removed from dictionary _subscriptionsByJsonRpcClient.");
if (_logger.IsTrace) _logger.Trace($"Client {clientId} removed from dictionary _subscriptionsByJsonRpcClient.");
}
else if (_logger.IsDebug) _logger.Debug($"Failed trying to remove client {jsonRpcDuplexClient?.Id} from dictionary _subscriptionsByJsonRpcClient.");
else if (_logger.IsDebug) _logger.Debug($"Failed trying to remove client {clientId} from dictionary _subscriptionsByJsonRpcClient.");
}

private void DisposeAndRemoveFromDictionary(HashSet<Subscription> subscriptionsBag)
Expand Down

0 comments on commit 66d4268

Please sign in to comment.