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  }