Skip to content

Commit e110d55

Browse files
authored
Move code to "macros" and "session" features (#110)
1 parent 0e33fb1 commit e110d55

File tree

14 files changed

+125
-110
lines changed

14 files changed

+125
-110
lines changed

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ homepage = "https://github.com/Cardinal-Cryptography/drink"
1818
license = "Apache-2.0"
1919
readme = "README.md"
2020
repository = "https://github.com/Cardinal-Cryptography/drink"
21-
version = "0.11.1"
21+
version = "0.12.0"
2222

2323
[workspace.dependencies]
2424
anyhow = { version = "1.0.71" }
@@ -57,5 +57,5 @@ sp-runtime-interface = { version = "24.0.0" }
5757

5858
# Local dependencies
5959

60-
drink = { version = "0.11.1", path = "drink" }
61-
drink-test-macro = { version = "0.11.1", path = "drink/test-macro" }
60+
drink = { version = "=0.12.0", path = "drink" }
61+
drink-test-macro = { version = "=0.12.0", path = "drink/test-macro" }

drink/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ drink-test-macro = { workspace = true }
3636
default = [
3737
# This is required for the runtime-interface to work properly in the std env.
3838
"std",
39-
"session"
39+
"session",
40+
"macros"
4041
]
4142
session = ["contract-metadata", "contract-transcode", "serde_json"]
43+
macros = ["contract-metadata", "contract-transcode", "serde_json"]
4244
std = []

drink/src/lib.rs

Lines changed: 3 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,27 @@
33
44
#![warn(missing_docs)]
55

6-
mod bundle;
76
pub mod errors;
8-
mod mock;
97
pub mod runtime;
108
pub mod sandbox;
119
pub use sandbox::*;
1210
#[cfg(feature = "session")]
1311
pub mod session;
1412

15-
use std::sync::{Arc, Mutex};
16-
17-
pub use bundle::ContractBundle;
13+
#[cfg(feature = "macros")]
1814
pub use drink_test_macro::{contract_bundle_provider, test};
1915
pub use errors::Error;
2016
pub use frame_support::{
2117
sp_runtime::{AccountId32, DispatchError},
2218
weights::Weight,
2319
};
2420
use frame_system::EventRecord;
25-
pub use mock::{mock_message, ContractMock, MessageMock, MockedCallResult, Selector};
26-
use pallet_contracts::{debug::ExecResult, ExecReturnValue};
27-
use pallet_contracts_uapi::ReturnFlags;
28-
use parity_scale_codec::{Decode, Encode};
21+
#[cfg(feature = "session")]
22+
pub use session::mock::{mock_message, ContractMock, MessageMock, MockedCallResult, Selector};
2923
/// Export pallets that are used in the minimal runtime.
3024
pub use {frame_support, frame_system, pallet_balances, pallet_contracts, pallet_timestamp};
3125

3226
pub use crate::runtime::minimal::{self, MinimalRuntime};
33-
use crate::{
34-
errors::MessageResult, mock::MockRegistry,
35-
runtime::pallet_contracts_debugging::InterceptingExtT,
36-
};
3727

3828
/// Alias for `frame-system`'s `RuntimeCall` type.
3929
pub type RuntimeCall<R> = <R as frame_system::Config>::RuntimeCall;
@@ -50,63 +40,3 @@ pub type EventRecordOf<T> =
5040

5141
/// Default gas limit.
5242
pub const DEFAULT_GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024);
53-
54-
/// Runtime extension enabling contract call interception.
55-
struct MockingExtension<AccountId: Ord> {
56-
/// Mock registry, shared with the sandbox.
57-
///
58-
/// Potentially the runtime is executed in parallel and thus we need to wrap the registry in
59-
/// `Arc<Mutex>` instead of `Rc<RefCell>`.
60-
mock_registry: Arc<Mutex<MockRegistry<AccountId>>>,
61-
}
62-
63-
impl<AccountId: Ord + Decode> InterceptingExtT for MockingExtension<AccountId> {
64-
fn intercept_call(
65-
&self,
66-
contract_address: Vec<u8>,
67-
_is_call: bool,
68-
input_data: Vec<u8>,
69-
) -> Vec<u8> {
70-
let contract_address = Decode::decode(&mut &contract_address[..])
71-
.expect("Contract address should be decodable");
72-
73-
match self
74-
.mock_registry
75-
.lock()
76-
.expect("Should be able to acquire registry")
77-
.get(&contract_address)
78-
{
79-
// There is no mock registered for this address, so we return `None` to indicate that
80-
// the call should be executed normally.
81-
None => None::<()>.encode(),
82-
// We intercept the call and return the result of the mock.
83-
Some(mock) => {
84-
let (selector, call_data) = input_data.split_at(4);
85-
let selector: Selector = selector
86-
.try_into()
87-
.expect("Input data should contain at least selector bytes");
88-
89-
let result = mock
90-
.call(selector, call_data.to_vec())
91-
.expect("TODO: let the user define the fallback mechanism");
92-
93-
// Although we don't know the exact type, thanks to the SCALE encoding we know
94-
// that `()` will always succeed (we only care about the `Ok`/`Err` distinction).
95-
let decoded_result: MessageResult<()> =
96-
Decode::decode(&mut &result[..]).expect("Mock result should be decodable");
97-
98-
let flags = match decoded_result {
99-
Ok(_) => ReturnFlags::empty(),
100-
Err(_) => ReturnFlags::REVERT,
101-
};
102-
103-
let result: ExecResult = Ok(ExecReturnValue {
104-
flags,
105-
data: result,
106-
});
107-
108-
Some(result).encode()
109-
}
110-
}
111-
}
112-
}

