Skip to content

Implemented contract instantiation and invocation for integration tests#1988

Merged
cmichi merged 43 commits intouse-ink:masterfrom
CoinFabrik:integration-tests-api-implementation
Jan 9, 2025
Merged

Implemented contract instantiation and invocation for integration tests#1988
cmichi merged 43 commits intouse-ink:masterfrom
CoinFabrik:integration-tests-api-implementation

Conversation

@Helios-vmg
Copy link
Copy Markdown
Contributor

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(), invoke_contract(), invoke_contract_delegate() and a few other functions for the integration testing environment. More specifically, it permits calling these functions from inside contracts transparently, as if the contract was running on the blockchain.

Description

  • The following off-chain API functions are implemented: instantiate_contract(), invoke_contract(), invoke_contract_delegate(), return_value(), code_hash(), set_code_hash(), own_code_hash().
  • Two additional, testing-only functions called get_return_value() and upload_code() were added. get_return_value() returns the value stored by the modified return_value() (see below). upload_code() simulates uploading the code of a contract to the blockchain and returns a code hash. The actual hash is based on the value of a function pointer, so no attempt is made to reproduce what the blockchain will produce.
  • 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.
  • When the test_instantiate feature is enabled, an alternative return_value() is used in the generated dispatch code that stores the encoded return value into key [0xFF_u8; 32]. This value is retrieved later to return it to the caller. 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 functions (for constructor as well as for message dispatch), thus allowing the test-case to proceed.
  • The files under crates/ink/src/reflect were moved to crates/primitives/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 crates were updated to expose the same types as before, so nothing changes for users.
  • It was necessary to add a small unsafe block in crates/env/src/engine/off_chain/mod.rs, to the OnInstance implementation for EnvInstance, to be able to return a mut reference while another mut reference was still borrowed, which was necessary because now that contract can invoke other contracts some API functions are called nested. This should be safe, as the object is in a TLS, so there's no possibility of undefined behavior arising from race conditions.
  • 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.
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?

Helios-vmg and others added 30 commits October 27, 2023 17:43
# Conflicts:
#	crates/env/src/lib.rs
#	crates/env/src/reflect/event.rs
#	crates/ink/codegen/Cargo.toml
Moved reflection, contract, arithmetic, and miscellaneous types from ink_env
to ink_primitives.
…tation

# Conflicts:
#	crates/engine/src/database.rs
@cmichi
Copy link
Copy Markdown
Collaborator

cmichi commented Nov 14, 2024

@Helios-vmg Could you merge master into your PR and resolve the conflicts?

…ation

# Conflicts:
#	CHANGELOG.md
#	crates/engine/src/database.rs
#	crates/env/Cargo.toml
#	crates/env/src/call/call_builder.rs
#	crates/env/src/call/create_builder.rs
#	crates/env/src/engine/off_chain/impls.rs
#	crates/env/src/engine/off_chain/mod.rs
#	crates/env/src/engine/on_chain/impls/pallet_contracts.rs
#	crates/env/src/lib.rs
#	crates/ink/codegen/Cargo.toml
#	crates/ink/macro/Cargo.toml
#	crates/primitives/Cargo.toml
@Helios-vmg
Copy link
Copy Markdown
Contributor Author

@cmichi Done. Some notes:
The following tests are failing, because they're failing on master as well:

  • /integration-tests/public/runtime-call-contract/sandbox-runtime/pallet-contract-caller/
  • /integration-tests/public/runtime-call-contract/
  • /integration-tests/public/static-buffer/
  • /integration-tests/public/contract-transfer/
  • /integration-tests/public/contract-terminate/
  • /integration-tests/public/payment-channel/

Likewise, running cargo test --all-features --workspace on the root is failing on master.
Finally, I will not be revisiting this in a year's time. If you guys don't merge this soon, you may as well just close the PR.

@cmichi cmichi merged commit c7de4c2 into use-ink:master Jan 9, 2025
@cmichi
Copy link
Copy Markdown
Collaborator

cmichi commented Jan 9, 2025

@Helios-vmg Thanks a lot for the PR and the merge of master. I'm sorry that it took that long. I'll see to fix the tests on master.

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.

3 participants