Skip to content
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

Implemented instantiate_contract() for integration testing environment #1963

Closed

Conversation

Helios-vmg
Copy link

Summary

  • [n] y/n | Does it introduce breaking changes?
  • [n] y/n | Is it dependant on the specific version of cargo-contract or pallet-contracts?

This PR implements instantiate_contract() for the integration testing environment. More specifically, it permits calling instantiate_contract() from inside contracts transparently, as if the contract was running on the blockchain, although the behavior is not 100% reproduced.

Description

  • A new function called set_contract_storage_test() was added to crates/env/src/api.rs. The function does nothing unless a feature is enabled, so existing contracts won't have their behavior changed. The function computes the storage key in an alternate way, based on a function pointer; this was necessary because the storage key is always being computed as 0 on integration. After computing the storage key, the function passes to set_contract_storage().
  • The contract code generator was modified to, in execute_dispatchable(), call set_contract_storage_test() after the call to the constructor CALLABLE. As previously mentioned, if the test_instantiate feature is not enabled the function does nothing, so the compiler will optimize the call away when targeting WASM.
  • return_value() was also implemented on the off-chain environment engine. When test_instantiation is enabled, an alternative return_value() is used that stores the encoded return value into key 0x0000000. This value may be retrieved later. Additionally, this alternative implementation returns (), instead of !.
  • A further modification was needed on execute_dispatchable() to avoid a compiler error when return_value() doesn't return !. When test_instantiate is enabled, An Ok(()) is added at the end of the function, thus allowing the test-case to proceed.
  • The files under crates/ink/src/reflect were moved to crates/env/src/reflect, as Env now needs some of those types in the instantiate_contract() implementation and it was otherwise impossible to avoid a circular dependence. The ink crate was updated to expose those types as before, so nothing changes for users of that crate.
  • A trait named ContractReverseReference was added to env. The trait just adds a Type type that links from ContractRef back to Contract. The code generator was also modified to generate the implementation for this trait. This was needed in the instantiate_contract() implementation, as the function only sees the ContractRef type, but it needs the Contract type to decode the serialized input buffer. This change also necessitated propagating some trait requirements, but these changes should be transparent to users.
  • My code follows the style guidelines of this project
  • I have added an entry to CHANGELOG.md
  • I have commented my code, particularly in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • Any dependent changes have been merged and published in downstream modules (N/A)

Other notes

To test a contract that uses instantiate_contract() in the off-chain environment, use cargo test --features test_instantiate.

@Helios-vmg
Copy link
Author

Regarding the build errors in the doc tests, I've been trying to resolve them, but it's difficult without any way to see the macro expansion. When I move the code inside the comments to an actual contract it compiles correctly. Is there any way to move forward with this? Can I mark the comments as no_compile and add equivalent integration tests to catch breaking changes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant