private List <FilterLog> GetFilterLogs(ReceiptsEventArgs e) { List <FilterLog> filterLogs = new(); if (_filter.Matches(e.BlockHeader.Bloom)) { int logIndex = 0; for (int i = 0; i < e.TxReceipts.Length; i++) { TxReceipt receipt = e.TxReceipts[i]; if (_filter.Matches(receipt.Bloom)) { int transactionLogIndex = 0; for (int j = 0; j < receipt.Logs.Length; j++) { var receiptLog = receipt.Logs[j]; if (_filter.Accepts(receiptLog)) { FilterLog filterLog = new( logIndex++, transactionLogIndex++, receipt, receiptLog); filterLogs.Add(filterLog); } } } } } return(filterLogs); }
public void LogsSubscription_with_null_arguments_on_ReceiptsInserted_event_with_one_TxReceipt_with_few_logs() { int blockNumber = 77777; Filter filter = null; LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; LogEntry logEntryB = Build.A.LogEntry.WithAddress(TestItem.AddressB).WithTopics(TestItem.KeccakB).TestObject; LogEntry logEntryC = Build.A.LogEntry.WithData(TestItem.RandomDataC).TestObject; TxReceipt[] txReceipts = new TxReceipt[] { Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryA, logEntryB, logEntryC).TestObject }; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; ReceiptsEventArgs receiptsEventArgs = new ReceiptsEventArgs(blockHeader, txReceipts); List <JsonRpcResult> jsonRpcResults = GetLogsSubscriptionResult(filter, receiptsEventArgs, out var subscriptionId); jsonRpcResults.Count.Should().Be(3); string serialized = _jsonSerializer.Serialize(jsonRpcResults[0].Response); var expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"blockNumber\":\"0x12fd1\",\"data\":\"0x010203\",\"logIndex\":\"0x0\",\"removed\":false,\"topics\":[\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x0\"}}}"); expectedResult.Should().Be(serialized); serialized = _jsonSerializer.Serialize(jsonRpcResults[1].Response); expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"blockNumber\":\"0x12fd1\",\"data\":\"0x\",\"logIndex\":\"0x1\",\"removed\":false,\"topics\":[\"0x1f675bff07515f5df96737194ea945c36c41e7b4fcef307b7cd4d0e602a69111\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x1\"}}}"); expectedResult.Should().Be(serialized); serialized = _jsonSerializer.Serialize(jsonRpcResults[2].Response); expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0x0000000000000000000000000000000000000000\",\"blockNumber\":\"0x12fd1\",\"data\":\"0x010208090a\",\"logIndex\":\"0x2\",\"removed\":false,\"topics\":[\"0x0000000000000000000000000000000000000000000000000000000000000000\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x2\"}}}"); expectedResult.Should().Be(serialized); }
private void OnReceiptsInserted(object?sender, ReceiptsEventArgs e) { bool isReceiptRemoved = e.TxReceipts.FirstOrDefault()?.Removed == true; if (isReceiptRemoved) { TryPublishReceiptsInBackground(e.BlockHeader, () => e.TxReceipts, nameof(_receiptStorage.ReceiptsInserted)); } }
public void LogsSubscription_on_ReceiptsInserted_event_with_few_TxReceipts_with_few_logs_with_few_topics_and_some_address_and_topic_mismatches() { int blockNumber = 55555; IEnumerable <object> topics = new List <object>() { TestItem.KeccakA }; Filter filter = new Filter() { FromBlock = BlockParameter.Latest, ToBlock = BlockParameter.Latest, Address = new [] { "0xb7705ae4c6f81b66cdb323c65f4e8133690fc099", "0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358" }, Topics = new [] { TestItem.KeccakA, TestItem.KeccakD } }; LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA, TestItem.KeccakD).WithData(TestItem.RandomDataA).TestObject; LogEntry logEntryB = Build.A.LogEntry.WithAddress(TestItem.AddressC).WithTopics(TestItem.KeccakA, TestItem.KeccakD).WithData(TestItem.RandomDataB).TestObject; LogEntry logEntryC = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithData(TestItem.RandomDataC).TestObject; LogEntry logEntryD = Build.A.LogEntry.WithAddress(TestItem.AddressB).WithTopics(TestItem.KeccakA, TestItem.KeccakD, TestItem.KeccakE).WithData(TestItem.RandomDataB).TestObject; LogEntry logEntryE = Build.A.LogEntry.WithTopics(TestItem.KeccakA, TestItem.KeccakD).WithData(TestItem.RandomDataB).TestObject; TxReceipt[] txReceipts = new TxReceipt[] { Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryA, logEntryB, logEntryC).TestObject, Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs().TestObject, Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryB).TestObject, Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryE, logEntryE, logEntryB, logEntryD, logEntryE, logEntryB).TestObject, Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryC, logEntryB, logEntryE, logEntryA, logEntryB).TestObject, }; Bloom bloom = new Bloom(txReceipts.Select(r => r.Bloom).ToArray()); BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).WithBloom(bloom).TestObject; ReceiptsEventArgs receiptsEventArgs = new ReceiptsEventArgs(blockHeader, txReceipts); List <JsonRpcResult> jsonRpcResults = GetLogsSubscriptionResult(filter, receiptsEventArgs, out var subscriptionId); jsonRpcResults.Count.Should().Be(3); string serialized = _jsonSerializer.Serialize(jsonRpcResults[0].Response); var expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"blockNumber\":\"0xd903\",\"data\":\"0x010203\",\"logIndex\":\"0x0\",\"removed\":false,\"topics\":[\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\",\"0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x0\"}}}"); expectedResult.Should().Be(serialized); serialized = _jsonSerializer.Serialize(jsonRpcResults[1].Response); expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"blockNumber\":\"0xd903\",\"data\":\"0x04050607\",\"logIndex\":\"0x1\",\"removed\":false,\"topics\":[\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\",\"0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2\",\"0x434b529473163ef4ed9c9341d9b7250ab9183c27e7add004c3bba38c56274e24\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x0\"}}}"); expectedResult.Should().Be(serialized); serialized = _jsonSerializer.Serialize(jsonRpcResults[2].Response); expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"blockNumber\":\"0xd903\",\"data\":\"0x010203\",\"logIndex\":\"0x2\",\"removed\":false,\"topics\":[\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\",\"0x6c3fd336b49dcb1c57dd4fbeaf5f898320b0da06a5ef64e798c6497600bb79f2\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x0\"}}}"); expectedResult.Should().Be(serialized); }
public void LogsSubscription_with_not_matching_block_on_ReceiptsInserted_event() { int blockNumber = 22222; Filter filter = null; LogEntry logEntry = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; TxReceipt[] txReceipts = new TxReceipt[] { Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntry).TestObject }; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; ReceiptsEventArgs receiptsEventArgs = new ReceiptsEventArgs(blockHeader, txReceipts); List <JsonRpcResult> jsonRpcResults = GetLogsSubscriptionResult(filter, receiptsEventArgs, out _); jsonRpcResults.Count.Should().Be(0); }
public void LogsSubscription_on_ReceiptsInserted_event_with_few_TxReceipts_with_few_logs_with_some_topic_mismatches() { int blockNumber = 55555; Filter filter = new Filter() { FromBlock = BlockParameter.Latest, ToBlock = BlockParameter.Latest, Address = "0xb7705ae4c6f81b66cdb323c65f4e8133690fc099", Topics = new [] { TestItem.KeccakA } }; LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; LogEntry logEntryB = Build.A.LogEntry.WithAddress(TestItem.AddressB).WithTopics(TestItem.KeccakB).WithData(TestItem.RandomDataB).TestObject; LogEntry logEntryC = Build.A.LogEntry.WithAddress(TestItem.AddressC).WithData(TestItem.RandomDataC).TestObject; TxReceipt[] txReceipts = new TxReceipt[] { Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryA, logEntryB, logEntryC).TestObject, Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs().TestObject, Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryB).TestObject, Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryC, logEntryC, logEntryB, logEntryC, logEntryC, logEntryB).TestObject, Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntryA, logEntryC, logEntryB, logEntryA, logEntryC).TestObject, }; Bloom bloom = new Bloom(txReceipts.Select(r => r.Bloom).ToArray()); BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).WithBloom(bloom).TestObject; ReceiptsEventArgs receiptsEventArgs = new ReceiptsEventArgs(blockHeader, txReceipts); List <JsonRpcResult> jsonRpcResults = GetLogsSubscriptionResult(filter, receiptsEventArgs, out var subscriptionId); jsonRpcResults.Count.Should().Be(3); string serialized = _jsonSerializer.Serialize(jsonRpcResults[0].Response); var expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"blockNumber\":\"0xd903\",\"data\":\"0x010203\",\"logIndex\":\"0x0\",\"removed\":false,\"topics\":[\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x0\"}}}"); expectedResult.Should().Be(serialized); serialized = _jsonSerializer.Serialize(jsonRpcResults[1].Response); expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"blockNumber\":\"0xd903\",\"data\":\"0x010203\",\"logIndex\":\"0x1\",\"removed\":false,\"topics\":[\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x0\"}}}"); expectedResult.Should().Be(serialized); serialized = _jsonSerializer.Serialize(jsonRpcResults[2].Response); expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"blockNumber\":\"0xd903\",\"data\":\"0x010203\",\"logIndex\":\"0x2\",\"removed\":false,\"topics\":[\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x1\"}}}"); expectedResult.Should().Be(serialized); }
private void OnReceiptsInserted(object?sender, ReceiptsEventArgs e) { Task.Run(() => { BlockHeader fromBlock = _blockFinder.FindHeader(_filter.FromBlock); BlockHeader toBlock = _blockFinder.FindHeader(_filter.ToBlock, true); bool isAfterFromBlock = e.BlockHeader.Number >= fromBlock.Number; bool isBeforeToBlock = e.BlockHeader.Number <= toBlock.Number || _filter.ToBlock.Equals(BlockParameter.Latest) || _filter.ToBlock.Equals(BlockParameter.Pending); if (isAfterFromBlock && isBeforeToBlock) { var filterLogs = GetFilterLogs(e); foreach (var filterLog in filterLogs) { JsonRpcResult result = CreateSubscriptionMessage(filterLog); JsonRpcDuplexClient.SendJsonRpcResult(result); if (_logger.IsTrace) { _logger.Trace($"Logs subscription {Id} printed new log."); } } } else { if (_logger.IsTrace) { _logger.Trace($"Logs subscription {Id}: OnReceiptsInserted event happens, but there are no logs matching filter."); } } }).ContinueWith( t => t.Exception?.Handle(ex => { if (_logger.IsDebug) { _logger.Debug($"Logs subscription {Id}: Failed Task.Run after ReceiptsInserted event."); } return(true); }) , TaskContinuationOptions.OnlyOnFaulted ); }
private List <JsonRpcResult> GetLogsSubscriptionResult(Filter filter, ReceiptsEventArgs receiptsEventArgs, out string subscriptionId) { LogsSubscription logsSubscription = new LogsSubscription(_jsonRpcDuplexClient, _receiptStorage, _filterStore, _blockTree, _logManager, filter); List <JsonRpcResult> jsonRpcResults = new List <JsonRpcResult>(); SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); logsSubscription.JsonRpcDuplexClient.SendJsonRpcResult(Arg.Do <JsonRpcResult>(j => { jsonRpcResults.Add(j); })); _receiptStorage.ReceiptsInserted += Raise.EventWith(new object(), receiptsEventArgs); semaphoreSlim.Wait(TimeSpan.FromMilliseconds(100)); subscriptionId = logsSubscription.Id; return(jsonRpcResults); }
public void LogsSubscription_with_null_arguments_on_ReceiptsInserted_event() { int blockNumber = 55555; Filter filter = null; LogEntry logEntry = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; TxReceipt[] txReceipts = new TxReceipt[] { Build.A.Receipt.WithBlockNumber(blockNumber).WithLogs(logEntry).TestObject }; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; ReceiptsEventArgs receiptsEventArgs = new ReceiptsEventArgs(blockHeader, txReceipts); List <JsonRpcResult> jsonRpcResults = GetLogsSubscriptionResult(filter, receiptsEventArgs, out var subscriptionId); jsonRpcResults.Count.Should().Be(1); string serialized = _jsonSerializer.Serialize(jsonRpcResults[0].Response); var expectedResult = string.Concat("{\"jsonrpc\":\"2.0\",\"method\":\"eth_subscription\",\"params\":{\"subscription\":\"", subscriptionId, "\",\"result\":{\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"blockNumber\":\"0xd903\",\"data\":\"0x010203\",\"logIndex\":\"0x0\",\"removed\":false,\"topics\":[\"0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760\"],\"transactionIndex\":\"0x0\",\"transactionLogIndex\":\"0x0\"}}}"); expectedResult.Should().Be(serialized); }
private void OnReceiptsInserted(object?sender, ReceiptsEventArgs e) { TryPublishReceiptsInBackground(e.BlockHeader, () => e.TxReceipts, nameof(_receiptCanonicalityMonitor.ReceiptsInserted), e.WasRemoved); }