drink/src/session.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,29 @@ use parity_scale_codec::Decode;
1515
pub use record::{EventBatch, Record};
1616

1717
use crate::{
18-
mock::MockRegistry,
1918
runtime::{
2019
pallet_contracts_debugging::{InterceptingExt, TracingExt},
2120
AccountIdFor, HashFor,
2221
},
2322
sandbox::SandboxConfig,
24-
MockingExtension, Sandbox, DEFAULT_GAS_LIMIT,
23+
session::mock::MockRegistry,
24+
Sandbox, DEFAULT_GAS_LIMIT,
2525
};
2626

27+
pub mod mock;
28+
use mock::MockingExtension;
29+
pub mod bundle;
2730
pub mod error;
2831
pub mod mocking_api;
2932
mod record;
3033
mod transcoding;
3134

35+
pub use bundle::ContractBundle;
3236
use error::SessionError;
3337

3438
use self::mocking_api::MockingApi;
3539
use crate::{
36-
bundle::ContractBundle, errors::MessageResult, runtime::MinimalRuntime,
37-
session::transcoding::TranscoderRegistry,
40+
errors::MessageResult, runtime::MinimalRuntime, session::transcoding::TranscoderRegistry,
3841
};
3942

4043
type BalanceOf<R> =
@@ -115,9 +118,8 @@ pub const NO_ENDOWMENT: Option<BalanceOf<MinimalRuntime>> = None;
115118
/// # use drink::{
116119
/// # local_contract_file,
117120
/// # session::Session,
118-
/// # session::{NO_ARGS, NO_SALT, NO_ENDOWMENT},
121+
/// # session::{ContractBundle, NO_ARGS, NO_SALT, NO_ENDOWMENT},
119122
/// # runtime::MinimalRuntime,
120-
/// # ContractBundle,
121123
/// # };
122124
///
123125
/// # fn main() -> Result<(), drink::session::error::SessionError> {

