Skip to content
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

Add ws api response improvements #24

Merged
merged 6 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 34 additions & 9 deletions rust/src/client_api/client_events.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use flatbuffers::WIPOffset;
use std::borrow::Cow;
use std::fmt::Display;
use std::net::SocketAddr;

use serde::{de::DeserializeOwned, Deserialize, Serialize};

Expand Down Expand Up @@ -200,7 +201,7 @@ pub enum ContractError {
MissingRelated {
key: crate::contract_interface::ContractInstanceId,
},
#[error("missing related contract: {key}")]
#[error("missing contract: {key}")]
MissingContract {
key: crate::contract_interface::ContractInstanceId,
},
Expand Down Expand Up @@ -245,8 +246,12 @@ pub enum ClientRequest<'a> {
ContractOp(#[serde(borrow)] ContractRequest<'a>),
Disconnect { cause: Option<Cow<'static, str>> },
Authenticate { token: String },
NodeQueries(ConnectedPeers),
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ConnectedPeers {}

impl ClientRequest<'_> {
pub fn into_owned(self) -> ClientRequest<'static> {
match self {
Expand All @@ -270,10 +275,10 @@ impl ClientRequest<'_> {
}
ContractRequest::Get {
key,
fetch_contract,
return_contract_code,
} => ContractRequest::Get {
key,
fetch_contract,
return_contract_code,
},
ContractRequest::Subscribe { key, summary } => ContractRequest::Subscribe {
key,
Expand All @@ -288,6 +293,7 @@ impl ClientRequest<'_> {
}
ClientRequest::Disconnect { cause } => ClientRequest::Disconnect { cause },
ClientRequest::Authenticate { token } => ClientRequest::Authenticate { token },
ClientRequest::NodeQueries(query) => ClientRequest::NodeQueries(query),
}
}

Expand Down Expand Up @@ -360,7 +366,7 @@ pub enum ContractRequest<'a> {
/// Key of the contract.
key: ContractKey,
/// If this flag is set then fetch also the contract itself.
fetch_contract: bool,
return_contract_code: bool,
},
/// Subscribe to the changes in a given contract. Implicitly starts a get operation
/// if the contract is not present yet.
Expand Down Expand Up @@ -388,10 +394,10 @@ impl ContractRequest<'_> {
},
Self::Get {
key,
fetch_contract,
return_contract_code: fetch_contract,
} => ContractRequest::Get {
key,
fetch_contract,
return_contract_code: fetch_contract,
},
Self::Subscribe { key, summary } => ContractRequest::Subscribe {
key,
Expand All @@ -418,7 +424,7 @@ impl<'a> TryFromFbs<&FbsContractRequest<'a>> for ContractRequest<'a> {
let fetch_contract = get.fetch_contract();
ContractRequest::Get {
key,
fetch_contract,
return_contract_code: fetch_contract,
}
}
ContractRequestType::Put => {
Expand Down Expand Up @@ -554,7 +560,7 @@ impl Display for ClientRequest<'_> {
ContractRequest::Update { key, .. } => write!(f, "update request for {key}"),
ContractRequest::Get {
key,
fetch_contract: contract,
return_contract_code: contract,
..
} => {
write!(
Expand Down Expand Up @@ -590,6 +596,7 @@ impl Display for ClientRequest<'_> {
},
ClientRequest::Disconnect { .. } => write!(f, "client disconnected"),
ClientRequest::Authenticate { .. } => write!(f, "authenticate"),
ClientRequest::NodeQueries(query) => write!(f, "node queries: {:?}", query),
}
}
}
Expand Down Expand Up @@ -669,10 +676,18 @@ pub enum HostResponse<T = WrappedState> {
key: DelegateKey,
values: Vec<OutboundDelegateMsg>,
},
QueryResponse(QueryResponse),
/// A requested action which doesn't require an answer was performed successfully.
Ok,
}

type Peer = String;

#[derive(Serialize, Deserialize, Debug)]
pub enum QueryResponse {
ConnectedPeers { peers: Vec<(Peer, SocketAddr)> },
}

