Skip to content

Commit 2547f73

Browse files
committed
Merge branch 'main' into reorg-live-mode
2 parents d496f6c + cdaed6e commit 2547f73

File tree

30 files changed

+523
-1052
lines changed

30 files changed

+523
-1052
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
* @LeoPatOZ @0xNeshi @pepebndc
1+
* @LeoPatOZ @0xNeshi @pepebndc
2+
SECURITY.md @LeoPatOZ @0xNeshi @pepebndc @OpenZeppelin/product-security

.github/workflows/scorecard.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
# This workflow uses actions that are not certified by GitHub. They are provided
3+
# by a third-party and are governed by separate terms of service, privacy
4+
# policy, and support documentation.
5+
name: Scorecard supply-chain security
6+
on:
7+
# For Branch-Protection check. Only the default branch is supported. See
8+
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
9+
branch_protection_rule:
10+
# To guarantee Maintained check is occasionally updated. See
11+
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
12+
schedule:
13+
- cron: 15 21 * * 4
14+
push:
15+
branches:
16+
- main
17+
# Declare default permissions as read only.
18+
permissions: read-all
19+
jobs:
20+
analysis:
21+
name: Scorecard analysis
22+
runs-on: ubuntu-latest
23+
permissions:
24+
# Needed to upload the results to code-scanning dashboard.
25+
security-events: write
26+
# Needed to publish results and get a badge (see publish_results below).
27+
id-token: write
28+
# comment the permissions below if installing in a public repository.
29+
# contents: read
30+
# actions: read
31+
steps:
32+
- name: Harden Runner
33+
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
34+
with:
35+
egress-policy: audit
36+
- name: Checkout code
37+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.5.4
38+
with:
39+
persist-credentials: false
40+
- name: Run analysis
41+
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
42+
with:
43+
results_file: results.sarif
44+
results_format: sarif
45+
publish_results: true
46+
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
47+
# format to the repository Actions tab.
48+
- name: Upload artifact
49+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
50+
with:
51+
name: SARIF file
52+
path: results.sarif
53+
retention-days: 5
54+
- name: Upload SARIF to GitHub Code Scanning
55+
uses: github/codeql-action/upload-sarif@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5
56+
with:
57+
sarif_file: results.sarif

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Thanks for your interest in contributing! This guide explains how to set up your
66

77
## Project Overview
88

9-
`event-scanner` is a Rust library for monitoring EVM-based smart contract events. It is built on the `alloy` ecosystem and provides in-memory scanning with retry-aware callback execution. See `README.md` for features, usage, examples, and testing notes.
9+
`event-scanner` is a Rust library for monitoring and streaming EVM-based smart contract events. It is built on the `alloy` ecosystem and provides in-memory scanning. See `README.md` for features, usage, examples, and testing notes.
1010

1111
- Workspace manifest: `Cargo.toml`
1212
- Library code: `src/`

Cargo.lock

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Event Scanner
22

