-
Notifications
You must be signed in to change notification settings - Fork 458
Implement ext_call in ink! #133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All in all looks decent.
However, you should note that this is a fairly low-level API to what you want to do.
For ink! we had in mind to support a more high-level approach to solve the underlying problem.
For the high-level parts we also need the low-level parts such as implemented in your PR so if you need it I am fine to merge the PR after some minor improvements (also docs are missing).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the gas generic type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should simply rebase to master, not do a merge commit. I suggest you to rewind and do a simple rebase.
Codecov Report
@@ Coverage Diff @@
## master #133 +/- ##
==========================================
- Coverage 79.54% 79.41% -0.13%
==========================================
Files 67 67
Lines 4986 4994 +8
==========================================
Hits 3966 3966
- Misses 1020 1028 +8
Continue to review full report at Codecov.
|
I implemented ReturnData as trait because implementation of get() differs between srml and test_env |
@Robbepop |
Sorry, I forgot to push my latest code review for your PR and was already wondering why you don't react. Let me elaborate a bit more on the idea I stated in a comment above about splitting the There currently is a problem with the proposed API that Also the proposed work around with the additional guard type that you already implemented is not working properly either due to the stated problems with in-between-calls. The idea to fix this is splitting this API up into two parts:
I am sorry for causing more work than necessary but we want to get this right and I think this is the way to go. |
Please rebase this on current |
model/src/exec_env.rs
Outdated
|
||
/// Calls a remote smart contract and return access to scratch buffer | ||
pub fn call_evaluate<U:Decode>( | ||
&self, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here: &mut self
Hey how is it going with this PR? |
@Robbepop Sorry for being late, i was busy for my job. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please incorporate my suggestions into your PR and run rustfmt
over it - many formatting errors.
core/src/env/traits.rs
Outdated
) -> Result<(), Self::CallError>; | ||
|
||
/// Calls a remote smart contract and return encoded data | ||
#[must_use] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are using Result
as return type we can remove this #[must_use]
again since Result
is #[must_use]
on a type level already.
core/src/env/srml/srml_only/impls.rs
Outdated
@@ -107,6 +112,8 @@ impl<T> Env for SrmlEnv<T> | |||
where | |||
T: EnvTypes, | |||
{ | |||
type CallError = CallError; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not want to introduce an associated type for CallError
at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have any idea where to implement CallError struct?
I want to use same struct in core/src/env/* and in model/src/exec_env.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since ink_model
depends on ink_core
just define it in ink_core
in ink_core::env
and use it from ink_model
.
core/src/env/test_env.rs
Outdated
input_data: &[u8], | ||
) -> Result<T,CallError> { | ||
add_call(callee, gas, value, input_data); | ||
unimplemented!(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unimplemented!(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see why you left it there. The returning of this is a bit more involved.
What I would recommend doing is the following:
Create another field in the test environment data (Vec<u8>
) that is settable by the user and that is actually taken upon calling call
to decode into the expected T
. So upon testing a smart contract using the test environment a tester can completely control it and say what it expects from the outside.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it!
Also, i need to check error of call
. Should i add a field of error flag?
Now it can catch only the decoding error, but cant catch error while executing call
.
lang/src/encode_input_data.rs
Outdated
use ink_utils; | ||
use parity_codec::Encode; | ||
|
||
pub trait EncodeSafe{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not idiomatic to do that and confusing. Please find another way to test this functionality. You are free to make limited use of macro_rules! macros in order to provide the functionality of your tests if required.
@taskooh we are about to implement a more elaborate version of this feature. For this we want to base our work on your PR, however, this requires the last remaining work done by you, otherwise we cannot merge it. We do not want to throw away all the work done by you so far. ;) |
…xt_call remove #[allow(unused)] from ext_call() implment call_invoke and call_evaluate fix format call_invoke and call_evaluate returns Return<_,CallError> fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please apply my code suggestions and remove the one test file I mentioned.
also it is important that you fix the things I mentioned in your current TestEnvData::call
implementation -> it is still calling unimplemented!()
.
rest looks O.K.
core/src/env/test_env.rs
Outdated
@@ -47,6 +50,15 @@ impl EventData { | |||
} | |||
} | |||
|
|||
/// Emulates the data given to remote smart contract call instructions. | |||
#[allow(unused)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why would you need #[allow(unused)]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Errors occurred:
error: field is never used: `callee`
--> core/src/env/test_env.rs:55:5
|
55 | callee: Vec<u8>,
| ^^^^^^^^^^^^^^^
|
note: lint level defined here
--> core/src/lib.rs:42:2
|
42 | unused,
| ^^^^^^
= note: #[deny(dead_code)] implied by #[deny(unused)]
error: field is never used: `gas`
--> core/src/env/test_env.rs:56:5
|
56 | gas: u64,
| ^^^^^^^^
error: field is never used: `value`
--> core/src/env/test_env.rs:57:5
|
57 | value: Vec<u8>,
| ^^^^^^^^^^^^^^
error: field is never used: `input_data`
--> core/src/env/test_env.rs:58:5
|
58 | input_data: Vec<u8>,
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the fields pub
so that they are accessible from the outside. ;)
@Robbepop @ascjones Is the |
core/src/env/test_env.rs
Outdated
@@ -47,6 +50,15 @@ impl EventData { | |||
} | |||
} | |||
|
|||
/// Emulates the data given to remote smart contract call instructions. | |||
#[allow(unused)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the fields pub
so that they are accessible from the outside. ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general looks good. Though as I say in the comment I would move call_invoke
and call_evaluate
up to model::EnvHandler
I wanna call another contract in a contract.
Is this the right approach to do that?