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 }