github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/examples/intkey_rust/src/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 use cbor; 19 20 use crypto::digest::Digest; 21 use crypto::sha2::Sha512; 22 23 use std::collections::BTreeMap; 24 use std::collections::HashMap; 25 use std::fmt; 26 use std::io::Cursor; 27 28 use cbor::encoder::GenericEncoder; 29 use cbor::value::Key; 30 use cbor::value::Text; 31 use cbor::value::Value; 32 33 use sawtooth_sdk::messages::processor::TpProcessRequest; 34 use sawtooth_sdk::processor::handler::ApplyError; 35 use sawtooth_sdk::processor::handler::TransactionContext; 36 use sawtooth_sdk::processor::handler::TransactionHandler; 37 38 const MAX_VALUE: u32 = 4_294_967_295; 39 const MAX_NAME_LEN: usize = 20; 40 41 #[derive(Copy, Clone)] 42 enum Verb { 43 Set, 44 Increment, 45 Decrement, 46 } 47 48 impl fmt::Display for Verb { 49 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 50 write!( 51 f, 52 "{}", 53 match *self { 54 Verb::Set => "Verb::Set", 55 Verb::Increment => "Verb::Increment", 56 Verb::Decrement => "Verb::Decrement", 57 } 58 ) 59 } 60 } 61 62 fn get_intkey_prefix() -> String { 63 let mut sha = Sha512::new(); 64 sha.input_str("intkey"); 65 sha.result_str()[..6].to_string() 66 } 67 68 struct IntkeyPayload { 69 verb: Verb, 70 name: String, 71 value: u32, 72 } 73 74 impl IntkeyPayload { 75 pub fn new(payload_data: &[u8]) -> Result<Option<IntkeyPayload>, ApplyError> { 76 let input = Cursor::new(payload_data); 77 78 let mut decoder = cbor::GenericDecoder::new(cbor::Config::default(), input); 79 let decoder_value = decoder 80 .value() 81 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 82 83 let c = cbor::value::Cursor::new(&decoder_value); 84 85 let verb_raw: String = match c.field("Verb").text_plain() { 86 None => { 87 return Err(ApplyError::InvalidTransaction(String::from( 88 "Verb must be 'set', 'inc', or 'dec'", 89 ))) 90 } 91 Some(verb_raw) => verb_raw.clone(), 92 }; 93 94 let verb = match verb_raw.as_str() { 95 "set" => Verb::Set, 96 "inc" => Verb::Increment, 97 "dec" => Verb::Decrement, 98 _ => { 99 return Err(ApplyError::InvalidTransaction(String::from( 100 "Verb must be 'set', 'inc', or 'dec'", 101 ))) 102 } 103 }; 104 105 let value_raw = c.field("Value"); 106 let value_raw = match value_raw.value() { 107 Some(x) => x, 108 None => { 109 return Err(ApplyError::InvalidTransaction(String::from( 110 "Must have a value", 111 ))) 112 } 113 }; 114 115 let value: u32 = match *value_raw { 116 cbor::value::Value::U8(x) => u32::from(x), 117 cbor::value::Value::U16(x) => u32::from(x), 118 cbor::value::Value::U32(x) => x, 119 _ => { 120 return Err(ApplyError::InvalidTransaction(String::from( 121 "Value must be an integer", 122 ))) 123 } 124 }; 125 126 let name_raw: String = match c.field("Name").text_plain() { 127 None => { 128 return Err(ApplyError::InvalidTransaction(String::from( 129 "Name must be a string", 130 ))) 131 } 132 Some(name_raw) => name_raw.clone(), 133 }; 134 135 if name_raw.len() > MAX_NAME_LEN { 136 return Err(ApplyError::InvalidTransaction(String::from( 137 "Name must be equal to or less than 20 characters", 138 ))); 139 } 140 141 let intkey_payload = IntkeyPayload { 142 verb: verb, 143 name: name_raw, 144 value: value, 145 }; 146 Ok(Some(intkey_payload)) 147 } 148 149 pub fn get_verb(&self) -> Verb { 150 self.verb 151 } 152 153 pub fn get_name(&self) -> &String { 154 &self.name 155 } 156 157 pub fn get_value(&self) -> u32 { 158 self.value 159 } 160 } 161 162 pub struct IntkeyState<'a> { 163 context: &'a mut TransactionContext, 164 get_cache: HashMap<String, BTreeMap<Key, Value>>, 165 } 166 167 impl<'a> IntkeyState<'a> { 168 pub fn new(context: &'a mut TransactionContext) -> IntkeyState { 169 IntkeyState { 170 context: context, 171 get_cache: HashMap::new(), 172 } 173 } 174 175 fn calculate_address(name: &str) -> String { 176 let mut sha = Sha512::new(); 177 sha.input(name.as_bytes()); 178 get_intkey_prefix() + &sha.result_str()[64..].to_string() 179 } 180 181 pub fn get(&mut self, name: &str) -> Result<Option<u32>, ApplyError> { 182 let address = IntkeyState::calculate_address(name); 183 let d = self.context.get_state(vec![address.clone()])?; 184 match d { 185 Some(packed) => { 186 let input = Cursor::new(packed); 187 let mut decoder = cbor::GenericDecoder::new(cbor::Config::default(), input); 188 let map_value = decoder 189 .value() 190 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 191 let mut map = match map_value { 192 Value::Map(m) => m, 193 _ => { 194 return Err(ApplyError::InternalError(String::from( 195 "No map returned from state", 196 ))) 197 } 198 }; 199 200 let status = match map.get(&Key::Text(Text::Text(String::from(name)))) { 201 Some(v) => match *v { 202 Value::U32(x) => Ok(Some(x)), 203 Value::U16(x) => Ok(Some(u32::from(x))), 204 Value::U8(x) => Ok(Some(u32::from(x))), 205 _ => Err(ApplyError::InternalError(String::from( 206 "Value returned from state is the wrong type.", 207 ))), 208 }, 209 None => Ok(None), 210 }; 211 self.get_cache.insert(address.clone(), map.clone()); 212 status 213 } 214 None => Ok(None), 215 } 216 } 217 218 pub fn set(&mut self, name: &str, value: u32) -> Result<(), ApplyError> { 219 let mut map: BTreeMap<Key, Value> = match self.get_cache 220 .get_mut(&IntkeyState::calculate_address(name)) 221 { 222 Some(m) => m.clone(), 223 None => BTreeMap::new(), 224 }; 225 map.insert(Key::Text(Text::Text(String::from(name))), Value::U32(value)); 226 227 let mut e = GenericEncoder::new(Cursor::new(Vec::new())); 228 e.value(&Value::Map(map)) 229 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 230 231 let packed = e.into_inner().into_writer().into_inner(); 232 let mut sets = HashMap::new(); 233 sets.insert(IntkeyState::calculate_address(name), packed); 234 self.context 235 .set_state(sets) 236 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 237 238 Ok(()) 239 } 240 } 241 242 pub struct IntkeyTransactionHandler { 243 family_name: String, 244 family_versions: Vec<String>, 245 namespaces: Vec<String>, 246 } 247 248 impl IntkeyTransactionHandler { 249 pub fn new() -> IntkeyTransactionHandler { 250 IntkeyTransactionHandler { 251 family_name: "intkey".to_string(), 252 family_versions: vec!["1.0".to_string()], 253 namespaces: vec![get_intkey_prefix().to_string()], 254 } 255 } 256 } 257 258 impl TransactionHandler for IntkeyTransactionHandler { 259 fn family_name(&self) -> String { 260 self.family_name.clone() 261 } 262 263 fn family_versions(&self) -> Vec<String> { 264 self.family_versions.clone() 265 } 266 267 fn namespaces(&self) -> Vec<String> { 268 self.namespaces.clone() 269 } 270 271 fn apply( 272 &self, 273 request: &TpProcessRequest, 274 context: &mut TransactionContext, 275 ) -> Result<(), ApplyError> { 276 let payload = IntkeyPayload::new(request.get_payload()); 277 let payload = match payload { 278 Err(e) => return Err(e), 279 Ok(payload) => payload, 280 }; 281 let payload = match payload { 282 Some(x) => x, 283 None => { 284 return Err(ApplyError::InvalidTransaction(String::from( 285 "Request must contain a payload", 286 ))) 287 } 288 }; 289 290 let mut state = IntkeyState::new(context); 291 292 info!( 293 "payload: {} {} {} {} {}", 294 payload.get_verb(), 295 payload.get_name(), 296 payload.get_value(), 297 request.get_header().get_inputs()[0], 298 request.get_header().get_outputs()[0] 299 ); 300 301 match payload.get_verb() { 302 Verb::Set => { 303 match state.get(payload.get_name()) { 304 Ok(Some(_)) => { 305 return Err(ApplyError::InvalidTransaction(format!( 306 "{} already set", 307 payload.get_name() 308 ))) 309 } 310 Ok(None) => (), 311 Err(err) => return Err(err), 312 }; 313 state.set(&payload.get_name(), payload.get_value()) 314 } 315 Verb::Increment => { 316 let orig_value: u32 = match state.get(payload.get_name()) { 317 Ok(Some(v)) => v, 318 Ok(None) => { 319 return Err(ApplyError::InvalidTransaction(String::from( 320 "inc requires a set value", 321 ))) 322 } 323 Err(err) => return Err(err), 324 }; 325 let diff = MAX_VALUE - orig_value; 326 if diff < payload.get_value() { 327 return Err(ApplyError::InvalidTransaction(String::from( 328 "Value is too large to inc", 329 ))); 330 }; 331 332 state.set(&payload.get_name(), orig_value + payload.get_value()) 333 } 334 Verb::Decrement => { 335 let orig_value: u32 = match state.get(payload.get_name()) { 336 Ok(Some(v)) => v, 337 Ok(None) => { 338 return Err(ApplyError::InvalidTransaction(String::from( 339 "dec requires a set value", 340 ))) 341 } 342 Err(err) => return Err(err), 343 }; 344 if payload.get_value() > orig_value { 345 return Err(ApplyError::InvalidTransaction(String::from( 346 "Value is too large to dec", 347 ))); 348 }; 349 state.set(&payload.get_name(), orig_value - payload.get_value()) 350 } 351 } 352 } 353 }