Refactor inbound substream logic with async (#1325)

## Issue Addressed
#1112 

The logic is slightly different but still valid wrt to error handling.
- Inbound state is either Busy with a future that return the subtream (and info about the processing)
- The state machine works as follows:
  - `Idle` with pending responses => `Busy`
  - `Busy` => finished ? if so and there are new pending responses then `Busy`, if not then `Idle`
               => not finished remains `Busy`
- Add an `InboundInfo` for readability
- Other stuff:
  - Close inbound substreams when all expected responses are sent
  - Remove the error variants from `RPCCodedResponse` and use the codes instead
  - Fix various spelling mistakes because I got sloppy last time

Sorry for the delay

Co-authored-by: Age Manning <Age@AgeManning.com>
This commit is contained in:
divma
2020-07-23 12:30:43 +00:00
parent 3c4daec9af
commit ba10c80633
7 changed files with 232 additions and 520 deletions

View File

@@ -249,14 +249,7 @@ pub enum RPCCodedResponse<T: EthSpec> {
/// The response is a successful.
Success(RPCResponse<T>),
/// The response was invalid.
InvalidRequest(ErrorType),
/// The response indicates a server error.
ServerError(ErrorType),
/// There was an unknown response.
Unknown(ErrorType),
Error(RPCResponseErrorCode, ErrorType),
/// Received a stream termination indicating which response is being terminated.
StreamTermination(ResponseTermination),
@@ -275,9 +268,7 @@ impl<T: EthSpec> RPCCodedResponse<T> {
pub fn as_u8(&self) -> Option<u8> {
match self {
RPCCodedResponse::Success(_) => Some(0),
RPCCodedResponse::InvalidRequest(_) => Some(1),
RPCCodedResponse::ServerError(_) => Some(2),
RPCCodedResponse::Unknown(_) => Some(255),
RPCCodedResponse::Error(code, _) => Some(code.as_u8()),
RPCCodedResponse::StreamTermination(_) => None,
}
}
@@ -292,20 +283,12 @@ impl<T: EthSpec> RPCCodedResponse<T> {
/// Builds an RPCCodedResponse from a response code and an ErrorMessage
pub fn from_error(response_code: u8, err: String) -> Self {
match response_code {
1 => RPCCodedResponse::InvalidRequest(err.into()),
2 => RPCCodedResponse::ServerError(err.into()),
_ => RPCCodedResponse::Unknown(err.into()),
}
}
/// Builds an RPCCodedResponse from a response code and an ErrorMessage
pub fn from_error_code(response_code: RPCResponseErrorCode, err: String) -> Self {
match response_code {
RPCResponseErrorCode::InvalidRequest => RPCCodedResponse::InvalidRequest(err.into()),
RPCResponseErrorCode::ServerError => RPCCodedResponse::ServerError(err.into()),
RPCResponseErrorCode::Unknown => RPCCodedResponse::Unknown(err.into()),
}
let code = match response_code {
1 => RPCResponseErrorCode::InvalidRequest,
2 => RPCResponseErrorCode::ServerError,
_ => RPCResponseErrorCode::Unknown,
};
RPCCodedResponse::Error(code, err.into())
}
/// Specifies which response allows for multiple chunks for the stream handler.
@@ -318,30 +301,27 @@ impl<T: EthSpec> RPCCodedResponse<T> {
RPCResponse::Pong(_) => false,
RPCResponse::MetaData(_) => false,
},
RPCCodedResponse::InvalidRequest(_) => true,
RPCCodedResponse::ServerError(_) => true,
RPCCodedResponse::Unknown(_) => true,
RPCCodedResponse::Error(_, _) => true,
// Stream terminations are part of responses that have chunks
RPCCodedResponse::StreamTermination(_) => true,
}
}
/// Returns true if this response is an error. Used to terminate the stream after an error is
/// sent.
pub fn is_error(&self) -> bool {
/// Returns true if this response always terminates the stream.
pub fn close_after(&self) -> bool {
match self {
RPCCodedResponse::Success(_) => false,
_ => true,
}
}
}
pub fn error_code(&self) -> Option<RPCResponseErrorCode> {
impl RPCResponseErrorCode {
fn as_u8(&self) -> u8 {
match self {
RPCCodedResponse::Success(_) => None,
RPCCodedResponse::StreamTermination(_) => None,
RPCCodedResponse::InvalidRequest(_) => Some(RPCResponseErrorCode::InvalidRequest),
RPCCodedResponse::ServerError(_) => Some(RPCResponseErrorCode::ServerError),
RPCCodedResponse::Unknown(_) => Some(RPCResponseErrorCode::Unknown),
RPCResponseErrorCode::InvalidRequest => 1,
RPCResponseErrorCode::ServerError => 2,
RPCResponseErrorCode::Unknown => 255,
}
}
}
@@ -383,9 +363,7 @@ impl<T: EthSpec> std::fmt::Display for RPCCodedResponse<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
RPCCodedResponse::Success(res) => write!(f, "{}", res),
RPCCodedResponse::InvalidRequest(err) => write!(f, "Invalid Request: {:?}", err),
RPCCodedResponse::ServerError(err) => write!(f, "Server Error: {:?}", err),
RPCCodedResponse::Unknown(err) => write!(f, "Unknown Error: {:?}", err),
RPCCodedResponse::Error(code, err) => write!(f, "{}: {:?}", code, err),
RPCCodedResponse::StreamTermination(_) => write!(f, "Stream Termination"),
}
}