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

Implement chain extensions builtin #1305

Merged
merged 28 commits into from
May 11, 2023
Merged

Conversation

xermicus
Copy link
Contributor

Provide a builtin to call chain extensions. This is the building block for implementing more high level interfaces directly in Solidity.

xermicus and others added 10 commits May 4, 2023 11:19
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: xermicus <cyrill@parity.io>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: xermicus <cyrill@parity.io>
let success = binary
.builder
.build_int_compare(IntPredicate::EQ, ret, i32_zero!(), "ret");
binary.builder.build_conditional_branch(success, ok, done);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is supposed to happen if the return value from the syscall is not 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll return it to the caller

However now that I think of it, it might be better to just trap. One could come up with the idea to try-catch it, but according to the solidity docs this is only supposed to be used for external calls

Copy link
Contributor Author

@xermicus xermicus May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I don't know the reasoning behind that logic in instruction.rs. Is it guaranteed that we always stay in call or deploy and this return there will return from the contract? I'm not sure about this. I think we should just trap.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the behavior entirely. We should not trap or do anything on a non-zero return value. Instead, we should return this value back to the caller.

In the case of call_chain_extension, the return value being non-zero has no apparent meaning. It depends on the chain extensions concrete implementation. Hence we should just return it to the caller, as he should know how to handle this.

binary.builder.build_unconditional_branch(done);

binary.builder.position_at_end(done);
ret.into()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong. Why is the syscall return value returned and not the vector?

Copy link
Contributor Author

@xermicus xermicus May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? An int value is expected, a pointer won't work. I guessed that this int value is supposed to be the return code from the builtin.

The return value goes into the last argument to the builtin. Right above in this section, I store it there in the ok branch. I'm quite confident that I read the code correctly and implemented this builtin in the target accordingly. I mean the unit test passes, and out of curiosity I tried it out on a real substrate node with the fetch-rand chain extension example. It worked as expected.

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
@xermicus xermicus requested a review from seanyoung May 11, 2023 08:37
xermicus and others added 3 commits May 11, 2023 11:14
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: xermicus <cyrill@parity.io>
src/sema/builtin.rs Outdated Show resolved Hide resolved
src/sema/builtin.rs Outdated Show resolved Hide resolved
src/sema/builtin.rs Outdated Show resolved Hide resolved
tests/substrate.rs Outdated Show resolved Hide resolved
Signed-off-by: xermicus <cyrill@parity.io>
Signed-off-by: xermicus <cyrill@parity.io>
@xermicus xermicus requested a review from seanyoung May 11, 2023 10:41
xermicus and others added 3 commits May 11, 2023 12:43
Signed-off-by: xermicus <cyrill@parity.io>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Copy link
Contributor

@seanyoung seanyoung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!!

docs/language/builtins.rst Outdated Show resolved Hide resolved
Comment on lines 333 to 334
Instead, it's specific to each chain extension. Hence, before using this builtin,
you must make sure that the chain extension being called is compatible.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about replacing
Hence, before using this builtin, you must make sure that the chain extension being called is compatible.
with
Hence, when using this builtin, ensure that the chain extension is used in the correct way.

Copy link
Contributor Author

@xermicus xermicus May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This suggests that the chain extension function / ID of interest can be used in various ways, and the caller can do something about that, doesn't it? But this is not the case. Either the implementation of the chain extension adheres to this, or it doesn't. There is nothing you can do about it (unless your are also the author of the parachain runtime, but this is a bit of a stretch).

My main goal of this warning is to make contract authors to reconsider whether they know what they are doing. Calling into a chain extension that you're not 100% certain about what it does is a really, really bad idea anyways.

However I changed the wording slightly based on your comment, to try and make it more clear.

src/emit/substrate/target.rs Outdated Show resolved Hide resolved
src/emit/substrate/target.rs Outdated Show resolved Hide resolved
tests/substrate_tests/builtins.rs Outdated Show resolved Hide resolved
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
xermicus and others added 4 commits May 11, 2023 14:03
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
docs/language/builtins.rst Outdated Show resolved Hide resolved
src/sema/diagnostics.rs Outdated Show resolved Hide resolved
Co-authored-by: Lucas Steuernagel <38472950+LucasSte@users.noreply.github.com>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
@xermicus xermicus requested a review from LucasSte May 11, 2023 13:29
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
@xermicus xermicus merged commit e8cfb9a into hyperledger:main May 11, 2023
15 checks passed
@xermicus xermicus deleted the chain-extensions branch May 15, 2023 10:47
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.

None yet

3 participants