github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/src/block_ffi.rs (about) 1 /* 2 * Copyright 2018 Intel Corporation 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 use batch::Batch; 18 use block::Block; 19 use cpython; 20 use cpython::{FromPyObject, ObjectProtocol, PyObject, Python, PythonObject, ToPyObject}; 21 use proto::batch::Batch as ProtoBatch; 22 use proto::batch::BatchHeader; 23 use proto::block::Block as ProtoBlock; 24 use proto::block::BlockHeader; 25 use proto::transaction::Transaction as ProtoTxn; 26 use proto::transaction::TransactionHeader; 27 use protobuf; 28 use protobuf::Message; 29 use transaction::Transaction; 30 31 impl<'source> FromPyObject<'source> for Block { 32 fn extract(py: Python, obj: &'source PyObject) -> cpython::PyResult<Self> { 33 let bytes: Vec<u8> = obj.call_method(py, "SerializeToString", cpython::NoArgs, None)? 34 .extract(py)?; 35 36 let mut proto_block: ProtoBlock = protobuf::parse_from_bytes(&bytes) 37 .expect("Unable to parse protobuf bytes from python protobuf object"); 38 39 let mut block_header: BlockHeader = protobuf::parse_from_bytes(proto_block.get_header()) 40 .expect("Unable to parse protobuf bytes from python protobuf object"); 41 let block = Block { 42 header_signature: proto_block.take_header_signature(), 43 header_bytes: proto_block.take_header(), 44 state_root_hash: block_header.take_state_root_hash(), 45 consensus: block_header.take_consensus(), 46 batch_ids: block_header.take_batch_ids().into_vec(), 47 signer_public_key: block_header.take_signer_public_key(), 48 previous_block_id: block_header.take_previous_block_id(), 49 block_num: block_header.get_block_num(), 50 51 batches: proto_block 52 .take_batches() 53 .iter_mut() 54 .map(proto_batch_to_batch) 55 .collect(), 56 }; 57 58 Ok(block) 59 } 60 } 61 62 fn proto_batch_to_batch(proto_batch: &mut ProtoBatch) -> Batch { 63 let mut batch_header: BatchHeader = protobuf::parse_from_bytes(proto_batch.get_header()) 64 .expect("Unable to parse protobuf bytes from python protobuf object"); 65 Batch { 66 header_signature: proto_batch.take_header_signature(), 67 header_bytes: proto_batch.take_header(), 68 signer_public_key: batch_header.take_signer_public_key(), 69 transaction_ids: batch_header.take_transaction_ids().into_vec(), 70 trace: proto_batch.get_trace(), 71 72 transactions: proto_batch 73 .take_transactions() 74 .iter_mut() 75 .map(proto_txn_to_txn) 76 .collect(), 77 } 78 } 79 80 fn proto_txn_to_txn(proto_txn: &mut ProtoTxn) -> Transaction { 81 let mut txn_header: TransactionHeader = protobuf::parse_from_bytes(proto_txn.get_header()) 82 .expect("Unable to parse protobuf bytes from python protobuf object"); 83 84 Transaction { 85 header_signature: proto_txn.take_header_signature(), 86 header_bytes: proto_txn.take_header(), 87 payload: proto_txn.take_payload(), 88 batcher_public_key: txn_header.take_batcher_public_key(), 89 dependencies: txn_header.take_dependencies().into_vec(), 90 family_name: txn_header.take_family_name(), 91 family_version: txn_header.take_family_version(), 92 inputs: txn_header.take_inputs().into_vec(), 93 outputs: txn_header.take_outputs().into_vec(), 94 nonce: txn_header.take_nonce(), 95 payload_sha512: txn_header.take_payload_sha512(), 96 signer_public_key: txn_header.take_signer_public_key(), 97 } 98 } 99 100 impl ToPyObject for Block { 101 type ObjectType = PyObject; 102 103 fn to_py_object(&self, py: Python) -> PyObject { 104 let block_protobuf_mod = py.import("sawtooth_validator.protobuf.block_pb2") 105 .expect("Unable to import block_pb2"); 106 let py_block = block_protobuf_mod 107 .get(py, "Block") 108 .expect("Unable to get Block"); 109 110 let mut proto_block = ProtoBlock::new(); 111 proto_block.set_header(self.header_bytes.clone()); 112 proto_block.set_header_signature(self.header_signature.clone()); 113 114 let proto_batches = self.batches 115 .iter() 116 .map(|batch| { 117 let mut proto_batch = ProtoBatch::new(); 118 proto_batch.set_header(batch.header_bytes.clone()); 119 proto_batch.set_header_signature(batch.header_signature.clone()); 120 121 let proto_txns = batch 122 .transactions 123 .iter() 124 .map(|txn| { 125 let mut proto_txn = ProtoTxn::new(); 126 proto_txn.set_header(txn.header_bytes.clone()); 127 proto_txn.set_header_signature(txn.header_signature.clone()); 128 proto_txn.set_payload(txn.payload.clone()); 129 proto_txn 130 }) 131 .collect::<Vec<_>>(); 132 133 proto_batch.set_transactions(protobuf::RepeatedField::from_vec(proto_txns)); 134 135 proto_batch 136 }) 137 .collect::<Vec<_>>(); 138 139 proto_block.set_batches(protobuf::RepeatedField::from_vec(proto_batches)); 140 141 let block = py_block 142 .call(py, cpython::NoArgs, None) 143 .expect("Unable to instantiate Block"); 144 block 145 .call_method( 146 py, 147 "ParseFromString", 148 (cpython::PyBytes::new(py, &proto_block.write_to_bytes().unwrap()).into_object(),), 149 None, 150 ) 151 .expect("Unable to ParseFromString"); 152 block 153 } 154 }