Blueprint Reports Macro System Documentation
The report macro is designed to provide a streamlined interface for creating and submitting slashing reports within an AVS (Actively Validated Service). This system allows developers to define specific reporting criteria and automate the process of submitting reports to their respective protocols, such as Tangle or Eigenlayer. The reports system is flexible and can be triggered by various event sources, including job-specific events, general service behaviors, or custom event listeners.
Reports are crucial for maintaining the integrity and security of the AVS by identifying and penalizing malicious or faulty behavior. The report macro system is continuously evolving, and we welcome feature requests and contributions on our GitHub (opens in a new tab).
The #[report] Macro
The #[report]
macro is used to define individual reporting functions within a blueprint. It allows you to specify various parameters and metadata for each report.
struct Context;
#[report(
id = <report_id>,
params(<parameters>),
result(<result_type>),
event_listener(listener = <EventListenerType>),
)]
pub fn report_name(<parameters>, ctx: Context) -> Result<<return_type>, <error_type>> {
// Report implementation
}
id
: A unique identifier for the report. This can be used to associate reports with specific jobs or behaviors.params
: A list of parameters that the report function accepts.result
: The type of result the report produces (often represented by an underscore _).event_listener
: Specifies the event listener that triggers the report generation.
Event Listeners for Reports
Reports can be triggered by various types of event listeners. Here are some examples:
-
Job-specific Listeners: These listeners are tied to specific job IDs and trigger reports based on the outcome or behavior of particular jobs.
-
Periodic Listeners: These listeners trigger reports at regular intervals, similar to cron jobs.
-
EVM Contract Event Listeners: These listeners monitor events from EVM-compatible smart contracts and trigger reports based on specific contract events.
-
Custom Event Listeners: Developers can implement custom event listeners to trigger reports based on specific criteria or complex conditions.
For more information on implementing custom event listeners, refer to the Event Listeners documentation.
Examples
- Job-specific Slashing Report:
use my_special_slashing_context::Context;
#[report(
id = 0,
params(submission, job_id, operator_address),
result(),
event_listener(TangleEventListener<Context, JobResultSubmitted>),
)]
pub fn job_failure_report(submission: Vec<u8>, job_id: u64, operator_address: Address, ctx: Context) -> Result<(), Error> {
// Submit report to Tangle protocol
let (proof, valid)) = ctx.validate_submission(submission, job_id, operator_address)?;
if valid {
Ok(())
} else {
ctx.submit_slashing_report(submission, proof, job_id, operator_address)
}
}
- Periodic Uptime Report:
use my_special_web_polling_context::Context;
#[report(
id = 1,
params(value),
result(_),
event_listener(
listener = PeriodicEventListener<2000, WebPoller, serde_json::Value, reqwest::Client>
),
)]
pub async fn uptime_report(url: String, ctx: Context) -> Result<(), Error> {
let response = ctx.client.get(url.parse()?).send().await?;
let status = response.status();
if !status.is_success() {
let epoch = ctx.get_current_epoch();
let signature = ctx.sign_report(url, epoch)?;
ctx.submit_report(url, status, epoch, signature)?;
}
Ok(())
}
- EVM Contract Event Report:
use my_math_verification_context::Context;
use IncredibleSquaringTaskManager::{TaskResponded, TaskResponse, TaskResponseMetadata, Task};
#[job(
id = 1,
params(task, task_index),
event_listener(
listener = EvmContractEventListener<TaskResponded>,
instance = IncredibleSquaringTaskManager,
abi = INCREDIBLE_SQUARING_TASK_MANAGER_ABI_STRING,
pre_processor = convert_event_to_inputs,
),
)]
pub async fn contract_violation_report(task: Task, task_response: TaskResponse, metadata: TaskResponseMetadata, ctx: Context) -> Result<(), Error> {
if task.numberToBeSquared * task.numberToBeSquared != task_response.numberSquared {
let signature = ctx.sign_invalid_square_result(task.numberToBeSquared, task_response.numberSquared, metadata.submitter)?;
ctx.submit_report(task, task_response, metadata, epoch, signature)?;
}
Ok(())
}
Integration with Jobs
Reports can be closely integrated with the Jobs system to provide comprehensive monitoring and slashing capabilities. For example, you can create reports that are triggered by specific job outcomes or that monitor the overall performance of your AVS jobs.