-
Notifications
You must be signed in to change notification settings - Fork 148
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
Contract runtime in dylibs #1168
Conversation
@@ -16,7 +16,7 @@ pub enum SystemMessage { | |||
PinkLog { | |||
block_number: u32, | |||
contract: AccountId, | |||
in_query: bool, | |||
exec_mode: String, |
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.
This breaks the previous version of logserver.
37c320c
to
340b897
Compare
@@ -31,6 +31,7 @@ export const types: RegistryTypes = { | |||
payload: "Vec<u8>", | |||
deposit: "u128", | |||
transfer: "u128", | |||
estimating: "bool", |
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 set this field to true when estimating gas fee on the UI. @Leechael
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 order to implement this change, we will need to ensure that it is synced across all testnets.
7249022
to
08db6e9
Compare
@h4x3rotab Ready for review |
0f5b5d8
to
69c812c
Compare
A bit busy, but will review soon... |
@@ -350,7 +350,12 @@ export async function create({ | |||
id: dest, | |||
}, | |||
data: { | |||
InkMessage: inputData, | |||
InkMessage: { |
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.
May be related: #1159
Still haven't reviewed: system/mod.rs, pink.rs |
I've reviewed all the files. |
This PR turns pink runtime(the phat contract execution engine) into dynamic libraries.
The problem this PR solves
PRruntime can run ink contracts with an embedded substrate runtime with pallets-contracts enabled. However, PRuntime only ships with one version of the runtime in the binary. This is a problem because when we release new versions of the pruntime, the pink runtime will be updated as well. If transactions are executed in different versions of the pruntime, it is hard to guarantee the consistency of the state. It would likely result in a divergence of the state between different workers or a single worker replayed with different versions of pruntime. That would totally break down the whole system.
The solution
Therefore, we need to ship multiple versions of pink runtime with pruntime and make sure each transaction is always executed in the same version of the runtime no matter when and where it is executed.
Because it is difficult to compile multiple versions of the runtime in the same statically linked binary, we decided to turn the runtime into dynamic libraries. The pruntime will load different versions of the runtime dynamically at runtime.
Version management
We will bound multiple versions of pink runtime in a single pruntime distribution in future releases. The library filenames are postfixed with versions like:
libpink.so.1.0
. The version is set to1.0
for now.pruntime load different versions of the pink runtime library via
libc::dlopen
.Libraries with different versions are distinguished by their filenames and identified by the version number.
There is an on-chain configuration
PhalaFatContracts::PinkRuntimeVersion
to specify the active version of pink runtime to be used to create new clusters.Once a cluster is created, the version of the pink runtime won't be changed unless the cluster owner manually upgrades the runtime.
Cluster owners can upgrade the runtime by calling
System::upgrade_runtime(to_version)
in transaction. If the pruntime doesn't have the specified version of the runtime, it will panic with a message asking to upgrade the pruntime.Cross boundary calls ABI
To enable cross-boundary calls between the main binary and dynamic libraries, a C ABI is used due to the lack of a stable ABI in Rust. However, the v1 implementation uses the parity SCALE codec to encode and decode cross-call arguments, which results in inefficient argument copying and en/decoding. To improve efficiency, a more efficient cross-call ABI should be developed for future versions, especially if the SCALE codec becomes a performance bottleneck.
Rust memory allocator in dynamic libraries
By default, Rust std comes with a default allocator which uses the alloc APIs from libc. As a result, every dynamic library written in Rust will have its own allocator. This is not what we want because we have a common allocator in the main executable which have some metrices and statistics. If we use the default allocator, the statistics will be not accurate. So we make this allocator in the runtime and delegate the calls to the allocator in the main executable.
Other changes
A new field
estimating
is added to the contract querying API.It is used to indicate whether the query is for estimating gas usage. If it is, the contract will emulate a transaction execution environment in which some off-chain ext functions are disabled. Phat-UI should use this flag to estimate gas usage.
Only one cluster per worker is allowed.
We did allow multiple clusters per worker in the past, but it is not necessary and complicates the runtime code. It is removed in this PR and the corresponding info structures in the response of
get_info
are changed.The ability to push mq messages for a contract is removed.
Currently, no contract is using this feature. And it has some security concerns. It is removed in this PR. It needs a more secure design to be added back.
System contract upgrading
The system contract upgrading is done on the contract side now, using the
ink::env::set_code_hash
API. It was implemented in the runtime side in the past and is removed in this PR.