github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/rust/src/processor/mod.rs (about)

     1  /*
     2   * Copyright 2017 Bitwise IO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   * -----------------------------------------------------------------------------
    16   */
    17  
    18  extern crate ctrlc;
    19  extern crate protobuf;
    20  extern crate rand;
    21  extern crate zmq;
    22  
    23  use std::error::Error;
    24  use std::sync::atomic::{AtomicBool, Ordering};
    25  use std::sync::mpsc::RecvTimeoutError;
    26  use std::sync::Arc;
    27  use std::time::Duration;
    28  
    29  use self::rand::Rng;
    30  
    31  pub mod handler;
    32  
    33  use messages::network::PingResponse;
    34  use messages::processor::TpProcessRequest;
    35  use messages::processor::TpProcessResponse;
    36  use messages::processor::TpProcessResponse_Status;
    37  use messages::processor::TpRegisterRequest;
    38  use messages::processor::TpUnregisterRequest;
    39  use messages::validator::Message_MessageType;
    40  use messaging::stream::MessageConnection;
    41  use messaging::stream::MessageSender;
    42  use messaging::stream::ReceiveError;
    43  use messaging::stream::SendError;
    44  use messaging::zmq_stream::ZmqMessageConnection;
    45  use messaging::zmq_stream::ZmqMessageSender;
    46  use protobuf::Message as M;
    47  use protobuf::RepeatedField;
    48  
    49  use self::handler::ApplyError;
    50  use self::handler::TransactionContext;
    51  use self::handler::TransactionHandler;
    52  
    53  /// Generates a random correlation id for use in Message
    54  fn generate_correlation_id() -> String {
    55      const LENGTH: usize = 16;
    56      rand::thread_rng().gen_ascii_chars().take(LENGTH).collect()
    57  }
    58  
    59  pub struct TransactionProcessor<'a> {
    60      endpoint: String,
    61      conn: ZmqMessageConnection,
    62      handlers: Vec<&'a TransactionHandler>,
    63  }
    64  
    65  impl<'a> TransactionProcessor<'a> {
    66      /// TransactionProcessor is for communicating with a
    67      /// validator and routing transaction processing requests to a registered
    68      /// handler. It uses ZMQ and channels to handle requests concurrently.
    69      pub fn new(endpoint: &str) -> TransactionProcessor {
    70          TransactionProcessor {
    71              endpoint: String::from(endpoint),
    72              conn: ZmqMessageConnection::new(endpoint),
    73              handlers: Vec::new(),
    74          }
    75      }
    76  
    77      /// Adds a transaction family handler
    78      ///
    79      /// # Arguments
    80      ///
    81      /// * handler - the handler to be added
    82      pub fn add_handler(&mut self, handler: &'a TransactionHandler) {
    83          self.handlers.push(handler);
    84      }
    85  
    86      fn register(&mut self, mut sender: ZmqMessageSender, unregister: &Arc<AtomicBool>) -> bool {
    87          for handler in &self.handlers {
    88              for version in handler.family_versions() {
    89                  let mut request = TpRegisterRequest::new();
    90                  request.set_family(handler.family_name().clone());
    91                  request.set_version(version.clone());
    92                  request.set_namespaces(RepeatedField::from_vec(handler.namespaces().clone()));
    93                  info!(
    94                      "sending TpRegisterRequest: {} {}",
    95                      &handler.family_name(),
    96                      &version
    97                  );
    98                  let serialized = match request.write_to_bytes() {
    99                      Ok(serialized) => serialized,
   100                      Err(err) => {
   101                          error!("Serialization failed: {}", err.description());
   102                          // try reconnect
   103                          return false;
   104                      }
   105                  };
   106                  let x: &[u8] = &serialized;
   107  
   108                  let mut future = match sender.send(
   109                      Message_MessageType::TP_REGISTER_REQUEST,
   110                      &generate_correlation_id(),
   111                      x,
   112                  ) {
   113                      Ok(fut) => fut,
   114                      Err(err) => {
   115                          error!("Registration failed: {}", err.description());
   116                          // try reconnect
   117                          return false;
   118                      }
   119                  };
   120  
   121                  // Absorb the TpRegisterResponse message
   122                  loop {
   123                      match future.get_timeout(Duration::from_millis(10000)) {
   124                          Ok(_) => break,
   125                          Err(_) => {
   126                              if unregister.load(Ordering::SeqCst) {
   127                                  return false;
   128                              }
   129                          }
   130                      };
   131                  }
   132              }
   133          }
   134          true
   135      }
   136  
   137      fn unregister(&mut self, mut sender: ZmqMessageSender) {
   138          let request = TpUnregisterRequest::new();
   139          info!("sending TpUnregisterRequest");
   140          let serialized = match request.write_to_bytes() {
   141              Ok(serialized) => serialized,
   142              Err(err) => {
   143                  error!("Serialization failed: {}", err.description());
   144                  return;
   145              }
   146          };
   147          let x: &[u8] = &serialized;
   148  
   149          let mut future = match sender.send(
   150              Message_MessageType::TP_UNREGISTER_REQUEST,
   151              &generate_correlation_id(),
   152              x,
   153          ) {
   154              Ok(fut) => fut,
   155              Err(err) => {
   156                  error!("Unregistration failed: {}", err.description());
   157                  return;
   158              }
   159          };
   160          // Absorb the TpUnregisterResponse message, wait one second for response then continue
   161          match future.get_timeout(Duration::from_millis(1000)) {
   162              Ok(_) => (),
   163              Err(err) => {
   164                  info!("Unregistration failed: {}", err.description());
   165              }
   166          };
   167      }
   168  
   169      /// Connects the transaction processor to a validator and starts
   170      /// listening for requests and routing them to an appropriate
   171      /// transaction handler.
   172      pub fn start(&mut self) {
   173          let unregister = Arc::new(AtomicBool::new(false));
   174          let r = unregister.clone();
   175          ctrlc::set_handler(move || {
   176              r.store(true, Ordering::SeqCst);
   177          }).expect("Error setting Ctrl-C handler");
   178  
   179          let mut first_time = true;
   180          let mut restart = true;
   181  
   182          while restart {
   183              info!("connecting to endpoint: {}", self.endpoint);
   184              if first_time {
   185                  first_time = false;
   186              } else {
   187                  self.conn = ZmqMessageConnection::new(&self.endpoint);
   188              }
   189              let (mut sender, receiver) = self.conn.create();
   190  
   191              if unregister.load(Ordering::SeqCst) {
   192                  self.unregister(sender.clone());
   193                  restart = false;
   194                  continue;
   195              }
   196  
   197              // if registration is not succesful, retry
   198              if self.register(sender.clone(), &unregister.clone()) {
   199                  ()
   200              } else {
   201                  continue;
   202              }
   203  
   204              loop {
   205                  if unregister.load(Ordering::SeqCst) {
   206                      self.unregister(sender.clone());
   207                      restart = false;
   208                      break;
   209                  }
   210                  match receiver.recv_timeout(Duration::from_millis(1000)) {
   211                      Ok(r) => {
   212                          // Check if we have a message
   213                          let message = match r {
   214                              Ok(message) => message,
   215                              Err(ReceiveError::DisconnectedError) => {
   216                                  info!("Trying to Reconnect");
   217                                  break;
   218                              }
   219                              Err(err) => {
   220                                  error!("Error: {}", err.description());
   221                                  continue;
   222                              }
   223                          };
   224  
   225                          info!("Message: {}", message.get_correlation_id());
   226  
   227                          match message.get_message_type() {
   228                              Message_MessageType::TP_PROCESS_REQUEST => {
   229                                  let request: TpProcessRequest =
   230                                      match protobuf::parse_from_bytes(&message.get_content()) {
   231                                          Ok(request) => request,
   232                                          Err(err) => {
   233                                              error!(
   234                                                  "Cannot parse TpProcessRequest: {}",
   235                                                  err.description()
   236                                              );
   237                                              continue;
   238                                          }
   239                                      };
   240  
   241                                  let mut context = TransactionContext::new(
   242                                      request.get_context_id(),
   243                                      sender.clone(),
   244                                  );
   245  
   246                                  let mut response = TpProcessResponse::new();
   247                                  match self.handlers[0].apply(&request, &mut context) {
   248                                      Ok(()) => {
   249                                          response.set_status(TpProcessResponse_Status::OK);
   250                                          info!("TP_PROCESS_REQUEST sending TpProcessResponse: OK");
   251                                      }
   252                                      Err(ApplyError::InvalidTransaction(msg)) => {
   253                                          response.set_status(
   254                                              TpProcessResponse_Status::INVALID_TRANSACTION,
   255                                          );
   256                                          response.set_message(msg.clone());
   257                                          info!(
   258                                              "TP_PROCESS_REQUEST sending TpProcessResponse: {}",
   259                                              msg
   260                                          );
   261                                      }
   262                                      Err(err) => {
   263                                          response
   264                                              .set_status(TpProcessResponse_Status::INTERNAL_ERROR);
   265                                          response.set_message(String::from(err.description()));
   266                                          info!(
   267                                              "TP_PROCESS_REQUEST sending TpProcessResponse: {}",
   268                                              err.description()
   269                                          );
   270                                      }
   271                                  };
   272  
   273                                  let serialized = match response.write_to_bytes() {
   274                                      Ok(serialized) => serialized,
   275                                      Err(err) => {
   276                                          error!("Serialization failed: {}", err.description());
   277                                          continue;
   278                                      }
   279                                  };
   280  
   281                                  let x: &[u8] = &serialized;
   282                                  match sender.reply(
   283                                      Message_MessageType::TP_PROCESS_RESPONSE,
   284                                      message.get_correlation_id(),
   285                                      x,
   286                                  ) {
   287                                      Ok(_) => (),
   288                                      Err(SendError::DisconnectedError) => {
   289                                          error!("DisconnectedError");
   290                                          break;
   291                                      }
   292                                      Err(SendError::TimeoutError) => error!("TimeoutError"),
   293                                      Err(SendError::UnknownError) => {
   294                                          restart = false;
   295                                          println!("UnknownError");
   296                                          break;
   297                                      }
   298                                  };
   299                              }
   300                              Message_MessageType::PING_REQUEST => {
   301                                  info!("sending PingResponse");
   302                                  let response = PingResponse::new();
   303                                  let serialized = match response.write_to_bytes() {
   304                                      Ok(serialized) => serialized,
   305                                      Err(err) => {
   306                                          error!("Serialization failed: {}", err.description());
   307                                          continue;
   308                                      }
   309                                  };
   310                                  let x: &[u8] = &serialized;
   311                                  match sender.reply(
   312                                      Message_MessageType::TP_PROCESS_RESPONSE,
   313                                      message.get_correlation_id(),
   314                                      x,
   315                                  ) {
   316                                      Ok(_) => (),
   317                                      Err(SendError::DisconnectedError) => {
   318                                          error!("DisconnectedError");
   319                                          break;
   320                                      }
   321                                      Err(SendError::TimeoutError) => error!("TimeoutError"),
   322                                      Err(SendError::UnknownError) => {
   323                                          restart = false;
   324                                          println!("UnknownError");
   325                                          break;
   326                                      }
   327                                  };
   328                              }
   329                              _ => {
   330                                  info!(
   331                                      "Transaction Processor recieved invalid message type: {:?}",
   332                                      message.get_message_type()
   333                                  );
   334                              }
   335                          }
   336                      }
   337                      Err(RecvTimeoutError::Timeout) => (),
   338                      Err(err) => {
   339                          error!("Error: {}", err.description());
   340                      }
   341                  }
   342              }
   343              sender.close();
   344          }
   345      }
   346  }