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

Properly fold results #381

Closed
wants to merge 8 commits into from
Closed

Properly fold results #381

wants to merge 8 commits into from

Conversation

ethanfrey
Copy link
Member

This shows an issue coming up with multi-test

If the top-level has a reply statement, it may return a new data to over-ride what was previously set with execute / instantiate / migrate.

However, if the submessage returns a result, but we don't set the data in reply, it must not override the top level reply.

This has lead to improper contract data being returned in some cases (one instantiate calls another instantiate, the second data is returned on the top level).

My "quick fix" here broke the reply-set-data functionality completely, and it seems a bit tricky to address. There is a broken test case however that should show a working solution when it passes.

@hashedone I'd be happy if you take a look and push to this branch if you see fit.

@hashedone hashedone force-pushed the properly-fold-results branch 3 times, most recently from a32b64f to c82285a Compare August 9, 2021 18:36
@hashedone
Copy link
Contributor

I tested also #36 with this change, seems to be working.

@hashedone hashedone marked this pull request as ready for review August 9, 2021 19:02
@@ -512,7 +512,12 @@ where
let subres =
self.execute_submsg(api, router, storage, block, contract.clone(), resend)?;
events.extend_from_slice(&subres.events);
Ok::<_, String>(subres.data.or(data))

if data.is_some() {
Copy link
Member Author

Choose a reason for hiding this comment

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

This may cover the test cases, but is not the general solution we need.
It still makes no distinction between data returned in the sub message execute and in the reply processing submessage execute

Copy link
Contributor

Choose a reason for hiding this comment

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

It does, just not in this very place. execute_submsg is modified, so it doesn't return data at all if reply was not executed, as in such a case those data are never to be used. At some point I even added checking for ReplyOn here, but when went deeper in this I realized it doesn't make sense - the logic behind deciding if reply is to be executed doesn't belong here, instead if there is no reply, then what is visible from execute_submsg should actually match what we expect - no data is set (as in such a case also wasmd implementation does not process this result in any way).

contract.clone(),
&echo::Message {
data: Some("First".to_owned()),
sub_msg: vec![make_echo_submsg_no_reply(contract, "Second", vec![])],
Copy link
Member Author

Choose a reason for hiding this comment

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

This does look like it passes. Hmm...

@@ -389,28 +389,26 @@ where
});

// call reply if meaningful
if let Ok(r) = res {
if let Ok(mut r) = res {
Copy link
Contributor

Choose a reason for hiding this comment

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

This if-let implementation was actually root cause of the problem. Previously when there was a submsg response received, but no reply was called, replay was returned including data received from submsg execution. It does not make sense, as submsg execution result is not propagated directly, it is only send to reply handled and forget, those in case when there is response from submsg, but no reply is called, Ok(None) is now returned here.

@ethanfrey
Copy link
Member Author

I think there is still errors here.

Please look at #384. It is a minimal change (building off lots of tests from other PRs). It fixes all tests and solves the issue. But I think it is a bit ugly.

@hashedone
Copy link
Contributor

hashedone commented Aug 10, 2021

This is strict equivalent of my change. I am pretty sure that you missed that I also altered execute_submsg function, but except of adding additional side result (which I agree is bad solution), I altered data to be None if reply is not called. I don't say that this is 100% bug free, but with this claim if you think there is a scenario it doesnt cover, please explain me it and I will write test to prove it covers it (or I will find a bug and correct the bug, but I am sure that in such case #348 would also fail as well as it is equivalent).

The only actual difference is, that you overwrite data on the one from reply also in case, when original message returned None, which you strictly wanted me not to happen. It that is proper behaviour, then just one line is to be changed (I just commited it so now those changes are actually equivalents).

@ethanfrey
Copy link
Member Author

Closing in favour of #385 and #383

@ethanfrey ethanfrey closed this Aug 10, 2021
@ethanfrey ethanfrey deleted the properly-fold-results branch August 10, 2021 09:09
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.

2 participants