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

Cap maximum depth of incomplete type display #221

Merged
merged 4 commits into from
Jun 28, 2024

Conversation

apoelstra
Copy link
Collaborator

This limit may still be too high -- I think you can output a 2^64 sized type which will wreck any terminal. But at least it's finite now.

Every instance of _iter methods called on an incomplete type (in the types/ module anyway) now has a maximum depth on it, which should eliminate all the places where we might loop forever with incomplete types.

Fixes #177

// input type. Will fail trying to unify the input type with the unit type *before*
// doing the occurs check, putting an infinitely-sized type into the error variant.
// Check that this error type can be printed in finite space/time.
let mut iter = BitIter::from([0xc1, 0x07, 0x20, 0x30].iter().copied());
Copy link
Collaborator

Choose a reason for hiding this comment

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

50293ca This test case would be better maintainable if we wrote it in the human encoding. We should strive to remove all byte blobs from the code base.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll take a look, but our options for decoding ConstructNodes are pretty limited.

@@ -538,4 +538,18 @@ mod tests {
// I created this unit test by hand
assert_program_not_deserializable::<Core>(&[0xa9, 0x48, 0x00], &Error::NotInCanonicalOrder);
}

#[test]
fn regression_177_1() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

50293ca: Adding this test case before the infinite loop is fixed means that CI runs forever on this commit. @apoelstra Does your local CI have a timeout?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, lol, let me reorder the commits. I don't know if I have a timeout, but if I do, it is in exceess of an hour..

Copy link
Collaborator

@uncomputable uncomputable left a comment

Choose a reason for hiding this comment

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

868964a Looks great, but let's move the test commit to the back.

I originally wanted to do this but couldn't because we weren't capping
the depth of error bound prints. Now we are.
Our existing occurs-check loop iterates through an incomplete type using
the NoSharing sharing tracker. This means that for exponentially-sized
types, we will do exponentially many iterations, even though the types
by-construction have a linear-sized description (in the number of shared
nodes in the program).

What we want to do is use the InternalSharing sharing tracker, *but*
this tracker is too agressive about sharing: it will not repeat nodes at
all, while to do the occurs-check, we want to repeat nodes that occur
inside themselves.

Instead we just implement a pre-order iterator inline (it is very simple
and we don't really need the dag.rs abstractions), implementing exactly
the occurs-check that we need.
@apoelstra apoelstra force-pushed the 2024-06--infinite-loop branch from 868964a to 66b2ddb Compare June 27, 2024 14:13
@apoelstra
Copy link
Collaborator Author

Reordered commits and rewrote the regression test to use the human-readable encoding. Conveniently with the human-readable encoding I can test both the bind error and the occurs-check error at once, since it attempts to continue after the first error.

Copy link
Collaborator

@uncomputable uncomputable left a comment

Choose a reason for hiding this comment

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

ACK 66b2ddb

@uncomputable uncomputable merged commit 534ca30 into master Jun 28, 2024
27 checks passed
@uncomputable uncomputable deleted the 2024-06--infinite-loop branch June 28, 2024 20:25
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.

Infinite finalization loop
2 participants