3+
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/OpenZeppelin/event-scanner/badge)](https://api.securityscorecards.dev/projects/github.com/OpenZeppelin/event-scanner)
4+
35
> ⚠️ **WARNING: ACTIVE DEVELOPMENT** ⚠️
46
>
57
> This project is under active development and likely contains bugs. APIs and behaviour may change without notice. Use at your own risk.
@@ -79,12 +81,12 @@ async fn run_scanner(ws_url: alloy::transports::http::reqwest::Url, contract: al
7981
.with_event(MyContract::SomeEvent::SIGNATURE)
8082
.with_callback(Arc::new(CounterCallback { processed: Arc::new(AtomicUsize::new(0)) }));
8183

82-
let mut scanner = EventScannerBuilder::new()
84+
let mut client = EventScannerBuilder::new()
8385
.with_event_filter(filter)
8486
.connect_ws::<Ethereum>(ws_url)
8587
.await?;
8688

87-
scanner.start(BlockNumberOrTag::Latest, None).await?;
89+
client.start_scanner(BlockNumberOrTag::Latest, None).await?;
8890
Ok(())
8991
}
9092
```

SECURITY.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Security Policy
2+
3+
Security vulnerabilities should be [disclosed](#reporting-a-vulnerability) to the [project maintainers](./.github/CODEOWNERS), or alternatively by email to security@openzeppelin.com.
4+
5+
## Supported Versions
6+
7+
The following versions are currently supported and receive security updates. Alpha, Beta and Release candidates will not receive security updates.
8+
9+
Security patches will be released for the latest minor of a given major release. For example, if an issue is found in versions >=1.13.0 and the latest is 1.14.0, the patch will be released only in version 1.14.1.
10+
11+
Only critical severity bug fixes will be backported to past major releases.
12+
13+
| Version | Supported |
14+
| --------- | ------------------ |
15+
| >= 0.1.x | :white_check_mark: |
16+
| <= 0.0.9 | :x: |
17+
18+
## Reporting a Vulnerability
19+
20+
We're extremely grateful for security researchers and users that report vulnerabilities to us.
21+
All reports are thoroughly investigated by the project's security team.
22+
23+
Vulnerabilities are reported privately via GitHub's [Security Advisories](https://docs.github.com/en/code-security/security-advisories) feature.
24+
Please use the following link to submit your vulnerability: [Report a vulnerability](https://github.com/openzeppelin/event-scanner/security/advisories/new)
25+
26+
Please see
27+
[Privately reporting a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability)
28+
for more information on how to submit a vulnerability using GitHub's interface.
29+
30+
## Legal
31+
32+
OpenZeppelin Event Scanner is made available under the GNU AGPL 3.0 License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including OpenZeppelin. Your use of the project is also governed by the terms found at www.openzeppelin.com/tos (the "Terms"). As set out in the Terms, you are solely responsible for any use of OpenZeppelin Even Scanner and you assume all risks associated with any such use. This Security Policy in no way evidences or represents an on-going duty by any contributor, including OpenZeppelin, to correct any flaws or alert you to all or any of the potential risks of utilizing the project.
33+

examples/historical_scanning/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ path = "main.rs"
1414
alloy.workspace = true
1515
alloy-node-bindings.workspace = true
1616
tokio.workspace = true
17+
tokio-stream.workspace = true
1718
anyhow.workspace = true
18-
async-trait.workspace = true
1919
tracing.workspace = true
2020
tracing-subscriber.workspace = true
21-
hex.workspace = true
2221
event-scanner = { path = "../.." }

examples/historical_scanning/main.rs

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,16 @@
1-
use std::{sync::Arc, time::Duration};
1+
use std::time::Duration;
22

33
use alloy::{
4-
eips::BlockNumberOrTag, network::Ethereum, providers::ProviderBuilder, rpc::types::Log, sol,
5-
sol_types::SolEvent,
4+
eips::BlockNumberOrTag, network::Ethereum, providers::ProviderBuilder, sol, sol_types::SolEvent,
65
};
76
use alloy_node_bindings::Anvil;
8-
use async_trait::async_trait;
9-
use event_scanner::{EventCallback, EventFilter, event_scanner::EventScannerBuilder};
7+
use event_scanner::{EventFilter, event_scanner::EventScanner};
108

119
use tokio::time::sleep;
10+
use tokio_stream::StreamExt;
1211
use tracing::info;
1312
use tracing_subscriber::EnvFilter;
1413

15-
struct CounterCallback;
16-
17-
#[async_trait]
18-
impl EventCallback for CounterCallback {
19-
async fn on_event(&self, log: &Log) -> anyhow::Result<()> {
20-
info!("Callback successfully executed with event {:?}", log.inner.data);
21-
Ok(())
22-
}
23-
}
24-
2514
sol! {
2615
#[allow(missing_docs)]
2716
#[sol(rpc, bytecode="608080604052346015576101b0908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c90816306661abd1461016157508063a87d942c14610145578063d732d955146100ad5763e8927fbc14610048575f80fd5b346100a9575f3660031901126100a9575f5460018101809111610095576020817f7ca2ca9527391044455246730762df008a6b47bbdb5d37a890ef78394535c040925f55604051908152a1005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b346100a9575f3660031901126100a9575f548015610100575f198101908111610095576020817f53a71f16f53e57416424d0d18ccbd98504d42a6f98fe47b09772d8f357c620ce925f55604051908152a1005b60405162461bcd60e51b815260206004820152601860248201527f436f756e742063616e6e6f74206265206e6567617469766500000000000000006044820152606490fd5b346100a9575f3660031901126100a95760205f54604051908152f35b346100a9575f3660031901126100a9576020905f548152f3fea2646970667358221220b846b706f79f5ae1fc4a4238319e723a092f47ce4051404186424739164ab02264736f6c634300081e0033")]
@@ -61,18 +50,22 @@ async fn main() -> anyhow::Result<()> {
6150

6251
let increase_filter = EventFilter::new()
6352
.with_contract_address(*contract_address)
64-
.with_event(Counter::CountIncreased::SIGNATURE)
65-
.with_callback(Arc::new(CounterCallback));
53+
.with_event(Counter::CountIncreased::SIGNATURE);
6654

6755
let _ = counter_contract.increase().send().await?.get_receipt().await?;
6856

69-
let mut scanner = EventScannerBuilder::new()
70-
.with_event_filter(increase_filter)
71-
.connect_ws::<Ethereum>(anvil.ws_endpoint_url())
72-
.await?;
57+
let mut client = EventScanner::new().connect_ws::<Ethereum>(anvil.ws_endpoint_url()).await?;
58+
59+
let mut stream = client.create_event_stream(increase_filter);
7360

7461
sleep(Duration::from_secs(10)).await;
75-
scanner.start(BlockNumberOrTag::Number(0), None).await.expect("failed to start scanner");
62+
client.start_scanner(BlockNumberOrTag::Number(0), None).await.expect("failed to start scanner");
63+
64+
while let Some(Ok(logs)) = stream.next().await {
65+
for log in logs {
66+
info!("Callback successfully executed with event {:?}", log.inner.data);
67+
}
68+
}
7669

7770
Ok(())
7871
}

examples/simple_counter/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ path = "main.rs"
1414
alloy.workspace = true
1515
alloy-node-bindings.workspace = true
1616
tokio.workspace = true
17+
tokio-stream.workspace = true
1718
anyhow.workspace = true
18-
async-trait.workspace = true
1919
tracing.workspace = true
2020
tracing-subscriber.workspace = true
21-
hex.workspace = true
2221
event-scanner = { path = "../.." }

examples/simple_counter/main.rs

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,42 @@
1-
use std::{sync::Arc, time::Duration};
1+
use std::time::Duration;
22

33
use alloy::{
4-
eips::BlockNumberOrTag, network::Ethereum, providers::ProviderBuilder, rpc::types::Log, sol,
5-
sol_types::SolEvent,
4+
eips::BlockNumberOrTag, network::Ethereum, providers::ProviderBuilder, sol, sol_types::SolEvent,
65
};
76
use alloy_node_bindings::Anvil;
8-
use async_trait::async_trait;
9-
use event_scanner::{EventCallback, EventFilter, event_scanner::EventScannerBuilder};
7+
use event_scanner::{EventFilter, event_scanner::EventScanner};
108

119
use tokio::time::sleep;
10+
use tokio_stream::StreamExt;
1211
use tracing::info;
1312
use tracing_subscriber::EnvFilter;
1413

15-
struct CounterCallback;
16-
17-
#[async_trait]
18-
impl EventCallback for CounterCallback {
19-
async fn on_event(&self, log: &Log) -> anyhow::Result<()> {
20-
info!("Callback successfully executed with event {:?}", log.inner.data);
21-
Ok(())
22-
}
23-
}
24-
2514
sol! {
2615
#[allow(missing_docs)]
2716
#[sol(rpc, bytecode="608080604052346015576101b0908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c90816306661abd1461016157508063a87d942c14610145578063d732d955146100ad5763e8927fbc14610048575f80fd5b346100a9575f3660031901126100a9575f5460018101809111610095576020817f7ca2ca9527391044455246730762df008a6b47bbdb5d37a890ef78394535c040925f55604051908152a1005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b346100a9575f3660031901126100a9575f548015610100575f198101908111610095576020817f53a71f16f53e57416424d0d18ccbd98504d42a6f98fe47b09772d8f357c620ce925f55604051908152a1005b60405162461bcd60e51b815260206004820152601860248201527f436f756e742063616e6e6f74206265206e6567617469766500000000000000006044820152606490fd5b346100a9575f3660031901126100a95760205f54604051908152f35b346100a9575f3660031901126100a9576020905f548152f3fea2646970667358221220b846b706f79f5ae1fc4a4238319e723a092f47ce4051404186424739164ab02264736f6c634300081e0033")]
28-
contract Counter {
29-
uint256 public count;
17+
contract Counter {
18+
uint256 public count;
3019

31-
event CountIncreased(uint256 newCount);
32-
event CountDecreased(uint256 newCount);
20+
event CountIncreased(uint256 newCount);
21+
event CountDecreased(uint256 newCount);
3322

34-
function increase() public {
35-
count += 1;
36-
emit CountIncreased(count);
37-
}
23+
function increase() public {
24+
count += 1;
25+
emit CountIncreased(count);
26+
}
3827

39-
function decrease() public {
40-
require(count > 0, "Count cannot be negative");
41-
count -= 1;
42-
emit CountDecreased(count);
43-
}
28+
function decrease() public {
29+
require(count > 0, "Count cannot be negative");
30+
count -= 1;
31+
emit CountDecreased(count);
32+
}
4433

45-
function getCount() public view returns (uint256) {
46-
return count;
34+
function getCount() public view returns (uint256) {
35+
return count;
36+
}
4737
}
4838
}
49-
}
39+
5040
#[tokio::main]
5141
async fn main() -> anyhow::Result<()> {
5242
let _ = tracing_subscriber::fmt().with_env_filter(EnvFilter::from_default_env()).try_init();
@@ -61,16 +51,17 @@ async fn main() -> anyhow::Result<()> {
6151

6252
let increase_filter = EventFilter::new()
6353
.with_contract_address(*contract_address)
64-
.with_event(Counter::CountIncreased::SIGNATURE)
65-
.with_callback(Arc::new(CounterCallback));
54+
.with_event(Counter::CountIncreased::SIGNATURE);
55+
56+
let mut client = EventScanner::new().connect_ws::<Ethereum>(anvil.ws_endpoint_url()).await?;
6657

67-
let mut scanner = EventScannerBuilder::new()
68-
.with_event_filter(increase_filter)
69-
.connect_ws::<Ethereum>(anvil.ws_endpoint_url())
70-
.await?;
58+
let mut stream = client.create_event_stream(increase_filter);
7159

7260
let task_1 = tokio::spawn(async move {
73-
scanner.start(BlockNumberOrTag::Latest, None).await.expect("failed to start scanner");
61+
client
62+
.start_scanner(BlockNumberOrTag::Latest, None)
63+
.await
64+
.expect("failed to start scanner");
7465
});
7566

7667
let task_2 = tokio::spawn(async move {
@@ -83,6 +74,12 @@ async fn main() -> anyhow::Result<()> {
8374
}
8475
});
8576

77+
while let Some(Ok(logs)) = stream.next().await {
78+
for log in logs {
79+
info!("Callback successfully executed with event {:?}", log.inner.data);
80+
}
81+
}
82+
8683
task_1.await.ok();
8784
task_2.await.ok();
8885

0 commit comments

Comments
 (0)