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
use std::collections::HashMap;

use anyhow::Result as AnyResult;
use cosmwasm_std::{Addr, Binary, CodeInfoResponse, CustomQuery, Order, Storage};
use cw_orch::daemon::queriers::CosmWasm;

use crate::{
    prefixed_storage::prefixed_read,
    wasm::{ContractData, CONTRACTS, NAMESPACE_WASM},
    wasm_emulation::{channel::RemoteChannel, input::WasmStorage, query::AllWasmQuerier},
    WasmKeeper,
};

pub struct WasmRemoteQuerier;

impl WasmRemoteQuerier {
    pub fn code_info(remote: RemoteChannel, code_id: u64) -> AnyResult<CodeInfoResponse> {
        let wasm_querier = CosmWasm::new_sync(remote.channel, &remote.rt);

        let code_info = remote.rt.block_on(wasm_querier._code(code_id))?;
        Ok(code_info)
    }

    pub fn load_distant_contract(remote: RemoteChannel, address: &Addr) -> AnyResult<ContractData> {
        let wasm_querier = CosmWasm::new_sync(remote.channel, &remote.rt);

        let code_info = remote.rt.block_on(wasm_querier._contract_info(address))?;

        Ok(ContractData {
            admin: code_info.admin.map(Addr::unchecked),
            code_id: code_info.code_id,
            creator: Addr::unchecked(code_info.creator),
        })
    }

    pub fn raw_query(
        remote: RemoteChannel,
        contract_addr: &Addr,
        key: Binary,
    ) -> AnyResult<Vec<u8>> {
        let wasm_querier = CosmWasm::new_sync(remote.channel, &remote.rt);
        let query_result = remote
            .rt
            .block_on(wasm_querier._contract_raw_state(contract_addr, key.to_vec()))
            .map(|query_result| query_result.data);
        Ok(query_result?)
    }
}

impl<ExecC, QueryC: CustomQuery> AllWasmQuerier for WasmKeeper<ExecC, QueryC> {
    fn query_all(&self, storage: &dyn Storage) -> AnyResult<WasmStorage> {
        let all_local_state: Vec<_> = storage.range(None, None, Order::Ascending).collect();

        let contracts = CONTRACTS
            .range(
                &prefixed_read(storage, NAMESPACE_WASM),
                None,
                None,
                Order::Ascending,
            )
            .map(|res| match res {
                Ok((key, value)) => Ok((key.to_string(), value)),
                Err(e) => Err(e),
            })
            .collect::<Result<HashMap<_, _>, _>>()?;

        Ok(WasmStorage {
            contracts,
            storage: all_local_state,
            codes: self.code_base.borrow().clone(),
            code_data: self.code_data.clone(),
        })
    }
}