Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Fix the light client protocol protobuf schema
  • Loading branch information
tomaka committed Nov 18, 2022
commit c2ee6ba31d32e59497d0f03805444479d6e01d46
57 changes: 29 additions & 28 deletions client/network/light/src/light_client_requests/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,18 @@ where
let request = schema::v1::light::Request::decode(&payload[..])?;

let response = match &request.request {
Some(schema::v1::light::request::Request::RemoteCallRequest(r)) =>
self.on_remote_call_request(&peer, r)?,
Some(schema::v1::light::request::Request::RemoteReadRequest(r)) =>
self.on_remote_read_request(&peer, r)?,
Some(schema::v1::light::request::Request::RemoteReadChildRequest(r)) =>
self.on_remote_read_child_request(&peer, r)?,
None =>
return Err(HandleRequestError::BadRequest("Remote request without request data.")),
Some(schema::v1::light::request::Request::RemoteCallRequest(r)) => {
self.on_remote_call_request(&peer, r)?
},
Some(schema::v1::light::request::Request::RemoteReadRequest(r)) => {
self.on_remote_read_request(&peer, r)?
},
Some(schema::v1::light::request::Request::RemoteReadChildRequest(r)) => {
self.on_remote_read_child_request(&peer, r)?
},
None => {
return Err(HandleRequestError::BadRequest("Remote request without request data."))
},
};

let mut data = Vec::new();
Expand All @@ -173,10 +177,7 @@ where
let block = Decode::decode(&mut request.block.as_ref())?;

let response = match self.client.execution_proof(block, &request.method, &request.data) {
Ok((_, proof)) => {
let r = schema::v1::light::RemoteCallResponse { proof: proof.encode() };
Some(schema::v1::light::response::Response::RemoteCallResponse(r))
},
Ok((_, proof)) => schema::v1::light::RemoteCallResponse { proof: Some(proof.encode()) },
Err(e) => {
trace!(
"remote call request from {} ({} at {:?}) failed with: {}",
Expand All @@ -185,11 +186,13 @@ where
request.block,
e,
);
None
schema::v1::light::RemoteCallResponse { proof: None }
},
};

Ok(schema::v1::light::Response { response })
Ok(schema::v1::light::Response {
response: Some(schema::v1::light::response::Response::RemoteCallResponse(response)),
})
}

fn on_remote_read_request(
Expand All @@ -199,7 +202,7 @@ where
) -> Result<schema::v1::light::Response, HandleRequestError> {
if request.keys.is_empty() {
debug!("Invalid remote read request sent by {}.", peer);
return Err(HandleRequestError::BadRequest("Remote read request without keys."))
return Err(HandleRequestError::BadRequest("Remote read request without keys."));
}

trace!(
Expand All @@ -213,10 +216,7 @@ where

let response =
match self.client.read_proof(block, &mut request.keys.iter().map(AsRef::as_ref)) {
Ok(proof) => {
let r = schema::v1::light::RemoteReadResponse { proof: proof.encode() };
Some(schema::v1::light::response::Response::RemoteReadResponse(r))
},
Ok(proof) => schema::v1::light::RemoteReadResponse { proof: Some(proof.encode()) },
Err(error) => {
trace!(
"remote read request from {} ({} at {:?}) failed with: {}",
Expand All @@ -225,11 +225,13 @@ where
request.block,
error,
);
None
schema::v1::light::RemoteReadResponse { proof: None }
},
};

Ok(schema::v1::light::Response { response })
Ok(schema::v1::light::Response {
response: Some(schema::v1::light::response::Response::RemoteReadResponse(response)),
})
}

fn on_remote_read_child_request(
Expand All @@ -239,7 +241,7 @@ where
) -> Result<schema::v1::light::Response, HandleRequestError> {
if request.keys.is_empty() {
debug!("Invalid remote child read request sent by {}.", peer);
return Err(HandleRequestError::BadRequest("Remove read child request without keys."))
return Err(HandleRequestError::BadRequest("Remove read child request without keys."));
}

trace!(
Expand All @@ -264,10 +266,7 @@ where
&mut request.keys.iter().map(AsRef::as_ref),
)
}) {
Ok(proof) => {
let r = schema::v1::light::RemoteReadResponse { proof: proof.encode() };
Some(schema::v1::light::response::Response::RemoteReadResponse(r))
},
Ok(proof) => schema::v1::light::RemoteReadResponse { proof: Some(proof.encode()) },
Err(error) => {
trace!(
"remote read child request from {} ({} {} at {:?}) failed with: {}",
Expand All @@ -277,11 +276,13 @@ where
request.block,
error,
);
None
schema::v1::light::RemoteReadResponse { proof: None }
},
};

