[fix] make cNIGHT grpc utxo queries deterministic#796
[fix] make cNIGHT grpc utxo queries deterministic#796lowhung wants to merge 10 commits intoinput-output-hk:mainfrom
Conversation
| } | ||
| message UtxoEventsResponse { | ||
| repeated UtxoEvent events = 1; | ||
| optional CardanoPosition next_position = 2; |
There was a problem hiding this comment.
I don't think this is needed. The db-sync implementation uses the last event.
truncated_utxos
.last()
.map_or(start_position.clone(), |u| u.header.tx_position.clone())
.increment(),
There was a problem hiding this comment.
Hmmmm I wanted to keep next_position in the response. The "legacy compatibility" behaviour here is a paired contract once the server applies the old truncation semantics, it also needs to return the matching next position...otherwise the client has to infer end again, which is the split contract I was hoping to remove. 09c780c.
There was a problem hiding this comment.
The request now carries the full start_position, so the endpoint can compute the exact fallback instead of making the client infer end again. That keeps truncation and continuation semantics together on the server. Updated in 5454aad
| fn stable_block_window( | ||
| protocol_params: &ProtocolParams, | ||
| as_of_timestamp_unix_millis: u64, | ||
| ) -> Result<StableBlockWindow, Status> { | ||
| let shelley = protocol_params.shelley.as_ref().ok_or_else(|| { | ||
| Status::failed_precondition("latest protocol parameters do not include shelley params") | ||
| })?; | ||
|
|
||
| let active_slots_coeff_numerator = u128::from(*shelley.active_slots_coeff.numer()); | ||
| let active_slots_coeff_denominator = u128::from(*shelley.active_slots_coeff.denom()); | ||
| if active_slots_coeff_numerator == 0 { | ||
| return Err(Status::failed_precondition( | ||
| "active_slots_coeff numerator must be non-zero", | ||
| )); | ||
| } | ||
|
|
||
| let slot_duration_millis = u128::from(shelley.slot_length).saturating_mul(1000); | ||
| let min_block_age_millis = rounded_div_u128_to_u64( | ||
| slot_duration_millis | ||
| .saturating_mul(u128::from(shelley.security_param)) | ||
| .saturating_mul(active_slots_coeff_denominator), | ||
| active_slots_coeff_numerator, | ||
| )?; | ||
| let max_block_age_millis = min_block_age_millis.saturating_mul(3); | ||
|
|
||
| Ok(StableBlockWindow { | ||
| min_block_timestamp_unix_millis: as_of_timestamp_unix_millis | ||
| .saturating_sub(max_block_age_millis), | ||
| max_block_timestamp_unix_millis: as_of_timestamp_unix_millis | ||
| .saturating_sub(min_block_age_millis), | ||
| }) | ||
| } |
There was a problem hiding this comment.
I think StableBlockWindow should be stored in state instead of having to query each time.
There was a problem hiding this comment.
Addressed in e8a3cb9. I did not store a literal timestamped StableBlockWindow, since that depends on each request’s as_of_timestamp_unix_millis; instead midnight_state::State now caches the derived bounds, and the gRPC service builds the request-specific window from those cached bounds.
Description
This PR moves the remaining gRPC-side compatibility logic for Midnight mainchain reads into Acropolis so a gRPC-backed node can match the existing db-sync-backed node behavior.
On the cNIGHT path, the endpoint now owns the full legacy compatibility contract instead of splitting it across the node client and the server:
GetUtxoEventsis anchored to a caller-suppliedend_block_hashso event collection is bounded to a chosen Cardano head.start_position, and the response includesnext_position, so the server owns both truncation and continuation semantics.next_positiontimestamps are emitted in millis.On the mc-hash path, the endpoint now answers historical stability queries instead of only current tip-relative ones:
GetLatestStableBlockandGetStableBlocktakestability_offsetplusas_of_timestamp_unix_millis.midnight_state::State, so the service no longer queries the parameters module on every gRPC request.Related Issue(s)
Relates to the matching Midnight node client changes in whankinsiv/midnight-node-acropolis#16.
How was this tested?
cargo test -p acropolis_module_midnight_statecargo clippy -p acropolis_module_midnight_state -- -D warningsChecklist
Impact / Side effects
This changes the Acropolis gRPC contract used by the Midnight node client:
GetUtxoEventsnow requiresend_block_hashandstart_position, and returnsnext_position.as_of_timestamp_unix_millisand usestability_offsetnaming.The intended effect is to make the gRPC-backed node produce the same mainchain-derived inputs as the existing db-sync-backed node while keeping the compatibility logic server-owned.
Reviewer notes / Areas to focus