impl HostResponse {
pub fn unwrap_put(self) -> ContractKey {
if let Self::ContractResponse(ContractResponse::PutResponse { key }) = self {
Expand Down Expand Up @@ -1095,6 +1110,7 @@ impl HostResponse {
finish_host_response_buffer(&mut builder, host_response_offset);
Ok(builder.finished_data().to_vec())
}
ContractResponse::SubscribeResponse { .. } => todo!(),
},
HostResponse::DelegateResponse { key, values } => {
let key_data = builder.create_vector(key.bytes());
Expand Down Expand Up @@ -1310,6 +1326,7 @@ impl HostResponse {
finish_host_response_buffer(&mut builder, host_response_offset);
Ok(builder.finished_data().to_vec())
}
HostResponse::QueryResponse(_) => unimplemented!(),
}
}
}
Expand All @@ -1330,9 +1347,13 @@ impl std::fmt::Display for HostResponse {
ContractResponse::UpdateNotification { key, .. } => {
f.write_fmt(format_args!("update notification for `{key}`"))
}
ContractResponse::SubscribeResponse { key, .. } => {
f.write_fmt(format_args!("subscribe response for `{key}`"))
}
},
HostResponse::DelegateResponse { .. } => write!(f, "delegate responses"),
HostResponse::Ok => write!(f, "ok response"),
HostResponse::QueryResponse(_) => write!(f, "query response"),
}
}
}
Expand Down Expand Up @@ -1361,6 +1382,10 @@ pub enum ContractResponse<T = WrappedState> {
#[serde(deserialize_with = "StateSummary::deser_state_summary")]
summary: StateSummary<'static>,
},
SubscribeResponse {
key: ContractKey,
subscribed: bool,
},
}

impl<T> From<ContractResponse<T>> for HostResponse<T> {
Expand Down Expand Up @@ -1436,7 +1461,7 @@ mod client_request_test {
match request {
ContractRequest::Get {
key,
fetch_contract,
return_contract_code: fetch_contract,
} => {
assert_eq!(key.encoded_contract_id(), EXPECTED_ENCODED_CONTRACT_ID);
assert!(!fetch_contract);
Expand Down
8 changes: 7 additions & 1 deletion rust/src/code_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde_with::serde_as;
const CONTRACT_KEY_SIZE: usize = 32;

#[serde_as]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Hash)]
#[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Hash)]
#[cfg_attr(any(feature = "testing", test), derive(arbitrary::Arbitrary))]
pub struct CodeHash(#[serde_as(as = "[_; CONTRACT_KEY_SIZE]")] pub(crate) [u8; CONTRACT_KEY_SIZE]);

Expand Down Expand Up @@ -71,3 +71,9 @@ impl Display for CodeHash {
write!(f, "{}", self.encode())
}
}

impl std::fmt::Debug for CodeHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("CodeHash").field(&self.encode()).finish()
}
}
28 changes: 25 additions & 3 deletions rust/src/contract_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ impl<'a> DerefMut for StateSummary<'a> {
/// It is the part of the executable belonging to the full specification
/// and does not include any other metadata (like the parameters).
#[serde_as]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Serialize, Deserialize, Clone)]
#[cfg_attr(any(feature = "testing", test), derive(arbitrary::Arbitrary))]
pub struct ContractCode<'a> {
// TODO: conver this to Arc<[u8]> instead
Expand Down Expand Up @@ -900,9 +900,17 @@ impl std::fmt::Display for ContractCode<'_> {
}
}

impl std::fmt::Debug for ContractCode<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ContractCode")
.field("hash", &self.code_hash);
Ok(())
}
}

/// The key representing the hash of the contract executable code hash and a set of `parameters`.
#[serde_as]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Hash)]
#[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Hash)]
#[cfg_attr(any(feature = "testing", test), derive(arbitrary::Arbitrary))]
#[repr(transparent)]
pub struct ContractInstanceId(#[serde_as(as = "[_; CONTRACT_KEY_SIZE]")] [u8; CONTRACT_KEY_SIZE]);
Expand Down Expand Up @@ -970,6 +978,14 @@ impl Display for ContractInstanceId {
}
}

impl std::fmt::Debug for ContractInstanceId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("ContractInstanceId")
.field(&self.encode())
.finish()
}
}

/// A complete key specification, that represents a cryptographic hash that identifies the contract.
#[serde_as]
#[derive(Debug, Eq, Copy, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -1137,7 +1153,7 @@ fn internal_fmt_key(

// TODO: get rid of this when State is internally an Arc<[u8]>
/// The state for a contract.
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
#[derive(PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(any(feature = "testing", test), derive(arbitrary::Arbitrary))]
pub struct WrappedState(
#[serde(
Expand Down Expand Up @@ -1223,6 +1239,12 @@ impl std::fmt::Display for WrappedState {
}
}

impl std::fmt::Debug for WrappedState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<Self as Display>::fmt(self, f)
}
}

/// Just as `freenet_stdlib::Contract` but with some convenience impl.
#[non_exhaustive]
#[derive(Clone, Debug, Serialize, Deserialize)]
Expand Down
Loading