Ok(schema::v1::light::Response { response })
Ok(schema::v1::light::Response {
response: Some(schema::v1::light::response::Response::RemoteReadResponse(response)),
})
}
}

Expand Down
32 changes: 32 additions & 0 deletions client/network/light/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,35 @@ pub(crate) mod v1 {
include!(concat!(env!("OUT_DIR"), "/api.v1.light.rs"));
}
}

#[cfg(test)]
mod tests {
use prost::Message as _;

#[test]
fn with_proof_encodes_correctly() {
let encoded = super::v1::light::Response {
response: Some(super::v1::light::response::Response::RemoteReadResponse(
super::v1::light::RemoteReadResponse { proof: Some(Vec::new()) },
)),
}
.encode_to_vec();

// Make sure that the response contains one field of number 2 and wire type 2 (message),
// then another field of number 2 and wire type 2 (bytes), then a length of 0.
assert_eq!(encoded, vec![(2 << 3) | 2, 2, (2 << 3) | 2, 0]);
}

#[test]
fn no_proof_encodes_correctly() {
let encoded = super::v1::light::Response {
response: Some(super::v1::light::response::Response::RemoteReadResponse(
super::v1::light::RemoteReadResponse { proof: None },
)),
}
.encode_to_vec();

// Make sure that the response contains one field of number 2 and wire type 2 (message).
assert_eq!(encoded, vec![(2 << 3) | 2, 0]);
}
}
28 changes: 15 additions & 13 deletions client/network/light/src/schema/light.v1.proto
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Schema definition for light client messages.

syntax = "proto3";
syntax = "proto2";

package api.v1.light;

// A pair of arbitrary bytes.
message Pair {
// The first element of the pair.
bytes fst = 1;
required bytes fst = 1;
// The second element of the pair.
bytes snd = 2;
required bytes snd = 2;
}

// Enumerate all possible light client request messages.
Expand All @@ -34,40 +34,42 @@ message Response {
// Remote call request.
message RemoteCallRequest {
// Block at which to perform call.
bytes block = 2;
required bytes block = 2;
// Method name.
string method = 3;
required string method = 3;
// Call data.
bytes data = 4;
required bytes data = 4;
}

// Remote call response.
message RemoteCallResponse {
// Execution proof.
bytes proof = 2;
// Execution proof. If missing, indicates that the remote couldn't answer, for example because
// the block is pruned.
optional bytes proof = 2;
}

// Remote storage read request.
message RemoteReadRequest {
// Block at which to perform call.
bytes block = 2;
required bytes block = 2;
// Storage keys.
repeated bytes keys = 3;
}

// Remote read response.
message RemoteReadResponse {
// Read proof.
bytes proof = 2;
// Read proof. If missing, indicates that the remote couldn't answer, for example because
// the block is pruned.
optional bytes proof = 2;
}

// Remote storage read child request.
message RemoteReadChildRequest {
// Block at which to perform call.
bytes block = 2;
required bytes block = 2;
// Child Storage key, this is relative
// to the child type storage location.
bytes storage_key = 3;
required bytes storage_key = 3;
// Storage keys.
repeated bytes keys = 6;
}