1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::convert::{TryFrom, TryInto};

use casper_types::{account::AccountHash, Key};

use crate::engine_server::{
    mappings::{self, ParsingError},
    state::{self, Key_Address, Key_Hash, Key_oneof_value},
};

impl From<Key> for state::Key {
    fn from(key: Key) -> Self {
        let mut pb_key = state::Key::new();
        match key {
            Key::Account(account) => {
                let mut pb_account = Key_Address::new();
                pb_account.set_account(account.as_bytes().to_vec());
                pb_key.set_address(pb_account);
            }
            Key::Hash(hash) => {
                let mut pb_hash = Key_Hash::new();
                pb_hash.set_hash(hash.to_vec());
                pb_key.set_hash(pb_hash);
            }
            Key::URef(uref) => {
                pb_key.set_uref(uref.into());
            }
            Key::DeployInfo(deploy_hash) => {
                let mut pb_deploy_hash = state::DeployHash::new();
                pb_deploy_hash.set_deploy_hash(deploy_hash.to_vec());
                pb_key.set_deploy_info(pb_deploy_hash)
            }
            Key::Transfer(transfer_addr) => {
                let mut pb_transfer_addr = state::TransferAddr::new();
                pb_transfer_addr.set_transfer_addr(transfer_addr.to_vec());
                pb_key.set_transfer(pb_transfer_addr)
            }
        }
        pb_key
    }
}

impl TryFrom<state::Key> for Key {
    type Error = ParsingError;

    fn try_from(pb_key: state::Key) -> Result<Self, Self::Error> {
        let pb_key = pb_key
            .value
            .ok_or_else(|| ParsingError::from("Unable to parse Protobuf Key"))?;

        let key = match pb_key {
            Key_oneof_value::address(pb_account) => {
                let account = mappings::vec_to_array(pb_account.account, "Protobuf Key::Account")?;
                Key::Account(AccountHash::new(account))
            }
            Key_oneof_value::hash(pb_hash) => {
                let hash = mappings::vec_to_array(pb_hash.hash, "Protobuf Key::Hash")?;
                Key::Hash(hash)
            }
            Key_oneof_value::uref(pb_uref) => {
                let uref = pb_uref.try_into()?;
                Key::URef(uref)
            }
            Key_oneof_value::transfer(pb_transfer_addr) => {
                let transfer_addr = mappings::vec_to_array(
                    pb_transfer_addr.transfer_addr,
                    "Protobuf Key::Transfer",
                )?;
                Key::Transfer(transfer_addr)
            }
            Key_oneof_value::deploy_info(pb_deploy_hash) => {
                let deploy_hash =
                    mappings::vec_to_array(pb_deploy_hash.deploy_hash, "Protobuf Key::DeployInfo")?;
                Key::DeployInfo(deploy_hash)
            }
        };
        Ok(key)
    }
}

#[cfg(test)]
mod tests {
    use proptest::proptest;

    use casper_types::gens;

    use super::*;
    use crate::engine_server::mappings::test_utils;

    proptest! {
        #[test]
        fn round_trip(key in gens::key_arb()) {
            test_utils::protobuf_round_trip::<Key, state::Key>(key);
        }
    }
}