ink_e2e/
client_utils.rs

1// Copyright (C) Use Ink (UK) Ltd.
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
15use crate::log_info;
16use std::{
17    collections::BTreeMap,
18    path::PathBuf,
19};
20
21/// Generate a unique salt based on the system time.
22/// todo return no `Option` here, just the salt.
23pub fn salt() -> Option<[u8; 32]> {
24    use funty::Fundamental as _;
25
26    let mut arr = [0u8; 32];
27    let t: [u8; 16] = std::time::SystemTime::now()
28        .duration_since(std::time::UNIX_EPOCH)
29        .unwrap_or_else(|err| panic!("unable to get unix time: {err}"))
30        .as_millis()
31        .as_u128()
32        .to_le_bytes();
33    arr[..16].copy_from_slice(t.as_slice());
34    arr[16..].copy_from_slice(t.as_slice());
35    Some(arr)
36}
37
38/// A registry of contracts that can be loaded.
39pub struct ContractsRegistry {
40    contracts: BTreeMap<String, PathBuf>,
41}
42
43impl ContractsRegistry {
44    /// Create a new registry with the given contracts.
45    pub fn new<P: Into<PathBuf>>(contracts: impl IntoIterator<Item = P>) -> Self {
46        let contracts = contracts
47            .into_iter()
48            .map(|path| {
49                let contract_binary_path: PathBuf = path.into();
50                let contract_name =
51                    contract_binary_path.file_stem().unwrap_or_else(|| {
52                        panic!(
53                            "Invalid contract binary path `{}`",
54                            contract_binary_path.display(),
55                        )
56                    });
57                (
58                    contract_name.to_string_lossy().to_string(),
59                    contract_binary_path,
60                )
61            })
62            .collect();
63
64        Self { contracts }
65    }
66
67    /// Load the binary code for the given contract.
68    pub fn load_code(&self, contract: &str) -> Vec<u8> {
69        let contract_binary_path = self
70            .contracts
71            .get(&contract.replace('-', "_"))
72            .unwrap_or_else(||
73                panic!(
74                    "Unknown contract {contract}. Available contracts: {:?}.\n\
75                     For a contract to be built, add it as a dependency to the `Cargo.toml`",
76                    self.contracts.keys()
77                )
78            );
79        let code = std::fs::read(contract_binary_path).unwrap_or_else(|err| {
80            panic!(
81                "Error loading '{}': {:?}",
82                contract_binary_path.display(),
83                err
84            )
85        });
86        log_info(&format!("{:?} has {} KiB", contract, code.len() / 1024));
87        code
88    }
89}