You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: send_blockchain_message.rs
    path of file: ./repos/saito-rust/src/networking/message_types
    
    the code of the file until where you have to start completion: use crate::crypto::SaitoHash;
use macros::TryFromByte;
use std::convert::{TryFrom, TryInto};

/// Data Object for SNDCHAIN. Is used as a payload in an APIMessage message field.
/// `block_id`
/// `block_hash`
/// `timestamp`
/// (future work) pre_hash: the hash which is hashed with the previous block_hash to generate the hash of the current block.
/// (future work) number of transactions: the number of transactions in the block for the recipient
pub const BLOCKCHAIN_BLOCK_DATA_SIZE: usize = 84;

#[derive(Debug, Copy, PartialEq, Clone, TryFromByte)]
pub enum SyncType {
    Full,
    Lite,
}
#[derive(Debug)]
pub struct SendBlockchainBlockData {
    pub block_id: u64,
    pub block_hash: SaitoHash,
    pub timestamp: u64,
    pub pre_hash: SaitoHash,
    pub number_of_transactions: u32,
}
#[derive(Debug)]
pub struct SendBlockchainMessage {
    sync_type: SyncType,
    starting_hash: SaitoHash,
    blocks_data: Vec<SendBlockchainBlockData>,
}

impl SendBlockchainMessage {
    pub fn new(
        sync_type: SyncType,
        starting_hash: SaitoHash,
        blocks_data: Vec<SendBlockchainBlockData>,
    ) -> Self {
        SendBlockchainMessage {
            sync_type,
            startin
    
    async fn test_send_blockchain_message_serialize() {
        let mut blocks_data: Vec<SendBlockchainBlockData> = vec![];
        blocks_data.push(SendBlockchainBlockData {
            block_id: 1,
            block_hash: [1; 32],
            timestamp: 1,
            pre_hash: [1; 32],
            number_of_transactions: 1,
        });
        blocks_data.push(SendBlockchainBlockData {
            block_id: 2,
            block_hash: [2; 32],
            timestamp: 2,
            pre_hash: [2; 32],
            number_of_transactions: 2,
        });
        let send_blockchain_message =
            SendBlockchainMessage::new(SyncType::Full, [1; 32], blocks_data);

        let serialized_send_blockchain_message = send_blockchain_message.serialize();
        let deserialized_send_blockchain_message =
            SendBlockchainMessage::deserialize(&serialized_send_blockchain_message);
        assert_eq!(
            send_blockchain_message.get_sync_type(),
            deserialized_send_blockchain_message.get_sync_type()
        );
        assert_eq!(
            send_blockchain_message.get_starting_hash(),
            deserialized_send_blockchain_message.get_starting_hash()
        );
        let block_data_in = send_blockchain_message.get_blocks_data();
        let block_data_out = deserialized_send_blockchain_message.get_blocks_data();
        assert_eq!(block_data_in[0].block_id, block_data_out[0].block_id);
        assert_eq!(block_data_in[0].timestamp, block_data_out[0].timestamp);
        assert_eq!(block_data_in[0].pre_hash, block_data_out[0].pre_hash);
        assert_eq!(
            block_data_in[0].number_of_transactions,
            block_data_out[0].number_of_transactions
        );
        assert_eq!(block_data_in[1].block_id, block_data_out[1].block_id);
        assert_eq!(block_data_in[1].timestamp, block_data_out[1].timestamp);
        assert_eq!(block_data_in[1].pre_hash, block_data_out[1].pre_hash);
        assert_eq!(
            block_data_in[1].number_of_transactions,
            block_data_out[1].number_of_transactions
        );
    }