github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/rust/src/processor/handler.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 protobuf; 19 extern crate rand; 20 extern crate zmq; 21 22 use protobuf::Message as M; 23 use protobuf::RepeatedField; 24 25 use std; 26 use std::borrow::Borrow; 27 use std::collections::HashMap; 28 use std::error::Error as StdError; 29 30 use messages::events::Event; 31 use messages::events::Event_Attribute; 32 use messages::processor::TpProcessRequest; 33 use messages::state_context::*; 34 use messages::validator::Message_MessageType; 35 36 use messaging::stream::MessageSender; 37 use messaging::stream::ReceiveError; 38 use messaging::stream::SendError; 39 use messaging::zmq_stream::ZmqMessageSender; 40 41 use super::generate_correlation_id; 42 43 #[derive(Debug)] 44 pub enum ApplyError { 45 /// Returned for an Invalid Transaction. 46 InvalidTransaction(String), 47 /// Returned when an internal error occurs during transaction processing. 48 InternalError(String), 49 } 50 51 impl std::error::Error for ApplyError { 52 fn description(&self) -> &str { 53 match *self { 54 ApplyError::InvalidTransaction(ref msg) => msg, 55 ApplyError::InternalError(ref msg) => msg, 56 } 57 } 58 59 fn cause(&self) -> Option<&std::error::Error> { 60 match *self { 61 ApplyError::InvalidTransaction(_) => None, 62 ApplyError::InternalError(_) => None, 63 } 64 } 65 } 66 67 impl std::fmt::Display for ApplyError { 68 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 69 match *self { 70 ApplyError::InvalidTransaction(ref s) => write!(f, "InvalidTransaction: {}", s), 71 ApplyError::InternalError(ref s) => write!(f, "InternalError: {}", s), 72 } 73 } 74 } 75 76 #[derive(Debug)] 77 pub enum ContextError { 78 /// Returned for an authorization error 79 AuthorizationError(String), 80 /// Returned when a error occurs due to missing info in a response 81 ResponseAttributeError(String), 82 /// Returned when there is an issues setting receipt data or events. 83 TransactionReceiptError(String), 84 /// Returned when a ProtobufError is returned during serializing 85 SerializationError(Box<StdError>), 86 /// Returned when an error is returned when sending a message 87 SendError(Box<StdError>), 88 /// Returned when an error is returned when sending a message 89 ReceiveError(Box<StdError>), 90 } 91 92 impl std::error::Error for ContextError { 93 fn description(&self) -> &str { 94 match *self { 95 ContextError::AuthorizationError(ref msg) => msg, 96 ContextError::ResponseAttributeError(ref msg) => msg, 97 ContextError::TransactionReceiptError(ref msg) => msg, 98 ContextError::SerializationError(ref err) => err.description(), 99 ContextError::SendError(ref err) => err.description(), 100 ContextError::ReceiveError(ref err) => err.description(), 101 } 102 } 103 104 fn cause(&self) -> Option<&std::error::Error> { 105 match *self { 106 ContextError::AuthorizationError(_) => None, 107 ContextError::ResponseAttributeError(_) => None, 108 ContextError::TransactionReceiptError(_) => None, 109 ContextError::SerializationError(ref err) => Some(err.borrow()), 110 ContextError::SendError(ref err) => Some(err.borrow()), 111 ContextError::ReceiveError(ref err) => Some(err.borrow()), 112 } 113 } 114 } 115 116 impl std::fmt::Display for ContextError { 117 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 118 match *self { 119 ContextError::AuthorizationError(ref s) => write!(f, "AuthorizationError: {}", s), 120 ContextError::ResponseAttributeError(ref s) => { 121 write!(f, "ResponseAttributeError: {}", s) 122 } 123 ContextError::TransactionReceiptError(ref s) => { 124 write!(f, "TransactionReceiptError: {}", s) 125 } 126 ContextError::SerializationError(ref err) => { 127 write!(f, "SerializationError: {}", err.description()) 128 } 129 ContextError::SendError(ref err) => write!(f, "SendError: {}", err.description()), 130 ContextError::ReceiveError(ref err) => write!(f, "ReceiveError: {}", err.description()), 131 } 132 } 133 } 134 135 impl From<ContextError> for ApplyError { 136 fn from(context_error: ContextError) -> Self { 137 match context_error { 138 ContextError::TransactionReceiptError(..) => { 139 ApplyError::InternalError(format!("{}", context_error)) 140 } 141 _ => ApplyError::InvalidTransaction(format!("{}", context_error)), 142 } 143 } 144 } 145 146 impl From<protobuf::ProtobufError> for ContextError { 147 fn from(e: protobuf::ProtobufError) -> Self { 148 ContextError::SerializationError(Box::new(e)) 149 } 150 } 151 152 impl From<SendError> for ContextError { 153 fn from(e: SendError) -> Self { 154 ContextError::SendError(Box::new(e)) 155 } 156 } 157 158 impl From<ReceiveError> for ContextError { 159 fn from(e: ReceiveError) -> Self { 160 ContextError::ReceiveError(Box::new(e)) 161 } 162 } 163 164 #[derive(Clone)] 165 pub struct TransactionContext { 166 context_id: String, 167 sender: ZmqMessageSender, 168 } 169 170 impl TransactionContext { 171 /// Context provides an interface for getting, setting, and deleting 172 /// validator state. All validator interactions by a handler should be 173 /// through a Context instance. 174 /// 175 /// # Arguments 176 /// 177 /// * `sender` - for client grpc communication 178 /// * `context_id` - the context_id passed in from the validator 179 pub fn new(context_id: &str, sender: ZmqMessageSender) -> TransactionContext { 180 TransactionContext { 181 context_id: String::from(context_id), 182 sender: sender, 183 } 184 } 185 186 /// get_state queries the validator state for data at each of the 187 /// addresses in the given list. The addresses that have been set 188 /// are returned. 189 /// 190 /// # Arguments 191 /// 192 /// * `addresses` - the addresses to fetch 193 pub fn get_state(&mut self, addresses: Vec<String>) -> Result<Option<Vec<u8>>, ContextError> { 194 let mut request = TpStateGetRequest::new(); 195 request.set_context_id(self.context_id.clone()); 196 request.set_addresses(RepeatedField::from_vec(addresses.to_vec())); 197 let serialized = request.write_to_bytes()?; 198 let x: &[u8] = &serialized; 199 200 let mut future = self.sender.send( 201 Message_MessageType::TP_STATE_GET_REQUEST, 202 &generate_correlation_id(), 203 x, 204 )?; 205 206 let response: TpStateGetResponse = protobuf::parse_from_bytes(future.get()?.get_content())?; 207 match response.get_status() { 208 TpStateGetResponse_Status::OK => { 209 let entry = match response.get_entries().first() { 210 Some(x) => x, 211 None => { 212 return Err(ContextError::ResponseAttributeError(String::from( 213 "TpStateGetResponse is missing entries.", 214 ))) 215 } 216 }; 217 match entry.get_data().len() { 218 0 => Ok(None), 219 _ => Ok(Some(Vec::from(entry.get_data()))), 220 } 221 } 222 TpStateGetResponse_Status::AUTHORIZATION_ERROR => { 223 Err(ContextError::AuthorizationError(format!( 224 "Tried to get unauthorized address: {:?}", 225 addresses 226 ))) 227 } 228 TpStateGetResponse_Status::STATUS_UNSET => Err(ContextError::ResponseAttributeError( 229 String::from("Status was not set for TpStateGetResponse"), 230 )), 231 } 232 } 233 234 /// set_state requests that each address in the provided map be 235 /// set in validator state to its corresponding value. 236 /// 237 /// # Arguments 238 /// 239 /// * `address` - address of where to store the data 240 /// * `paylaod` - payload is the data to store at the address 241 pub fn set_state(&mut self, entries: HashMap<String, Vec<u8>>) -> Result<(), ContextError> { 242 let state_entries: Vec<TpStateEntry> = entries 243 .iter() 244 .map(|(address, payload)| { 245 let mut entry = TpStateEntry::new(); 246 entry.set_address(address.to_string()); 247 entry.set_data(payload.to_vec()); 248 entry 249 }) 250 .collect(); 251 252 let mut request = TpStateSetRequest::new(); 253 request.set_context_id(self.context_id.clone()); 254 request.set_entries(RepeatedField::from_vec(state_entries.to_vec())); 255 let serialized = request.write_to_bytes()?; 256 let x: &[u8] = &serialized; 257 258 let mut future = self.sender.send( 259 Message_MessageType::TP_STATE_SET_REQUEST, 260 &generate_correlation_id(), 261 x, 262 )?; 263 264 let response: TpStateSetResponse = protobuf::parse_from_bytes(future.get()?.get_content())?; 265 match response.get_status() { 266 TpStateSetResponse_Status::OK => Ok(()), 267 TpStateSetResponse_Status::AUTHORIZATION_ERROR => { 268 Err(ContextError::AuthorizationError(format!( 269 "Tried to set unauthorized address: {:?}", 270 state_entries 271 ))) 272 } 273 TpStateSetResponse_Status::STATUS_UNSET => Err(ContextError::ResponseAttributeError( 274 String::from("Status was not set for TpStateSetResponse"), 275 )), 276 } 277 } 278 279 /// delete_state requests that each of the provided addresses be unset 280 /// in validator state. A list of successfully deleted addresses 281 /// is returned. 282 /// 283 /// # Arguments 284 /// 285 /// * `addresses` - the addresses to fetch 286 pub fn delete_state( 287 &mut self, 288 addresses: Vec<String>, 289 ) -> Result<Option<Vec<String>>, ContextError> { 290 let mut request = TpStateDeleteRequest::new(); 291 request.set_context_id(self.context_id.clone()); 292 request.set_addresses(RepeatedField::from_vec(addresses.clone())); 293 294 let serialized = request.write_to_bytes()?; 295 let x: &[u8] = &serialized; 296 297 let mut future = self.sender.send( 298 Message_MessageType::TP_STATE_DELETE_REQUEST, 299 &generate_correlation_id(), 300 x, 301 )?; 302 303 let response: TpStateDeleteResponse = 304 protobuf::parse_from_bytes(future.get()?.get_content())?; 305 match response.get_status() { 306 TpStateDeleteResponse_Status::OK => Ok(Some(Vec::from(response.get_addresses()))), 307 TpStateDeleteResponse_Status::AUTHORIZATION_ERROR => { 308 Err(ContextError::AuthorizationError(format!( 309 "Tried to delete unauthorized address: {:?}", 310 addresses 311 ))) 312 } 313 TpStateDeleteResponse_Status::STATUS_UNSET => { 314 Err(ContextError::ResponseAttributeError(String::from( 315 "Status was not set for TpStateDeleteResponse", 316 ))) 317 } 318 } 319 } 320 321 /// add_receipt_data adds a blob to the execution result for this transaction 322 /// 323 /// # Arguments 324 /// 325 /// * `data` - the data to add 326 pub fn add_receipt_data(&mut self, data: &[u8]) -> Result<(), ContextError> { 327 let mut request = TpReceiptAddDataRequest::new(); 328 request.set_context_id(self.context_id.clone()); 329 request.set_data(Vec::from(data)); 330 331 let serialized = request.write_to_bytes()?; 332 let x: &[u8] = &serialized; 333 334 let mut future = self.sender.send( 335 Message_MessageType::TP_RECEIPT_ADD_DATA_REQUEST, 336 &generate_correlation_id(), 337 x, 338 )?; 339 340 let response: TpReceiptAddDataResponse = 341 protobuf::parse_from_bytes(future.get()?.get_content())?; 342 match response.get_status() { 343 TpReceiptAddDataResponse_Status::OK => Ok(()), 344 TpReceiptAddDataResponse_Status::ERROR => Err(ContextError::TransactionReceiptError( 345 format!("Failed to add receipt data {:?}", data), 346 )), 347 TpReceiptAddDataResponse_Status::STATUS_UNSET => { 348 Err(ContextError::ResponseAttributeError(String::from( 349 "Status was not set for TpReceiptAddDataResponse", 350 ))) 351 } 352 } 353 } 354 355 /// add_event adds a new event to the execution result for this transaction. 356 /// 357 /// # Arguments 358 /// 359 /// * `event_type` - This is used to subscribe to events. It should be globally unique and 360 /// describe what, in general, has occured. 361 /// * `attributes` - Additional information about the event that is transparent to the 362 /// validator. Attributes can be used by subscribers to filter the type of events 363 /// they receive. 364 /// * `data` - Additional information about the event that is opaque to the validator. 365 pub fn add_event( 366 &mut self, 367 event_type: String, 368 attributes: Vec<(String, String)>, 369 data: &[u8], 370 ) -> Result<(), ContextError> { 371 let mut event = Event::new(); 372 event.set_event_type(event_type); 373 374 let mut attributes_vec = Vec::new(); 375 for (key, value) in attributes { 376 let mut attribute = Event_Attribute::new(); 377 attribute.set_key(key); 378 attribute.set_value(value); 379 attributes_vec.push(attribute); 380 } 381 event.set_attributes(RepeatedField::from_vec(attributes_vec)); 382 event.set_data(Vec::from(data)); 383 384 let mut request = TpEventAddRequest::new(); 385 request.set_context_id(self.context_id.clone()); 386 request.set_event(event.clone()); 387 388 let serialized = request.write_to_bytes()?; 389 let x: &[u8] = &serialized; 390 391 let mut future = self.sender.send( 392 Message_MessageType::TP_RECEIPT_ADD_DATA_REQUEST, 393 &generate_correlation_id(), 394 x, 395 )?; 396 397 let response: TpEventAddResponse = protobuf::parse_from_bytes(future.get()?.get_content())?; 398 match response.get_status() { 399 TpEventAddResponse_Status::OK => Ok(()), 400 TpEventAddResponse_Status::ERROR => Err(ContextError::TransactionReceiptError( 401 format!("Failed to add event {:?}", event), 402 )), 403 TpEventAddResponse_Status::STATUS_UNSET => Err(ContextError::ResponseAttributeError( 404 String::from("Status was not set for TpEventAddRespons"), 405 )), 406 } 407 } 408 } 409 410 pub trait TransactionHandler { 411 /// TransactionHandler that defines the business logic for a new transaction family. 412 /// The family_name, family_versions, and namespaces functions are 413 /// used by the processor to route processing requests to the handler. 414 415 /// family_name should return the name of the transaction family that this 416 /// handler can process, e.g. "intkey" 417 fn family_name(&self) -> String; 418 419 /// family_versions should return a list of versions this transaction 420 /// family handler can process, e.g. ["1.0"] 421 fn family_versions(&self) -> Vec<String>; 422 423 /// namespaces should return a list containing all the handler's 424 /// namespaces, e.g. ["abcdef"] 425 fn namespaces(&self) -> Vec<String>; 426 427 /// Apply is the single method where all the business logic for a 428 /// transaction family is defined. The method will be called by the 429 /// transaction processor upon receiving a TpProcessRequest that the 430 /// handler understands and will pass in the TpProcessRequest and an 431 /// initialized instance of the Context type. 432 fn apply( 433 &self, 434 request: &TpProcessRequest, 435 context: &mut TransactionContext, 436 ) -> Result<(), ApplyError>; 437 }