eth/event_filter.cpp¶
Namespaces¶
| Name |
|---|
| eth |
Source code¶
// Copyright 2025 GeniusVentures
// SPDX-License-Identifier: Apache-2.0
#include <eth/event_filter.hpp>
#include <algorithm>
namespace eth {
// ---------------------------------------------------------------------------
// EventFilter::matches
// ---------------------------------------------------------------------------
bool EventFilter::matches(const codec::LogEntry& log, uint64_t block) const noexcept
{
// Block range check
if (from_block.has_value() && block < from_block.value())
{
return false;
}
if (to_block.has_value() && block > to_block.value())
{
return false;
}
// Address check: if filter specifies addresses, the log's emitter must be in the list
if (!addresses.empty())
{
const auto it = std::find(addresses.begin(), addresses.end(), log.address);
if (it == addresses.end())
{
return false;
}
}
// Topic check: per-position matching
for (size_t i = 0; i < topics.size(); ++i)
{
if (!topics[i].has_value())
{
// Wildcard – any value (including absent) is fine
continue;
}
if (i >= log.topics.size())
{
// Log doesn't have a topic at this position but filter requires one
return false;
}
if (log.topics[i] != topics[i].value())
{
return false;
}
}
return true;
}
// ---------------------------------------------------------------------------
// EventWatcher
// ---------------------------------------------------------------------------
WatchId EventWatcher::watch(EventFilter filter, EventCallback callback) noexcept
{
const WatchId id = next_id_++;
subscriptions_.push_back({id, std::move(filter), std::move(callback)});
return id;
}
void EventWatcher::unwatch(WatchId id) noexcept
{
subscriptions_.erase(
std::remove_if(
subscriptions_.begin(),
subscriptions_.end(),
[id](const Subscription& s) { return s.id == id; }),
subscriptions_.end());
}
void EventWatcher::process_block_logs(
const std::vector<codec::LogEntry>& logs,
uint64_t block_number,
const codec::Hash256& block_hash) noexcept
{
uint32_t log_index = 0;
for (const auto& log : logs)
{
for (const auto& sub : subscriptions_)
{
if (sub.filter.matches(log, block_number))
{
MatchedEvent event{
log,
block_number,
block_hash,
codec::Hash256{}, // tx_hash unknown at block-log level
log_index
};
sub.callback(event);
}
}
++log_index;
}
}
void EventWatcher::process_receipt(
const codec::Receipt& receipt,
const codec::Hash256& tx_hash,
uint64_t block_number,
const codec::Hash256& block_hash) noexcept
{
uint32_t log_index = 0;
for (const auto& log : receipt.logs)
{
for (const auto& sub : subscriptions_)
{
if (sub.filter.matches(log, block_number))
{
MatchedEvent event{
log,
block_number,
block_hash,
tx_hash,
log_index
};
sub.callback(event);
}
}
++log_index;
}
}
} // namespace eth
Updated on 2026-04-13 at 23:22:46 -0700