github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-supply-chain-master/processor/src/handler.rs (about) 1 // Copyright 2018 Cargill Incorporated 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use protobuf; 16 use protobuf::Message; 17 use protobuf::RepeatedField; 18 19 use std::collections::HashMap; 20 21 use sawtooth_sdk::processor::handler::ApplyError; 22 use sawtooth_sdk::processor::handler::TransactionContext; 23 use sawtooth_sdk::processor::handler::TransactionHandler; 24 use sawtooth_sdk::messages::processor::TpProcessRequest; 25 26 use messages::*; 27 use addressing::*; 28 29 const PROPERTY_PAGE_MAX_LENGTH: usize = 256; 30 31 #[derive(Debug, Clone)] 32 enum Action { 33 CreateAgent(payload::CreateAgentAction), 34 CreateRecord(payload::CreateRecordAction), 35 FinalizeRecord(payload::FinalizeRecordAction), 36 CreateRecordType(payload::CreateRecordTypeAction), 37 UpdateProperties(payload::UpdatePropertiesAction), 38 CreateProposal(payload::CreateProposalAction), 39 AnswerProposal(payload::AnswerProposalAction), 40 RevokeReporter(payload::RevokeReporterAction), 41 } 42 43 struct SupplyChainPayload { 44 action: Action, 45 timestamp: u64, 46 } 47 48 impl SupplyChainPayload { 49 pub fn new(payload: &[u8]) -> Result<Option<SupplyChainPayload>, ApplyError> { 50 let payload: payload::SCPayload = match protobuf::parse_from_bytes(payload) { 51 Ok(payload) => payload, 52 Err(_) => { 53 return Err(ApplyError::InvalidTransaction(String::from( 54 "Cannot deserialize payload", 55 ))) 56 } 57 }; 58 59 let supply_chain_action = payload.get_action(); 60 let action = match supply_chain_action { 61 payload::SCPayload_Action::CREATE_AGENT => { 62 let create_agent = payload.get_create_agent(); 63 if create_agent.get_name() == "" { 64 return Err(ApplyError::InvalidTransaction(String::from( 65 "Agent name cannot be an empty string", 66 ))); 67 } 68 Action::CreateAgent(create_agent.clone()) 69 } 70 payload::SCPayload_Action::CREATE_RECORD => { 71 let create_record = payload.get_create_record(); 72 if create_record.get_record_id() == "" { 73 return Err(ApplyError::InvalidTransaction(String::from( 74 "Record id cannot be empty string", 75 ))); 76 } 77 Action::CreateRecord(create_record.clone()) 78 } 79 payload::SCPayload_Action::FINALIZE_RECORD => { 80 Action::FinalizeRecord(payload.get_finalize_record().clone()) 81 } 82 payload::SCPayload_Action::CREATE_RECORD_TYPE => { 83 let create_record_type = payload.get_create_record_type(); 84 if create_record_type.get_name() == "" { 85 return Err(ApplyError::InvalidTransaction(String::from( 86 "Record Type name cannot be an empty string", 87 ))); 88 }; 89 let properties = create_record_type.get_properties(); 90 if properties.len() == 0 { 91 return Err(ApplyError::InvalidTransaction(String::from( 92 "Record type must have at least one property", 93 ))); 94 } 95 for prop in properties { 96 if prop.name == "" { 97 return Err(ApplyError::InvalidTransaction(String::from( 98 "Property name cannot be an empty string", 99 ))); 100 } 101 } 102 103 Action::CreateRecordType(create_record_type.clone()) 104 } 105 payload::SCPayload_Action::UPDATE_PROPERTIES => { 106 Action::UpdateProperties(payload.get_update_properties().clone()) 107 } 108 payload::SCPayload_Action::CREATE_PROPOSAL => { 109 Action::CreateProposal(payload.get_create_proposal().clone()) 110 } 111 payload::SCPayload_Action::ANSWER_PROPOSAL => { 112 Action::AnswerProposal(payload.get_answer_proposal().clone()) 113 } 114 payload::SCPayload_Action::REVOKE_REPORTER => { 115 Action::RevokeReporter(payload.get_revoke_reporter().clone()) 116 } 117 }; 118 let timestamp = match payload.get_timestamp() { 119 0 => { 120 return Err(ApplyError::InvalidTransaction(String::from( 121 "Timestamp is not set", 122 ))) 123 } 124 x => x, 125 }; 126 127 Ok(Some(SupplyChainPayload { 128 action: action, 129 timestamp: timestamp, 130 })) 131 } 132 133 pub fn get_action(&self) -> Action { 134 self.action.clone() 135 } 136 137 pub fn get_timestamp(&self) -> u64 { 138 self.timestamp 139 } 140 } 141 142 pub struct SupplyChainState<'a> { 143 context: &'a mut TransactionContext, 144 } 145 146 impl<'a> SupplyChainState<'a> { 147 pub fn new(context: &'a mut TransactionContext) -> SupplyChainState { 148 SupplyChainState { context: context } 149 } 150 151 pub fn get_record(&mut self, record_id: &str) -> Result<Option<record::Record>, ApplyError> { 152 let address = make_record_address(record_id); 153 let d = self.context.get_state(vec![address])?; 154 match d { 155 Some(packed) => { 156 let records: record::RecordContainer = 157 match protobuf::parse_from_bytes(packed.as_slice()) { 158 Ok(records) => records, 159 Err(_) => { 160 return Err(ApplyError::InternalError(String::from( 161 "Cannot deserialize record container", 162 ))) 163 } 164 }; 165 166 for record in records.get_entries() { 167 if record.record_id == record_id { 168 return Ok(Some(record.clone())); 169 } 170 } 171 Ok(None) 172 } 173 None => Ok(None), 174 } 175 } 176 177 pub fn set_record( 178 &mut self, 179 record_id: &str, 180 record: record::Record, 181 ) -> Result<(), ApplyError> { 182 let address = make_record_address(record_id); 183 let d = self.context.get_state(vec![address.clone()])?; 184 let mut record_container = match d { 185 Some(packed) => match protobuf::parse_from_bytes(packed.as_slice()) { 186 Ok(records) => records, 187 Err(_) => { 188 return Err(ApplyError::InternalError(String::from( 189 "Cannot deserialize record container", 190 ))) 191 } 192 }, 193 None => record::RecordContainer::new(), 194 }; 195 // remove old record if it exists and sort the records by record id 196 let records = record_container.get_entries().to_vec(); 197 let mut index = None; 198 let mut count = 0; 199 for record in records.clone() { 200 if record.record_id == record_id { 201 index = Some(count); 202 break; 203 } 204 count = count + 1; 205 } 206 207 match index { 208 Some(x) => { 209 record_container.entries.remove(x); 210 } 211 None => (), 212 }; 213 record_container.entries.push(record); 214 record_container 215 .entries 216 .sort_by_key(|r| r.clone().record_id); 217 let serialized = match record_container.write_to_bytes() { 218 Ok(serialized) => serialized, 219 Err(_) => { 220 return Err(ApplyError::InternalError(String::from( 221 "Cannot serialize record container", 222 ))) 223 } 224 }; 225 let mut sets = HashMap::new(); 226 sets.insert(address, serialized); 227 self.context 228 .set_state(sets) 229 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 230 Ok(()) 231 } 232 233 pub fn get_record_type( 234 &mut self, 235 type_name: &str, 236 ) -> Result<Option<record::RecordType>, ApplyError> { 237 let address = make_record_type_address(type_name); 238 let d = self.context.get_state(vec![address])?; 239 match d { 240 Some(packed) => { 241 let record_types: record::RecordTypeContainer = 242 match protobuf::parse_from_bytes(packed.as_slice()) { 243 Ok(record_types) => record_types, 244 Err(_) => { 245 return Err(ApplyError::InternalError(String::from( 246 "Cannot deserialize record type container", 247 ))) 248 } 249 }; 250 251 for record_type in record_types.get_entries() { 252 if record_type.name == type_name { 253 return Ok(Some(record_type.clone())); 254 } 255 } 256 Ok(None) 257 } 258 None => Ok(None), 259 } 260 } 261 262 pub fn set_record_type( 263 &mut self, 264 type_name: &str, 265 record_type: record::RecordType, 266 ) -> Result<(), ApplyError> { 267 let address = make_record_type_address(type_name); 268 let d = self.context.get_state(vec![address.clone()])?; 269 let mut record_types = match d { 270 Some(packed) => match protobuf::parse_from_bytes(packed.as_slice()) { 271 Ok(record_types) => record_types, 272 Err(_) => { 273 return Err(ApplyError::InternalError(String::from( 274 "Cannot deserialize record container", 275 ))) 276 } 277 }, 278 None => record::RecordTypeContainer::new(), 279 }; 280 281 record_types.entries.push(record_type); 282 record_types.entries.sort_by_key(|rt| rt.clone().name); 283 let serialized = match record_types.write_to_bytes() { 284 Ok(serialized) => serialized, 285 Err(_) => { 286 return Err(ApplyError::InternalError(String::from( 287 "Cannot serialize record type container", 288 ))) 289 } 290 }; 291 let mut sets = HashMap::new(); 292 sets.insert(address, serialized); 293 self.context 294 .set_state(sets) 295 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 296 Ok(()) 297 } 298 299 pub fn get_agent(&mut self, agent_id: &str) -> Result<Option<agent::Agent>, ApplyError> { 300 let address = make_agent_address(agent_id); 301 let d = self.context.get_state(vec![address])?; 302 match d { 303 Some(packed) => { 304 let agents: agent::AgentContainer = 305 match protobuf::parse_from_bytes(packed.as_slice()) { 306 Ok(agents) => agents, 307 Err(_) => { 308 return Err(ApplyError::InternalError(String::from( 309 "Cannot deserialize agent container", 310 ))) 311 } 312 }; 313 314 for agent in agents.get_entries() { 315 if agent.public_key == agent_id { 316 return Ok(Some(agent.clone())); 317 } 318 } 319 Ok(None) 320 } 321 None => Ok(None), 322 } 323 } 324 325 pub fn set_agent(&mut self, agent_id: &str, agent: agent::Agent) -> Result<(), ApplyError> { 326 let address = make_agent_address(agent_id); 327 let d = self.context.get_state(vec![address.clone()])?; 328 let mut agents = match d { 329 Some(packed) => match protobuf::parse_from_bytes(packed.as_slice()) { 330 Ok(agents) => agents, 331 Err(_) => { 332 return Err(ApplyError::InternalError(String::from( 333 "Cannot deserialize agent container", 334 ))) 335 } 336 }, 337 None => agent::AgentContainer::new(), 338 }; 339 340 agents.entries.push(agent); 341 agents.entries.sort_by_key(|a| a.clone().public_key); 342 let serialized = match agents.write_to_bytes() { 343 Ok(serialized) => serialized, 344 Err(_) => { 345 return Err(ApplyError::InternalError(String::from( 346 "Cannot serialize agent container", 347 ))) 348 } 349 }; 350 let mut sets = HashMap::new(); 351 sets.insert(address, serialized); 352 self.context 353 .set_state(sets) 354 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 355 Ok(()) 356 } 357 358 pub fn get_property( 359 &mut self, 360 record_id: &str, 361 property_name: &str, 362 ) -> Result<Option<property::Property>, ApplyError> { 363 let address = make_property_address(record_id, property_name, 0); 364 let d = self.context.get_state(vec![address])?; 365 match d { 366 Some(packed) => { 367 let properties: property::PropertyContainer = 368 match protobuf::parse_from_bytes(packed.as_slice()) { 369 Ok(properties) => properties, 370 Err(_) => { 371 return Err(ApplyError::InternalError(String::from( 372 "Cannot deserialize property container", 373 ))) 374 } 375 }; 376 377 for property in properties.get_entries() { 378 if property.name == property_name { 379 return Ok(Some(property.clone())); 380 } 381 } 382 Ok(None) 383 } 384 None => Ok(None), 385 } 386 } 387 388 pub fn set_property( 389 &mut self, 390 record_id: &str, 391 property_name: &str, 392 property: property::Property, 393 ) -> Result<(), ApplyError> { 394 let address = make_property_address(record_id, property_name, 0); 395 let d = self.context.get_state(vec![address.clone()])?; 396 let mut property_container = match d { 397 Some(packed) => match protobuf::parse_from_bytes(packed.as_slice()) { 398 Ok(properties) => properties, 399 Err(_) => { 400 return Err(ApplyError::InternalError(String::from( 401 "Cannot deserialize property container", 402 ))) 403 } 404 }, 405 None => property::PropertyContainer::new(), 406 }; 407 // remove old property if it exists and sort the properties by name 408 let properties = property_container.get_entries().to_vec(); 409 let mut index = None; 410 let mut count = 0; 411 for prop in properties.clone() { 412 if prop.name == property_name { 413 index = Some(count); 414 break; 415 } 416 count = count + 1; 417 } 418 419 match index { 420 Some(x) => { 421 property_container.entries.remove(x); 422 } 423 None => (), 424 }; 425 property_container.entries.push(property); 426 property_container.entries.sort_by_key(|p| p.clone().name); 427 let serialized = match property_container.write_to_bytes() { 428 Ok(serialized) => serialized, 429 Err(_) => { 430 return Err(ApplyError::InternalError(String::from( 431 "Cannot serialize property container", 432 ))) 433 } 434 }; 435 let mut sets = HashMap::new(); 436 sets.insert(address, serialized); 437 self.context 438 .set_state(sets) 439 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 440 Ok(()) 441 } 442 443 pub fn get_property_page( 444 &mut self, 445 record_id: &str, 446 property_name: &str, 447 page: u32, 448 ) -> Result<Option<property::PropertyPage>, ApplyError> { 449 let address = make_property_address(record_id, property_name, page); 450 let d = self.context.get_state(vec![address])?; 451 match d { 452 Some(packed) => { 453 let property_pages: property::PropertyPageContainer = 454 match protobuf::parse_from_bytes(packed.as_slice()) { 455 Ok(property_pages) => property_pages, 456 Err(_) => { 457 return Err(ApplyError::InternalError(String::from( 458 "Cannot deserialize property page container", 459 ))) 460 } 461 }; 462 463 for property_page in property_pages.get_entries() { 464 if property_page.name == property_name { 465 return Ok(Some(property_page.clone())); 466 } 467 } 468 Ok(None) 469 } 470 None => Ok(None), 471 } 472 } 473 474 pub fn set_property_page( 475 &mut self, 476 record_id: &str, 477 property_name: &str, 478 page_num: u32, 479 property_page: property::PropertyPage, 480 ) -> Result<(), ApplyError> { 481 let address = make_property_address(record_id, property_name, page_num); 482 let d = self.context.get_state(vec![address.clone()])?; 483 let mut property_pages = match d { 484 Some(packed) => match protobuf::parse_from_bytes(packed.as_slice()) { 485 Ok(property_pages) => property_pages, 486 Err(_) => { 487 return Err(ApplyError::InternalError(String::from( 488 "Cannot deserialize property page container", 489 ))) 490 } 491 }, 492 None => property::PropertyPageContainer::new(), 493 }; 494 // remove old property page if it exists and sort the property pages by name 495 let pages = property_pages.get_entries().to_vec(); 496 let mut index = None; 497 let mut count = 0; 498 for page in pages.clone() { 499 if page.name == property_name { 500 index = Some(count); 501 break; 502 } 503 count = count + 1; 504 } 505 506 match index { 507 Some(x) => { 508 property_pages.entries.remove(x); 509 } 510 None => (), 511 }; 512 property_pages.entries.push(property_page); 513 property_pages.entries.sort_by_key(|pp| pp.clone().name); 514 let serialized = match property_pages.write_to_bytes() { 515 Ok(serialized) => serialized, 516 Err(_) => { 517 return Err(ApplyError::InternalError(String::from( 518 "Cannot serialize property page container", 519 ))) 520 } 521 }; 522 let mut sets = HashMap::new(); 523 sets.insert(address, serialized); 524 self.context 525 .set_state(sets) 526 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 527 Ok(()) 528 } 529 530 pub fn get_proposal_container( 531 &mut self, 532 record_id: &str, 533 agent_id: &str, 534 ) -> Result<Option<proposal::ProposalContainer>, ApplyError> { 535 let address = make_proposal_address(record_id, agent_id); 536 let d = self.context.get_state(vec![address])?; 537 match d { 538 Some(packed) => { 539 let proposals: proposal::ProposalContainer = 540 match protobuf::parse_from_bytes(packed.as_slice()) { 541 Ok(property_pages) => property_pages, 542 Err(_) => { 543 return Err(ApplyError::InternalError(String::from( 544 "Cannot deserialize proposal container", 545 ))) 546 } 547 }; 548 549 Ok(Some(proposals)) 550 } 551 None => Ok(None), 552 } 553 } 554 555 pub fn set_proposal_container( 556 &mut self, 557 record_id: &str, 558 agent_id: &str, 559 proposals: proposal::ProposalContainer, 560 ) -> Result<(), ApplyError> { 561 let address = make_proposal_address(record_id, agent_id); 562 let serialized = match proposals.write_to_bytes() { 563 Ok(serialized) => serialized, 564 Err(_) => { 565 return Err(ApplyError::InternalError(String::from( 566 "Cannot serialize proposal container", 567 ))) 568 } 569 }; 570 let mut sets = HashMap::new(); 571 sets.insert(address, serialized); 572 self.context 573 .set_state(sets) 574 .map_err(|err| ApplyError::InternalError(format!("{}", err)))?; 575 Ok(()) 576 } 577 } 578 579 pub struct SupplyChainTransactionHandler { 580 family_name: String, 581 family_versions: Vec<String>, 582 namespaces: Vec<String>, 583 } 584 585 impl SupplyChainTransactionHandler { 586 pub fn new() -> SupplyChainTransactionHandler { 587 SupplyChainTransactionHandler { 588 family_name: "supply_chain".to_string(), 589 family_versions: vec!["1.1".to_string()], 590 namespaces: vec![get_supply_chain_prefix().to_string()], 591 } 592 } 593 594 fn _create_agent( 595 &self, 596 payload: payload::CreateAgentAction, 597 mut state: SupplyChainState, 598 signer: &str, 599 timestamp: u64, 600 ) -> Result<(), ApplyError> { 601 let name = payload.get_name(); 602 match state.get_agent(signer) { 603 Ok(Some(_)) => { 604 return Err(ApplyError::InvalidTransaction(format!( 605 "Agent already exists: {}", 606 name 607 ))) 608 } 609 Ok(None) => (), 610 Err(err) => return Err(err), 611 } 612 613 let mut new_agent = agent::Agent::new(); 614 new_agent.set_public_key(signer.to_string()); 615 new_agent.set_name(name.to_string()); 616 new_agent.set_timestamp(timestamp); 617 618 state.set_agent(signer, new_agent)?; 619 Ok(()) 620 } 621 622 fn _create_record( 623 &self, 624 payload: payload::CreateRecordAction, 625 mut state: SupplyChainState, 626 signer: &str, 627 timestamp: u64, 628 ) -> Result<(), ApplyError> { 629 match state.get_agent(signer) { 630 Ok(Some(_)) => (), 631 Ok(None) => { 632 return Err(ApplyError::InvalidTransaction(format!( 633 "Agent is not register: {}", 634 signer 635 ))) 636 } 637 Err(err) => return Err(err), 638 } 639 let record_id = payload.get_record_id(); 640 match state.get_record(record_id) { 641 Ok(Some(_)) => { 642 return Err(ApplyError::InvalidTransaction(format!( 643 "Record already exists: {}", 644 record_id 645 ))) 646 } 647 Ok(None) => (), 648 Err(err) => return Err(err), 649 } 650 651 let type_name = payload.get_record_type(); 652 let record_type = match state.get_record_type(type_name) { 653 Ok(Some(record_type)) => record_type, 654 Ok(None) => { 655 return Err(ApplyError::InvalidTransaction(format!( 656 "Record Type does not exist {}", 657 type_name 658 ))) 659 } 660 Err(err) => return Err(err), 661 }; 662 663 let mut type_schemata: HashMap<&str, property::PropertySchema> = HashMap::new(); 664 let mut required_properties: HashMap<&str, property::PropertySchema> = HashMap::new(); 665 let mut provided_properties: HashMap<&str, property::PropertyValue> = HashMap::new(); 666 for property in record_type.get_properties() { 667 type_schemata.insert(property.get_name(), property.clone()); 668 if property.get_required() { 669 required_properties.insert(property.get_name(), property.clone()); 670 } 671 } 672 673 for property in payload.get_properties() { 674 provided_properties.insert(property.get_name(), property.clone()); 675 } 676 677 for name in required_properties.keys() { 678 if !provided_properties.contains_key(name) { 679 return Err(ApplyError::InvalidTransaction(format!( 680 "Required property {} not provided", 681 name 682 ))); 683 } 684 } 685 686 for (provided_name, provided_properties) in provided_properties.clone() { 687 let required_type = match type_schemata.get(provided_name) { 688 Some(required_type) => required_type.data_type, 689 None => { 690 return Err(ApplyError::InvalidTransaction(format!( 691 "Provided property {} is not in schemata", 692 provided_name 693 ))) 694 } 695 }; 696 let provided_type = provided_properties.data_type; 697 if provided_type != required_type { 698 return Err(ApplyError::InvalidTransaction(format!( 699 "Value provided for {} is the wrong type", 700 provided_name 701 ))); 702 }; 703 704 let is_delayed = match type_schemata.get(provided_name) { 705 Some(property_schema) => property_schema.delayed, 706 None => false, 707 }; 708 if is_delayed { 709 return Err(ApplyError::InvalidTransaction(format!( 710 "Property is 'delayed', and cannot be set at record creation: {}", 711 provided_name 712 ))); 713 }; 714 } 715 let mut new_record = record::Record::new(); 716 new_record.set_record_id(record_id.to_string()); 717 new_record.set_record_type(type_name.to_string()); 718 new_record.set_field_final(false); 719 720 let mut owner = record::Record_AssociatedAgent::new(); 721 owner.set_agent_id(signer.to_string()); 722 owner.set_timestamp(timestamp); 723 new_record.owners.push(owner.clone()); 724 new_record.custodians.push(owner.clone()); 725 726 state.set_record(record_id, new_record)?; 727 728 let mut reporter = property::Property_Reporter::new(); 729 reporter.set_public_key(signer.to_string()); 730 reporter.set_authorized(true); 731 reporter.set_index(0); 732 733 for (property_name, property) in type_schemata { 734 let mut new_property = property::Property::new(); 735 new_property.set_name(property_name.to_string()); 736 new_property.set_record_id(record_id.to_string()); 737 new_property.set_data_type(property.get_data_type()); 738 new_property.reporters.push(reporter.clone()); 739 new_property.set_current_page(1); 740 new_property.set_wrapped(false); 741 new_property.set_fixed(property.get_fixed()); 742 new_property.set_number_exponent(property.get_number_exponent()); 743 new_property.set_enum_options( 744 RepeatedField::from_vec(property.get_enum_options().to_vec())); 745 new_property.set_struct_properties( 746 RepeatedField::from_vec(property.get_struct_properties().to_vec())); 747 new_property.set_unit(property.get_unit().to_string()); 748 749 state.set_property(record_id, property_name, new_property.clone())?; 750 751 let mut new_property_page = property::PropertyPage::new(); 752 new_property_page.set_name(property_name.to_string()); 753 new_property_page.set_record_id(record_id.to_string()); 754 755 if provided_properties.contains_key(property_name) { 756 let provided_property = &provided_properties[property_name]; 757 let reported_value = match self._make_new_reported_value( 758 0, 759 timestamp, 760 provided_property, 761 &new_property, 762 ) { 763 Ok(reported_value) => reported_value, 764 Err(err) => return Err(err), 765 }; 766 767 new_property_page.reported_values.push(reported_value); 768 } 769 state.set_property_page(record_id, property_name, 1, new_property_page)?; 770 } 771 772 Ok(()) 773 } 774 775 fn _finalize_record( 776 &self, 777 payload: payload::FinalizeRecordAction, 778 mut state: SupplyChainState, 779 signer: &str, 780 ) -> Result<(), ApplyError> { 781 let record_id = payload.get_record_id(); 782 let final_record = match state.get_record(record_id) { 783 Ok(Some(final_record)) => final_record, 784 Ok(None) => { 785 return Err(ApplyError::InvalidTransaction(format!( 786 "Record does not exist: {}", 787 record_id 788 ))) 789 } 790 Err(err) => return Err(err), 791 }; 792 let owner = match final_record.owners.last() { 793 Some(x) => x, 794 None => { 795 return Err(ApplyError::InvalidTransaction(String::from( 796 "Owner was not found", 797 ))) 798 } 799 }; 800 let custodian = match final_record.custodians.last() { 801 Some(x) => x, 802 None => { 803 return Err(ApplyError::InvalidTransaction(String::from( 804 "Custodian was not found", 805 ))) 806 } 807 }; 808 809 if owner.agent_id != signer || custodian.agent_id != signer { 810 return Err(ApplyError::InvalidTransaction(format!( 811 "Must be owner and custodian to finalize record" 812 ))); 813 } 814 if final_record.get_field_final() { 815 return Err(ApplyError::InvalidTransaction(format!( 816 "Record is already final: {}", 817 record_id 818 ))); 819 } 820 821 let mut record_clone = final_record.clone(); 822 record_clone.set_field_final(true); 823 state.set_record(record_id, record_clone)?; 824 825 Ok(()) 826 } 827 828 fn _create_record_type( 829 &self, 830 payload: payload::CreateRecordTypeAction, 831 mut state: SupplyChainState, 832 signer: &str, 833 ) -> Result<(), ApplyError> { 834 match state.get_agent(signer) { 835 Ok(Some(_)) => (), 836 Ok(None) => { 837 return Err(ApplyError::InvalidTransaction(format!( 838 "Agent is not register: {}", 839 signer 840 ))) 841 } 842 Err(err) => return Err(err), 843 } 844 let name = payload.get_name(); 845 let mut provided_properties: HashMap<&str, property::PropertySchema> = HashMap::new(); 846 for property in payload.get_properties() { 847 provided_properties.insert(property.get_name(), property.clone()); 848 } 849 match state.get_record_type(name) { 850 Ok(Some(_)) => { 851 return Err(ApplyError::InvalidTransaction(format!( 852 "Record type already exists: {}", 853 signer 854 ))) 855 } 856 Ok(None) => (), 857 Err(err) => return Err(err), 858 } 859 let mut record_type = record::RecordType::new(); 860 record_type.set_name(name.to_string()); 861 record_type.set_properties(RepeatedField::from_vec(payload.get_properties().to_vec())); 862 863 state.set_record_type(name, record_type)?; 864 865 Ok(()) 866 } 867 868 fn _update_properties( 869 &self, 870 payload: payload::UpdatePropertiesAction, 871 mut state: SupplyChainState, 872 signer: &str, 873 timestamp: u64, 874 ) -> Result<(), ApplyError> { 875 let record_id = payload.get_record_id(); 876 let update_record = match state.get_record(record_id) { 877 Ok(Some(update_record)) => update_record, 878 Ok(None) => { 879 return Err(ApplyError::InvalidTransaction(format!( 880 "Record does not exist: {}", 881 record_id 882 ))) 883 } 884 Err(err) => return Err(err), 885 }; 886 887 if update_record.get_field_final() { 888 return Err(ApplyError::InvalidTransaction(format!( 889 "Record is final: {}", 890 record_id 891 ))); 892 } 893 894 let updates = payload.get_properties(); 895 896 for update in updates { 897 let name = update.get_name(); 898 let data_type = update.get_data_type(); 899 900 let mut prop = match state.get_property(record_id, name) { 901 Ok(Some(prop)) => prop, 902 Ok(None) => { 903 return Err(ApplyError::InvalidTransaction(format!( 904 "Record does not have provided poperty: {}", 905 name 906 ))) 907 } 908 Err(err) => return Err(err), 909 }; 910 911 let mut allowed = false; 912 let mut reporter_index = 0; 913 for reporter in prop.get_reporters() { 914 if reporter.get_public_key() == signer && reporter.get_authorized() { 915 allowed = true; 916 reporter_index = reporter.get_index(); 917 break; 918 } 919 } 920 if !allowed { 921 return Err(ApplyError::InvalidTransaction(format!( 922 "Reporter is not authorized: {}", 923 signer 924 ))); 925 } 926 927 if prop.fixed { 928 return Err(ApplyError::InvalidTransaction(format!( 929 "Property is fixed and cannot be updated: {}", 930 prop.name 931 ))); 932 } 933 934 if data_type != prop.data_type { 935 return Err(ApplyError::InvalidTransaction(format!( 936 "Update has wrong type: {:?} != {:?}", 937 data_type, prop.data_type 938 ))); 939 } 940 941 let page_number = prop.get_current_page(); 942 let mut page = match state.get_property_page(record_id, name, page_number) { 943 Ok(Some(page)) => page, 944 Ok(None) => { 945 return Err(ApplyError::InvalidTransaction(String::from( 946 "Property page does not exist", 947 ))) 948 } 949 Err(err) => return Err(err), 950 }; 951 952 let reported_value = match self._make_new_reported_value( 953 reporter_index, 954 timestamp, 955 update, 956 &prop, 957 ) { 958 Ok(reported_value) => reported_value, 959 Err(err) => return Err(err), 960 }; 961 page.reported_values.push(reported_value); 962 page.reported_values 963 .sort_by_key(|rv| (rv.clone().timestamp, rv.clone().reporter_index)); 964 state.set_property_page(record_id, name, page_number, page.clone())?; 965 if page.reported_values.len() >= PROPERTY_PAGE_MAX_LENGTH { 966 let mut new_page_number = page_number + 1; 967 if page_number + 1 <= PROPERTY_PAGE_MAX_LENGTH as u32 { 968 new_page_number = 1; 969 } 970 971 let new_page = match state.get_property_page(record_id, name, new_page_number) { 972 Ok(Some(mut new_page)) => { 973 new_page.set_reported_values(RepeatedField::from_vec(Vec::new())); 974 new_page 975 } 976 Ok(None) => { 977 let mut new_page = property::PropertyPage::new(); 978 new_page.set_name(name.to_string()); 979 new_page.set_record_id(record_id.to_string()); 980 new_page 981 } 982 Err(err) => return Err(err), 983 }; 984 state.set_property_page(record_id, name, new_page_number, new_page)?; 985 986 prop.set_current_page(new_page_number); 987 if new_page_number == 1 && !prop.get_wrapped() { 988 prop.set_wrapped(true); 989 } 990 state.set_property(record_id, name, prop)?; 991 } 992 } 993 994 Ok(()) 995 } 996 997 fn _create_proposal( 998 &self, 999 payload: payload::CreateProposalAction, 1000 mut state: SupplyChainState, 1001 signer: &str, 1002 timestamp: u64, 1003 ) -> Result<(), ApplyError> { 1004 let record_id = payload.record_id; 1005 let receiving_agent = payload.receiving_agent; 1006 let role = payload.role; 1007 let properties = payload.properties; 1008 1009 match state.get_agent(signer) { 1010 Ok(Some(agent)) => agent, 1011 Ok(None) => { 1012 return Err(ApplyError::InvalidTransaction(format!( 1013 "Issuing agent does not exist: {}", 1014 signer 1015 ))) 1016 } 1017 Err(err) => return Err(err), 1018 }; 1019 1020 match state.get_agent(&receiving_agent) { 1021 Ok(Some(agent)) => agent, 1022 Ok(None) => { 1023 return Err(ApplyError::InvalidTransaction(format!( 1024 "Receiving agent does not exist: {}", 1025 receiving_agent 1026 ))) 1027 } 1028 Err(err) => return Err(err), 1029 }; 1030 1031 let mut proposals = match state.get_proposal_container(&record_id, &receiving_agent) { 1032 Ok(Some(proposals)) => proposals, 1033 Ok(None) => proposal::ProposalContainer::new(), 1034 Err(err) => return Err(err), 1035 }; 1036 1037 let mut open_proposals = Vec::<proposal::Proposal>::new(); 1038 for prop in proposals.get_entries() { 1039 if prop.status == proposal::Proposal_Status::OPEN { 1040 open_proposals.push(prop.clone()); 1041 } 1042 } 1043 1044 for prop in open_proposals { 1045 if prop.get_receiving_agent() == receiving_agent && prop.get_role() == role 1046 && prop.get_record_id() == record_id 1047 { 1048 return Err(ApplyError::InvalidTransaction(String::from( 1049 "Proposal already exists", 1050 ))); 1051 } 1052 } 1053 1054 let proposal_record = match state.get_record(&record_id) { 1055 Ok(Some(record)) => record, 1056 Ok(None) => { 1057 return Err(ApplyError::InvalidTransaction(format!( 1058 "Record does not exist: {}", 1059 record_id 1060 ))) 1061 } 1062 Err(err) => return Err(err), 1063 }; 1064 1065 if proposal_record.get_field_final() { 1066 return Err(ApplyError::InvalidTransaction(format!( 1067 "Record is final: {}", 1068 record_id 1069 ))); 1070 } 1071 1072 if role == proposal::Proposal_Role::OWNER || role == proposal::Proposal_Role::REPORTER { 1073 let owner = match proposal_record.owners.last() { 1074 Some(owner) => owner, 1075 None => { 1076 return Err(ApplyError::InvalidTransaction(String::from( 1077 "Owner not found", 1078 ))) 1079 } 1080 }; 1081 if owner.get_agent_id() != signer { 1082 return Err(ApplyError::InvalidTransaction(String::from( 1083 "Only the owner can create a proposal to change ownership", 1084 ))); 1085 } 1086 } 1087 1088 if role == proposal::Proposal_Role::CUSTODIAN { 1089 let custodian = match proposal_record.custodians.last() { 1090 Some(custodian) => custodian, 1091 None => { 1092 return Err(ApplyError::InvalidTransaction(String::from( 1093 "Custodian not found", 1094 ))) 1095 } 1096 }; 1097 1098 if custodian.get_agent_id() != signer { 1099 return Err(ApplyError::InvalidTransaction(String::from( 1100 "Only the custodian can create a proposal to change custodianship", 1101 ))); 1102 } 1103 } 1104 1105 let mut new_proposal = proposal::Proposal::new(); 1106 new_proposal.set_record_id(record_id.to_string()); 1107 new_proposal.set_timestamp(timestamp); 1108 new_proposal.set_issuing_agent(signer.to_string()); 1109 new_proposal.set_receiving_agent(receiving_agent.to_string()); 1110 new_proposal.set_role(role); 1111 new_proposal.set_properties(properties); 1112 new_proposal.set_status(proposal::Proposal_Status::OPEN); 1113 1114 proposals.entries.push(new_proposal); 1115 proposals.entries.sort_by_key(|p| { 1116 ( 1117 p.clone().record_id, 1118 p.clone().receiving_agent, 1119 p.clone().timestamp, 1120 ) 1121 }); 1122 state.set_proposal_container(&record_id, &receiving_agent, proposals)?; 1123 1124 Ok(()) 1125 } 1126 1127 fn _answer_proposal( 1128 &self, 1129 payload: payload::AnswerProposalAction, 1130 mut state: SupplyChainState, 1131 signer: &str, 1132 timestamp: u64, 1133 ) -> Result<(), ApplyError> { 1134 let record_id = payload.get_record_id(); 1135 let receiving_agent = payload.get_receiving_agent(); 1136 let role = payload.get_role(); 1137 let response = payload.get_response(); 1138 1139 let mut proposals = match state.get_proposal_container(record_id, receiving_agent) { 1140 Ok(Some(proposals)) => proposals, 1141 Ok(None) => { 1142 return Err(ApplyError::InvalidTransaction(String::from( 1143 "Proposal does not exist", 1144 ))) 1145 } 1146 Err(err) => return Err(err), 1147 }; 1148 1149 let mut exists = false; 1150 let mut current_proposal = match proposals.clone().entries.last() { 1151 Some(current_proposal) => current_proposal.clone(), 1152 None => { 1153 return Err(ApplyError::InvalidTransaction(format!( 1154 "No open proposals found for record {} for {}", 1155 record_id, receiving_agent 1156 ))) 1157 } 1158 }; 1159 1160 let mut proposal_index = 0; 1161 let mut count = 0; 1162 1163 for prop in proposals.get_entries() { 1164 if prop.get_receiving_agent() == receiving_agent && prop.get_role() == role 1165 && prop.get_record_id() == record_id 1166 && prop.status == proposal::Proposal_Status::OPEN 1167 { 1168 current_proposal = prop.clone(); 1169 exists = true; 1170 proposal_index = count; 1171 break; 1172 } 1173 count = count + 1; 1174 } 1175 1176 if !exists { 1177 return Err(ApplyError::InvalidTransaction(format!( 1178 "No open proposals found for record {} for {}", 1179 record_id, receiving_agent 1180 ))); 1181 } 1182 1183 match response { 1184 payload::AnswerProposalAction_Response::CANCEL => { 1185 if current_proposal.get_issuing_agent() != signer { 1186 return Err(ApplyError::InvalidTransaction(String::from( 1187 "Only the issuing agent can cancel a proposal", 1188 ))); 1189 } 1190 current_proposal.status = proposal::Proposal_Status::CANCELED; 1191 } 1192 payload::AnswerProposalAction_Response::REJECT => { 1193 if current_proposal.get_receiving_agent() != signer { 1194 return Err(ApplyError::InvalidTransaction(String::from( 1195 "Only the receiving agent can reject a proposal", 1196 ))); 1197 } 1198 current_proposal.status = proposal::Proposal_Status::REJECTED; 1199 } 1200 payload::AnswerProposalAction_Response::ACCEPT => { 1201 if current_proposal.get_receiving_agent() != signer { 1202 return Err(ApplyError::InvalidTransaction(String::from( 1203 "Only the receiving agent can Accept a proposal", 1204 ))); 1205 }; 1206 1207 let mut proposal_record = match state.get_record(record_id) { 1208 Ok(Some(record)) => record, 1209 Ok(None) => { 1210 return Err(ApplyError::InvalidTransaction(format!( 1211 "Record in proposal does not exist: {}", 1212 record_id 1213 ))) 1214 } 1215 Err(err) => return Err(err), 1216 }; 1217 1218 let owner = match proposal_record.clone().owners.last() { 1219 Some(owner) => owner.clone(), 1220 None => { 1221 return Err(ApplyError::InvalidTransaction(String::from( 1222 "Owner not found", 1223 ))) 1224 } 1225 }; 1226 1227 let custodian = match proposal_record.clone().custodians.last() { 1228 Some(custodian) => custodian.clone(), 1229 None => { 1230 return Err(ApplyError::InvalidTransaction(String::from( 1231 "Custodian not found", 1232 ))) 1233 } 1234 }; 1235 1236 match role { 1237 proposal::Proposal_Role::OWNER => { 1238 if owner.get_agent_id() != current_proposal.get_issuing_agent() { 1239 current_proposal.status = proposal::Proposal_Status::CANCELED; 1240 info!("Record owner does not match the issuing agent of the proposal"); 1241 // remove old proposal and replace with new one 1242 proposals.entries.remove(proposal_index); 1243 proposals.entries.push(current_proposal); 1244 proposals.entries.sort_by_key(|p| { 1245 ( 1246 p.clone().record_id, 1247 p.clone().receiving_agent, 1248 p.clone().timestamp, 1249 ) 1250 }); 1251 state.set_proposal_container(&record_id, &receiving_agent, proposals)?; 1252 return Ok(()); 1253 } 1254 1255 let mut new_owner = record::Record_AssociatedAgent::new(); 1256 new_owner.set_agent_id(receiving_agent.to_string()); 1257 new_owner.set_timestamp(timestamp); 1258 proposal_record.owners.push(new_owner); 1259 state.set_record(record_id, proposal_record.clone())?; 1260 1261 let record_type = 1262 match state.get_record_type(proposal_record.get_record_type()) { 1263 Ok(Some(record_type)) => record_type, 1264 Ok(None) => { 1265 return Err(ApplyError::InvalidTransaction(format!( 1266 "RecordType does not exist: {}", 1267 proposal_record.get_record_type() 1268 ))) 1269 } 1270 Err(err) => return Err(err), 1271 }; 1272 1273 for prop_schema in record_type.get_properties() { 1274 let mut prop = 1275 match state.get_property(record_id, prop_schema.get_name()) { 1276 Ok(Some(prop)) => prop, 1277 Ok(None) => { 1278 return Err(ApplyError::InvalidTransaction(String::from( 1279 "Property does not exist", 1280 ))) 1281 } 1282 Err(err) => return Err(err), 1283 }; 1284 1285 let mut authorized = false; 1286 let mut new_reporters: Vec< 1287 property::Property_Reporter, 1288 > = Vec::new(); 1289 let temp_prob = prop.clone(); 1290 let reporters = temp_prob.get_reporters(); 1291 for reporter in reporters { 1292 if reporter.get_public_key() == owner.get_agent_id() { 1293 let mut new_reporter = reporter.clone(); 1294 new_reporter.set_authorized(false); 1295 new_reporters.push(new_reporter); 1296 } else if reporter.get_public_key() == receiving_agent { 1297 let mut new_reporter = reporter.clone(); 1298 new_reporter.set_authorized(true); 1299 authorized = true; 1300 new_reporters.push(new_reporter); 1301 } else { 1302 new_reporters.push(reporter.clone()); 1303 } 1304 } 1305 1306 if !authorized { 1307 let mut reporter = property::Property_Reporter::new(); 1308 reporter.set_public_key(receiving_agent.to_string()); 1309 reporter.set_authorized(true); 1310 reporter.set_index(prop.reporters.len() as u32); 1311 new_reporters.push(reporter); 1312 } 1313 1314 prop.set_reporters(RepeatedField::from_vec(new_reporters)); 1315 state.set_property(record_id, prop.get_name(), prop.clone())?; 1316 } 1317 current_proposal.status = proposal::Proposal_Status::ACCEPTED; 1318 } 1319 proposal::Proposal_Role::CUSTODIAN => { 1320 if custodian.get_agent_id() != current_proposal.get_issuing_agent() { 1321 current_proposal.status = proposal::Proposal_Status::CANCELED; 1322 info!( 1323 "Record custodian does not match the issuing agent of the proposal" 1324 ); 1325 // remove old proposal and replace with new one 1326 proposals.entries.remove(proposal_index); 1327 proposals.entries.push(current_proposal.clone()); 1328 proposals.entries.sort_by_key(|p| { 1329 ( 1330 p.clone().record_id, 1331 p.clone().receiving_agent, 1332 p.clone().timestamp, 1333 ) 1334 }); 1335 state.set_proposal_container( 1336 &record_id, 1337 &receiving_agent, 1338 proposals.clone(), 1339 )?; 1340 } 1341 1342 let mut new_custodian = record::Record_AssociatedAgent::new(); 1343 new_custodian.set_agent_id(receiving_agent.to_string()); 1344 new_custodian.set_timestamp(timestamp); 1345 proposal_record.custodians.push(new_custodian.clone()); 1346 state.set_record(record_id, proposal_record)?; 1347 current_proposal.status = proposal::Proposal_Status::ACCEPTED; 1348 } 1349 proposal::Proposal_Role::REPORTER => { 1350 if owner.get_agent_id() != current_proposal.get_issuing_agent() { 1351 current_proposal.status = proposal::Proposal_Status::CANCELED; 1352 info!("Record owner does not match the issuing agent of the proposal"); 1353 // remove old proposal and replace with new one 1354 proposals.entries.remove(proposal_index); 1355 proposals.entries.push(current_proposal); 1356 proposals.entries.sort_by_key(|p| { 1357 ( 1358 p.clone().record_id, 1359 p.clone().receiving_agent, 1360 p.clone().timestamp, 1361 ) 1362 }); 1363 state.set_proposal_container(&record_id, &receiving_agent, proposals)?; 1364 return Ok(()); 1365 } 1366 1367 let mut reporter = property::Property_Reporter::new(); 1368 reporter.set_public_key(receiving_agent.to_string()); 1369 reporter.set_authorized(true); 1370 1371 for prop_name in current_proposal.get_properties() { 1372 let mut prop = match state.get_property(record_id, prop_name) { 1373 Ok(Some(prop)) => prop, 1374 Ok(None) => { 1375 return Err(ApplyError::InvalidTransaction(String::from( 1376 "Property does not exist", 1377 ))) 1378 } 1379 Err(err) => return Err(err), 1380 }; 1381 reporter.set_index(prop.reporters.len() as u32); 1382 prop.reporters.push(reporter.clone()); 1383 state.set_property(record_id, prop_name, prop)?; 1384 } 1385 current_proposal.status = proposal::Proposal_Status::ACCEPTED; 1386 } 1387 } 1388 } 1389 } 1390 // remove old proposal and replace with new one 1391 proposals.entries.remove(proposal_index); 1392 proposals.entries.push(current_proposal.clone()); 1393 proposals.entries.sort_by_key(|p| { 1394 ( 1395 p.clone().record_id, 1396 p.clone().receiving_agent, 1397 p.clone().timestamp, 1398 ) 1399 }); 1400 state.set_proposal_container(&record_id, &receiving_agent, proposals)?; 1401 1402 Ok(()) 1403 } 1404 1405 fn _revoke_reporter( 1406 &self, 1407 payload: payload::RevokeReporterAction, 1408 mut state: SupplyChainState, 1409 signer: &str, 1410 ) -> Result<(), ApplyError> { 1411 let record_id = payload.get_record_id(); 1412 let reporter_id = payload.get_reporter_id(); 1413 let properties = payload.get_properties(); 1414 1415 let revoke_record = match state.get_record(record_id) { 1416 Ok(Some(record)) => record, 1417 Ok(None) => { 1418 return Err(ApplyError::InvalidTransaction(format!( 1419 "Record does not exists: {}", 1420 record_id 1421 ))) 1422 } 1423 Err(err) => return Err(err), 1424 }; 1425 1426 let owner = match revoke_record.owners.last() { 1427 Some(x) => x, 1428 None => { 1429 return Err(ApplyError::InvalidTransaction(String::from( 1430 "Owner was not found", 1431 ))) 1432 } 1433 }; 1434 1435 if owner.get_agent_id() != signer { 1436 return Err(ApplyError::InvalidTransaction(format!( 1437 "Must be owner to revoke reporters" 1438 ))); 1439 } 1440 1441 if revoke_record.get_field_final() { 1442 return Err(ApplyError::InvalidTransaction(format!( 1443 "Record is final: {}", 1444 record_id 1445 ))); 1446 } 1447 1448 for prop_name in properties { 1449 let mut prop = match state.get_property(record_id, prop_name) { 1450 Ok(Some(prop)) => prop, 1451 Ok(None) => { 1452 return Err(ApplyError::InvalidTransaction(format!( 1453 "Property does not exists" 1454 ))) 1455 } 1456 Err(err) => return Err(err), 1457 }; 1458 1459 let mut new_reporters: Vec<property::Property_Reporter> = Vec::new(); 1460 let mut revoked = false; 1461 for reporter in prop.get_reporters() { 1462 if reporter.get_public_key() == reporter_id { 1463 if !reporter.get_authorized() { 1464 return Err(ApplyError::InvalidTransaction(format!( 1465 "Reporter is already unauthorized." 1466 ))); 1467 } 1468 let mut unauthorized_reporter = reporter.clone(); 1469 unauthorized_reporter.set_authorized(false); 1470 revoked = true; 1471 new_reporters.push(unauthorized_reporter); 1472 } else { 1473 new_reporters.push(reporter.clone()); 1474 } 1475 } 1476 if !revoked { 1477 return Err(ApplyError::InvalidTransaction(format!( 1478 "Reporter cannot be revoked: {}", 1479 reporter_id 1480 ))); 1481 } 1482 prop.set_reporters(RepeatedField::from_vec(new_reporters)); 1483 1484 state.set_property(record_id, prop_name, prop)?; 1485 } 1486 1487 Ok(()) 1488 } 1489 1490 fn _make_new_reported_value( 1491 &self, 1492 reporter_index: u32, 1493 timestamp: u64, 1494 value: &property::PropertyValue, 1495 property: &property::Property, 1496 ) -> Result<property::PropertyPage_ReportedValue, ApplyError> { 1497 let mut reported_value = property::PropertyPage_ReportedValue::new(); 1498 reported_value.set_reporter_index(reporter_index); 1499 reported_value.set_timestamp(timestamp); 1500 1501 match value.get_data_type() { 1502 property::PropertySchema_DataType::TYPE_UNSET => { 1503 return Err(ApplyError::InvalidTransaction(String::from( 1504 "DataType is not set", 1505 ))) 1506 } 1507 property::PropertySchema_DataType::BYTES => { 1508 reported_value.set_bytes_value(value.get_bytes_value().to_vec()) 1509 } 1510 property::PropertySchema_DataType::BOOLEAN => { 1511 reported_value.set_boolean_value(value.get_boolean_value()) 1512 } 1513 property::PropertySchema_DataType::NUMBER => { 1514 reported_value.set_number_value(value.get_number_value()) 1515 } 1516 property::PropertySchema_DataType::STRING => { 1517 reported_value.set_string_value(value.get_string_value().to_string()) 1518 } 1519 property::PropertySchema_DataType::ENUM => { 1520 let enum_name = value.get_enum_value().to_string(); 1521 let enum_index = match property.enum_options.iter() 1522 .position(|name| name == &enum_name) { 1523 Some(index) => index, 1524 None => { 1525 return Err(ApplyError::InvalidTransaction(format!( 1526 "Provided enum name is not a valid option: {}", 1527 enum_name, 1528 ))) 1529 } 1530 }; 1531 reported_value.set_enum_value(enum_index as u32) 1532 } 1533 property::PropertySchema_DataType::STRUCT => { 1534 match self._validate_struct_values( 1535 &value.struct_values, 1536 &property.struct_properties 1537 ) { 1538 Ok(_) => (), 1539 Err(e) => return Err(e), 1540 } 1541 1542 let struct_values = RepeatedField::from_vec(value.get_struct_values().to_vec()); 1543 reported_value.set_struct_values(struct_values) 1544 } 1545 property::PropertySchema_DataType::LOCATION => { 1546 reported_value.set_location_value(value.get_location_value().clone()) 1547 } 1548 }; 1549 Ok(reported_value) 1550 } 1551 1552 fn _validate_struct_values( 1553 &self, 1554 struct_values: &RepeatedField<property::PropertyValue>, 1555 schema_values: &RepeatedField<property::PropertySchema> 1556 ) -> Result<(), ApplyError> { 1557 if struct_values.len() != schema_values.len() { 1558 return Err(ApplyError::InvalidTransaction(format!( 1559 "Provided struct does not match schema length: {:?} != {:?}", 1560 struct_values.len(), 1561 schema_values.len(), 1562 ))) 1563 } 1564 1565 for schema in schema_values.iter() { 1566 let value = match struct_values.iter().find(|val| val.name == schema.name) { 1567 Some(val) => val, 1568 None => return Err(ApplyError::InvalidTransaction(format!( 1569 "Provided struct missing required property from schema: {}", 1570 schema.name, 1571 ))) 1572 }; 1573 1574 if value.data_type != schema.data_type { 1575 return Err(ApplyError::InvalidTransaction(format!( 1576 "Struct property \"{}\" must have data type: {:?}", 1577 schema.name, 1578 schema.data_type, 1579 ))) 1580 } 1581 1582 if schema.data_type == property::PropertySchema_DataType::STRUCT { 1583 match self._validate_struct_values( 1584 &value.struct_values, 1585 &schema.struct_properties 1586 ) { 1587 Ok(_) => (), 1588 Err(e) => return Err(e), 1589 } 1590 } 1591 } 1592 1593 Ok(()) 1594 } 1595 } 1596 1597 impl TransactionHandler for SupplyChainTransactionHandler { 1598 fn family_name(&self) -> String { 1599 return self.family_name.clone(); 1600 } 1601 1602 fn family_versions(&self) -> Vec<String> { 1603 return self.family_versions.clone(); 1604 } 1605 1606 fn namespaces(&self) -> Vec<String> { 1607 return self.namespaces.clone(); 1608 } 1609 1610 fn apply( 1611 &self, 1612 request: &TpProcessRequest, 1613 context: &mut TransactionContext, 1614 ) -> Result<(), ApplyError> { 1615 let payload = SupplyChainPayload::new(request.get_payload()); 1616 let payload = match payload { 1617 Err(e) => return Err(e), 1618 Ok(payload) => payload, 1619 }; 1620 let payload = match payload { 1621 Some(x) => x, 1622 None => { 1623 return Err(ApplyError::InvalidTransaction(String::from( 1624 "Request must contain a payload", 1625 ))) 1626 } 1627 }; 1628 1629 let signer = request.get_header().get_signer_public_key(); 1630 let state = SupplyChainState::new(context); 1631 1632 info!( 1633 "payload: {:?} {} {} {}", 1634 payload.get_action(), 1635 payload.get_timestamp(), 1636 request.get_header().get_inputs()[0], 1637 request.get_header().get_outputs()[0] 1638 ); 1639 1640 match payload.get_action() { 1641 Action::CreateAgent(agent_payload) => { 1642 self._create_agent(agent_payload, state, signer, payload.get_timestamp())? 1643 } 1644 Action::CreateRecord(record_payload) => { 1645 self._create_record(record_payload, state, signer, payload.get_timestamp())? 1646 } 1647 Action::FinalizeRecord(finalize_payload) => { 1648 self._finalize_record(finalize_payload, state, signer)? 1649 } 1650 Action::CreateRecordType(record_type_payload) => { 1651 self._create_record_type(record_type_payload, state, signer)? 1652 } 1653 Action::UpdateProperties(update_properties_payload) => self._update_properties( 1654 update_properties_payload, 1655 state, 1656 signer, 1657 payload.get_timestamp(), 1658 )?, 1659 Action::CreateProposal(proposal_payload) => { 1660 self._create_proposal(proposal_payload, state, signer, payload.get_timestamp())? 1661 } 1662 Action::AnswerProposal(answer_proposal_payload) => self._answer_proposal( 1663 answer_proposal_payload, 1664 state, 1665 signer, 1666 payload.get_timestamp(), 1667 )?, 1668 Action::RevokeReporter(revoke_reporter_payload) => { 1669 self._revoke_reporter(revoke_reporter_payload, state, signer)? 1670 } 1671 } 1672 Ok(()) 1673 } 1674 }