#![warn(missing_docs)]
mod bundle;
pub mod errors;
mod mock;
pub mod runtime;
pub mod sandbox;
pub use sandbox::*;
#[cfg(feature = "session")]
pub mod session;
use std::sync::{Arc, Mutex};
pub use bundle::ContractBundle;
pub use drink_test_macro::{contract_bundle_provider, test};
pub use errors::Error;
pub use frame_support::{
sp_runtime::{AccountId32, DispatchError},
weights::Weight,
};
use frame_system::EventRecord;
pub use mock::{mock_message, ContractMock, MessageMock, MockedCallResult, Selector};
use pallet_contracts::{debug::ExecResult, ExecReturnValue};
use pallet_contracts_uapi::ReturnFlags;
use parity_scale_codec::{Decode, Encode};
pub use {frame_support, frame_system, pallet_balances, pallet_contracts, pallet_timestamp};
use crate::{
errors::MessageResult,
mock::MockRegistry,
runtime::{pallet_contracts_debugging::InterceptingExtT, *},
};
pub type RuntimeCall<R> = <R as frame_system::Config>::RuntimeCall;
pub type BalanceOf<R> = <R as pallet_balances::Config>::Balance;
pub type DrinkResult<T> = std::result::Result<T, Error>;
pub type EventRecordOf<T> =
EventRecord<<T as frame_system::Config>::RuntimeEvent, <T as frame_system::Config>::Hash>;
pub const DEFAULT_GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024);
struct MockingExtension<AccountId: Ord> {
mock_registry: Arc<Mutex<MockRegistry<AccountId>>>,
}
impl<AccountId: Ord + Decode> InterceptingExtT for MockingExtension<AccountId> {
fn intercept_call(
&self,
contract_address: Vec<u8>,
_is_call: bool,
input_data: Vec<u8>,
) -> Vec<u8> {
let contract_address = Decode::decode(&mut &contract_address[..])
.expect("Contract address should be decodable");
match self
.mock_registry
.lock()
.expect("Should be able to acquire registry")
.get(&contract_address)
{
None => None::<()>.encode(),
Some(mock) => {
let (selector, call_data) = input_data.split_at(4);
let selector: Selector = selector
.try_into()
.expect("Input data should contain at least selector bytes");
let result = mock
.call(selector, call_data.to_vec())
.expect("TODO: let the user define the fallback mechanism");
let decoded_result: MessageResult<()> =
Decode::decode(&mut &result[..]).expect("Mock result should be decodable");
let flags = match decoded_result {
Ok(_) => ReturnFlags::empty(),
Err(_) => ReturnFlags::REVERT,
};
let result: ExecResult = Ok(ExecReturnValue {
flags,
data: result,
});
Some(result).encode()
}
}
}
}