drink/src/bundle.rs renamed to drink/src/session/bundle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl ContractBundle {
7070
#[macro_export]
7171
macro_rules! local_contract_file {
7272
() => {
73-
drink::ContractBundle::local(
73+
drink::session::ContractBundle::local(
7474
env!("CARGO_MANIFEST_DIR"),
7575
env!("CARGO_CRATE_NAME").to_owned() + ".contract",
7676
)

drink/src/mock.rs renamed to drink/src/session/mock.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
//! Mocking utilities for contract calls.
2+
13
mod contract;
24
mod error;
3-
5+
mod extension;
46
use std::collections::BTreeMap;
57

68
pub use contract::{mock_message, ContractMock, MessageMock, Selector};
79
use error::MockingError;
10+
pub(crate) use extension::MockingExtension;
811

912
/// Untyped result of a mocked call.
1013
pub type MockedCallResult = Result<Vec<u8>, MockingError>;

drink/src/mock/contract.rs renamed to drink/src/session/mock/contract.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use parity_scale_codec::{Decode, Encode};
44

55
use crate::{
66
errors::LangError,
7-
mock::{error::MockingError, MockedCallResult},
7+
session::mock::{error::MockingError, MockedCallResult},
88
};
99

1010
/// Alias for a 4-byte selector.

drink/src/mock/error.rs renamed to drink/src/session/mock/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use thiserror::Error;
22

3-
use crate::Selector;
3+
use crate::session::mock::Selector;
44

55
/// Error type for mocking operations.
66
#[derive(Error, Debug)]
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use std::sync::{Arc, Mutex};
2+
3+
use pallet_contracts::{debug::ExecResult, ExecReturnValue};
4+
use pallet_contracts_uapi::ReturnFlags;
5+
use parity_scale_codec::{Decode, Encode};
6+
7+
use crate::{
8+
errors::MessageResult,
9+
runtime::pallet_contracts_debugging::InterceptingExtT,
10+
session::mock::{MockRegistry, Selector},
11+
};
12+
13+
/// Runtime extension enabling contract call interception.
14+
pub(crate) struct MockingExtension<AccountId: Ord> {
15+
/// Mock registry, shared with the sandbox.
16+
///
17+
/// Potentially the runtime is executed in parallel and thus we need to wrap the registry in
18+
/// `Arc<Mutex>` instead of `Rc<RefCell>`.
19+
pub mock_registry: Arc<Mutex<MockRegistry<AccountId>>>,
20+
}
21+
22+
impl<AccountId: Ord + Decode> InterceptingExtT for MockingExtension<AccountId> {
23+
fn intercept_call(
24+
&self,
25+
contract_address: Vec<u8>,
26+
_is_call: bool,
27+
input_data: Vec<u8>,
28+
) -> Vec<u8> {
29+
let contract_address = Decode::decode(&mut &contract_address[..])
30+
.expect("Contract address should be decodable");
31+
32+
match self
33+
.mock_registry
34+
.lock()
35+
.expect("Should be able to acquire registry")
36+
.get(&contract_address)
37+
{
38+
// There is no mock registered for this address, so we return `None` to indicate that
39+
// the call should be executed normally.
40+
None => None::<()>.encode(),
41+
// We intercept the call and return the result of the mock.
42+
Some(mock) => {
43+
let (selector, call_data) = input_data.split_at(4);
44+
let selector: Selector = selector
45+
.try_into()
46+
.expect("Input data should contain at least selector bytes");
47+
48+
let result = mock
49+
.call(selector, call_data.to_vec())
50+
.expect("TODO: let the user define the fallback mechanism");
51+
52+
// Although we don't know the exact type, thanks to the SCALE encoding we know
53+
// that `()` will always succeed (we only care about the `Ok`/`Err` distinction).
54+
let decoded_result: MessageResult<()> =
55+
Decode::decode(&mut &result[..]).expect("Mock result should be decodable");
56+
57+
let flags = match decoded_result {
58+
Ok(_) => ReturnFlags::empty(),
59+
Err(_) => ReturnFlags::REVERT,
60+
};
61+
62+
let result: ExecResult = Ok(ExecReturnValue {
63+
flags,
64+
data: result,
65+
});
66+
67+
Some(result).encode()
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)