-
Notifications
You must be signed in to change notification settings - Fork 305
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1e8b1b8
commit 52a3dbb
Showing
23 changed files
with
1,554 additions
and
1,746 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,204 +0,0 @@ | ||
use std::pin::Pin; | ||
use std::sync::Arc; | ||
|
||
use async_stream::try_stream; | ||
use futures::StreamExt; | ||
use futures::TryStreamExt; | ||
use penumbra_asset::{asset, Value}; | ||
use penumbra_chain::component::AppHashRead; | ||
use penumbra_chain::component::StateReadExt as _; | ||
use penumbra_dex::component::router::RouteAndFill; | ||
use penumbra_dex::component::router::RoutingParams; | ||
use penumbra_dex::{ | ||
component::{PositionRead, StateReadExt}, | ||
lp::{position, position::Position}, | ||
DirectedTradingPair, SwapExecution, TradingPair, | ||
}; | ||
use penumbra_governance::StateReadExt as _; | ||
use penumbra_proto::{ | ||
self as proto, | ||
client::v1alpha1::{ | ||
specific_query_service_server::SpecificQueryService, BatchSwapOutputDataRequest, | ||
DenomMetadataByIdRequest, KeyValueRequest, KeyValueResponse, ProposalInfoRequest, | ||
ProposalInfoResponse, ProposalRateDataRequest, ProposalRateDataResponse, | ||
ValidatorStatusRequest, | ||
}, | ||
StateReadProto as _, | ||
}; | ||
use penumbra_sct::component::StateReadExt as _; | ||
use penumbra_shielded_pool::component::SupplyRead as _; | ||
use penumbra_stake::rate::RateData; | ||
use penumbra_stake::StateReadExt as _; | ||
|
||
use penumbra_proto::DomainType; | ||
use penumbra_storage::StateDelta; | ||
use penumbra_storage::StateRead; | ||
|
||
use tonic::Status; | ||
use tracing::instrument; | ||
|
||
// We need to use the tracing-futures version of Instrument, | ||
// because we want to instrument a Stream, and the Stream trait | ||
// isn't in std, and the tracing::Instrument trait only works with | ||
// (stable) std types. | ||
//use tracing_futures::Instrument; | ||
|
||
use super::Info; | ||
|
||
#[tonic::async_trait] | ||
impl SpecificQueryService for Info { | ||
|
||
|
||
|
||
#[instrument(skip(self, request))] | ||
async fn proposal_info( | ||
&self, | ||
request: tonic::Request<ProposalInfoRequest>, | ||
) -> Result<tonic::Response<ProposalInfoResponse>, Status> { | ||
let state = self.storage.latest_snapshot(); | ||
state | ||
.check_chain_id(&request.get_ref().chain_id) | ||
.await | ||
.map_err(|e| tonic::Status::unknown(format!("chain_id not OK: {e}")))?; | ||
let proposal_id = request.into_inner().proposal_id; | ||
|
||
let start_block_height = state | ||
.proposal_voting_start(proposal_id) | ||
.await | ||
.map_err(|e| tonic::Status::internal(e.to_string()))? | ||
.ok_or_else(|| tonic::Status::unknown(format!("proposal {proposal_id} not found")))?; | ||
|
||
let start_position = state | ||
.proposal_voting_start_position(proposal_id) | ||
.await | ||
.map_err(|e| tonic::Status::internal(e.to_string()))? | ||
.ok_or_else(|| tonic::Status::unknown(format!("proposal {proposal_id} not found")))?; | ||
|
||
Ok(tonic::Response::new(ProposalInfoResponse { | ||
start_block_height, | ||
start_position: start_position.into(), | ||
})) | ||
} | ||
|
||
type ProposalRateDataStream = Pin< | ||
Box<dyn futures::Stream<Item = Result<ProposalRateDataResponse, tonic::Status>> + Send>, | ||
>; | ||
|
||
#[instrument(skip(self, request))] | ||
async fn proposal_rate_data( | ||
&self, | ||
request: tonic::Request<ProposalRateDataRequest>, | ||
) -> Result<tonic::Response<Self::ProposalRateDataStream>, Status> { | ||
let state = self.storage.latest_snapshot(); | ||
state | ||
.check_chain_id(&request.get_ref().chain_id) | ||
.await | ||
.map_err(|e| tonic::Status::unknown(format!("chain_id not OK: {e}")))?; | ||
let proposal_id = request.into_inner().proposal_id; | ||
|
||
use penumbra_governance::state_key; | ||
|
||
let s = state.prefix(&state_key::all_rate_data_at_proposal_start(proposal_id)); | ||
Ok(tonic::Response::new( | ||
s.map_ok(|i: (String, RateData)| { | ||
let (_key, rate_data) = i; | ||
ProposalRateDataResponse { | ||
rate_data: Some(rate_data.into()), | ||
} | ||
}) | ||
.map_err(|e: anyhow::Error| { | ||
tonic::Status::unavailable(format!("error getting prefix value from storage: {e}")) | ||
}) | ||
// TODO: how do we instrument a Stream | ||
//.instrument(Span::current()) | ||
.boxed(), | ||
)) | ||
} | ||
|
||
#[instrument(skip(self, request))] | ||
async fn key_value( | ||
&self, | ||
request: tonic::Request<KeyValueRequest>, | ||
) -> Result<tonic::Response<KeyValueResponse>, Status> { | ||
let state = self.storage.latest_snapshot(); | ||
// We map the error here to avoid including `tonic` as a dependency | ||
// in the `chain` crate, to support its compilation to wasm. | ||
state | ||
.check_chain_id(&request.get_ref().chain_id) | ||
.await | ||
.map_err(|e| tonic::Status::unknown(format!("chain_id not OK: {e}")))?; | ||
|
||
let request = request.into_inner(); | ||
tracing::debug!(?request); | ||
|
||
if request.key.is_empty() { | ||
return Err(Status::invalid_argument("key is empty")); | ||
} | ||
|
||
// TODO(erwan): we are unconditionally generating the proof here; we shouldn't do that if the | ||
// request doesn't ask for it | ||
let (some_value, proof) = state | ||
.get_with_proof_to_apphash(request.key.into_bytes()) | ||
.await | ||
.map_err(|e| tonic::Status::internal(e.to_string()))?; | ||
|
||
Ok(tonic::Response::new(KeyValueResponse { | ||
value: some_value.map(Into::into), | ||
proof: if request.proof { | ||
Some(ibc_proto::ibc::core::commitment::v1::MerkleProof { | ||
proofs: proof | ||
.proofs | ||
.into_iter() | ||
.map(|p| { | ||
let mut encoded = Vec::new(); | ||
prost::Message::encode(&p, &mut encoded).expect("able to encode proof"); | ||
prost::Message::decode(&*encoded).expect("able to decode proof") | ||
}) | ||
.collect(), | ||
}) | ||
} else { | ||
None | ||
}, | ||
})) | ||
} | ||
|
||
type PrefixValueStream = | ||
Pin<Box<dyn futures::Stream<Item = Result<PrefixValueResponse, tonic::Status>> + Send>>; | ||
|
||
#[instrument(skip(self, request))] | ||
async fn prefix_value( | ||
&self, | ||
request: tonic::Request<PrefixValueRequest>, | ||
) -> Result<tonic::Response<Self::PrefixValueStream>, Status> { | ||
let state = self.storage.latest_snapshot(); | ||
state | ||
.check_chain_id(&request.get_ref().chain_id) | ||
.await | ||
.map_err(|e| tonic::Status::unknown(format!("chain_id not OK: {e}")))?; | ||
let request = request.into_inner(); | ||
tracing::debug!(?request); | ||
|
||
if request.prefix.is_empty() { | ||
return Err(Status::invalid_argument("prefix is empty")); | ||
} | ||
|
||
Ok(tonic::Response::new( | ||
state | ||
.prefix_raw(&request.prefix) | ||
.map_ok(|i: (String, Vec<u8>)| { | ||
let (key, value) = i; | ||
PrefixValueResponse { key, value } | ||
}) | ||
.map_err(|e: anyhow::Error| { | ||
tonic::Status::unavailable(format!( | ||
"error getting prefix value from storage: {e}" | ||
)) | ||
}) | ||
// TODO: how do we instrument a Stream | ||
//.instrument(Span::current()) | ||
.boxed(), | ||
)) | ||
} | ||
|
||
|
||
} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.