dfinity / motoko

Simple high-level language for writing Internet Computer canisters
Apache License 2.0
515 stars 97 forks source link

Investigate why reject callback is invoked on one-way sends #2681

Closed ggreif closed 3 years ago

ggreif commented 3 years ago

While testing #2663 I also looked into one-way sends and their reject semantics. I observed that the success callback wasn't called. To replay, revert 5b76ab1663b21c5dfcc383b77050f1a25c7b7fdd and change one of the ignoring_callback env to _faulting_callback env.

ggreif commented 3 years ago

I have added a bit of instrumentation in #2705. As of commit 51e6f4eecc99d26dbbb9adae1d2b7f8d268bf80e I get for ic-ref-run the following output:

oneway-cleanup: [tc] [comp] [comp-ref] [valid] [valid-ref] [ic-ref-run]
--- oneway-cleanup.ic-ref-run (expected)
+++ oneway-cleanup.ic-ref-run (actual)
@@ -0,0 +1,10 @@
+→ update create_canister(record {dnczaeh = null})
+← replied: (record {hymijyo = principal "cvccv-qqaaq-aaaaa-aaaaa-c"})
+→ update install_code(record {arg = blob ""; kca_xin = blob "\00asm\01\00\00\00\0…
+← replied: ()
+→ update go()
+debug.print: oneway_success!
+debug.print: oneway_fail!
+debug.print: canister trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: assertion failed at oneway-cleanup.mo:11.5-11.17"
+debug.print: (rejection) ABOUT TO FAULT
+← replied: ()

This shows that the success callback is not invoked for the oneway success case. Instead, in both cases the reject callback is invoked. But when answering the oneway_success, we don't find a rejection message (as opposed to oneway_fail, when we do).

So this remains strange. The callbacks are set up in the correct way, I wonder how the execution layer makes a distinction between oneway messages and regular async sends. ic-ref and drun both show the same overall behaviour. @nomeata any ideas where I could dig deeper?

ggreif commented 3 years ago

@crusso mysteries, mysteries... I wonder if we can enable some extra logging in the drun callback invocation path to figure out why the wrong guy is picked.

crusso commented 3 years ago

Doesn't the compiler use the same callback for both reply and reject when calling a oneway?

crusso commented 3 years ago

The execution engines doesn't distinguish between oneways and ordinary messages. We compile oneways by replying early.

ggreif commented 3 years ago

Okay, @crusso is correct: See https://github.com/dfinity/motoko/pull/2705#discussion_r681736206, closing.