-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(tenderdash-abci): deterministic request_id #38
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
[workspace] | ||
|
||
resolver = "2" | ||
members = ["abci", "proto-compiler", "proto"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
use tenderdash_proto::abci::request::Value; | ||
use prost::Message; | ||
use tenderdash_proto::abci::{self, request::Value}; | ||
use tracing::Level; | ||
|
||
const SPAN_NAME: &str = "abci"; | ||
|
@@ -20,16 +21,18 @@ macro_rules! block_span { | |
/// | ||
/// This function creates a new `tracing::span::EnteredSpan` based on the | ||
/// provided request. It uses the request to determine the endpoint and includes | ||
/// a unique request ID in the span. | ||
/// a request ID in the span. | ||
/// | ||
/// Request ID is deterministic and is based on the request value. It is | ||
/// not guaranteed to be unique, as the same request can be sent multiple times. | ||
/// However, it should be the same on all nodes for the same request. | ||
/// | ||
/// The level of the span is set to ERROR, so it will be included on all log | ||
/// levels. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `request` - A value that can be converted into a `Value`. Depending on the | ||
/// specific variant of `Value`, additional information like height, round, or | ||
/// path might be included in the span. | ||
/// * `request` - request to create a span for. | ||
/// | ||
/// # Returns | ||
/// | ||
|
@@ -38,20 +41,28 @@ macro_rules! block_span { | |
/// # Examples | ||
/// | ||
/// ``` | ||
/// # use tenderdash_proto::abci::{RequestInfo, request}; | ||
/// # use tenderdash_proto::abci::{RequestInfo, Request, request::Value}; | ||
/// # use tenderdash_abci::tracing_span::span; | ||
/// | ||
/// let request = request::Value::Info(RequestInfo::default()); | ||
/// let span = span(request); | ||
/// let request = Request { | ||
/// value: Some(Value::Info(Default::default())), | ||
/// }; | ||
/// let span = span(&request); | ||
/// ``` | ||
pub fn span<T>(request: T) -> tracing::span::EnteredSpan | ||
pub fn span(request: &abci::Request) -> tracing::span::EnteredSpan | ||
where | ||
T: Into<Value>, | ||
{ | ||
let value = request.into(); | ||
let value = request.value.as_ref().expect("request value is missing"); | ||
|
||
// we use md5 as we need 16-byte request id for uuid, and it doesn't have to be | ||
// cryptographically secure | ||
let mut md5 = lhash::Md5::new(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's pretty expensive, especially for the process and prepare proposal that contain state transitions. Should we do that only if a specific logging level is enabled? |
||
md5.update(&request.encode_to_vec()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, BLAKE3 much faster than md5 (which is not using in crypto world at all) |
||
let request_id = uuid::Uuid::from_bytes(md5.result()) | ||
.as_hyphenated() | ||
.to_string(); | ||
|
||
let endpoint = abci_method_name(&value); | ||
let request_id = uuid::Uuid::new_v4().to_string(); | ||
let endpoint = abci_method_name(value); | ||
|
||
let span = match value { | ||
Value::Info(_r) => tracing::span!(LEVEL, SPAN_NAME, endpoint, request_id), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach has downsides, especially if we want to filter by specific requests in elastic. There are endpoints like info, query, etc. where we don't have much difference so they will have the same ID.
We could have both: unique request ID and md5 so we will benefit from both depending on what we need.
That would be great if we could use the same request ID with tenderdash so we can easily filter related events.