-
Notifications
You must be signed in to change notification settings - Fork 27
Test that a panic in actor code results in undefined execution #87
Comments
FYI @Stebalien. |
@anorth mind scoring? Usual drill (pick a discomfort factor, remove the needs-scoring label, unassign yourself). Thanks! |
I believe the panic is currently caught and an exit status of 1 is recorded. |
This one is pretty bad: it will lead to a fork (though probably one localised to one miner). |
@alanshaw here's another 9! Should jump the queue from the 8's you had planned. |
@alanshaw as @anorth duly points out, this is gonna be rather tricky because there is no exit code associated with this. Rather, we expect the VM to return an error. Right now, test vectors don't record internal errors that are exogenous to the protocol, as these are implementation specific. One way of doing this is recording an empty receipt in the vector, which the driver would interpret as an error. WDYT? |
As we discussed in the colo, I had an idea for recording the error in a separate section of the postconditions to the // 3 messages to apply but the 3rd causes a panic and fails entirely, with no receipt.
"apply_messages": [
{ "bytes": "...", "epoch": 0 },
{ "bytes": "...", "epoch": 0 },
{ "bytes": "...", "epoch": 0 }
],
"postconditions": {
// Indexes into the apply_messages array, identifying which message(s) failed entirely, with no receipt.
"apply_message_failures": [2],
// Receipts as usual, in this case we'll have just 2.
"receipts": [/* ... */],
} The idea is that the driver could verify exactly which message(s) failed to be applied. There's probably no value in recording things like error messages since this will be implementation dependent. The driver could also verify the receipts for messages that did apply successfully (although see open questions below). We need to use an index into the The questions I have are:
For completeness, here's some reasons for not using an empty receipt in the
|
Agree.
Agree.
Agree with all these points. Conclusion: ship it! 🚀cc @austinabell As discussed on Slack! |
Yeah I would say all is valid reasoning, lgtm. I would say that I don't think that having an array of invalid indexes and an incomplete receipt list is just as unintuitive as having a nullable receipt. I just think the benefit to having a null or even putting a string error in place of the receipt (can go deserialization do this easily of having a data type of two variants?) is that the indexes will match the message indexes, and otherwise would be confusing. Doesn't matter just sharing thoughts. Question I have is: can there be more than one error or have the error as the non-last message? iirc the VM execution states something like if the error if fatal, then the resulting state is undefined and shouldn't be used. There won't be a functional issue for us, but would this potentially be testing functionality or hit an edge case that cannot happen on a network? No harm in trying I guess, just thinking out loud |
I think @austinabell has a point as well. Is there a hybrid that could be best-of-both-worlds here? I'm thinking:
|
I agree also, for some reason I didn't consider a |
If an actor implementation panics directly (rather than calling Abortf) then the evaluation is undefined. There is no exit code corresponding to this. The result should not go on chain. A panic (which could also come from some actor dependency) may indicate a transient state or error that cannot be replicated by other nodes and thus cannot form part of consensus. E.g. an out-of-memory.
Test that when an actor panics, the VM indicates this by some kind of failure that is distinguished from an Abortf and has no risk of going on chain.
This could be a little tricky, and implementation specific.
The text was updated successfully, but these errors were encountered: