-
Notifications
You must be signed in to change notification settings - Fork 353
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
Changes from 1 commit
4952a79
bd21de6
b18753f
dc0a106
15797ca
2440816
05512dd
549f3a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -389,28 +389,26 @@ where | |
}); | ||
|
||
// call reply if meaningful | ||
if let Ok(r) = res { | ||
if let Ok(mut r) = res { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, |
||
if matches!(reply_on, ReplyOn::Always | ReplyOn::Success) { | ||
let mut orig = r.clone(); | ||
let reply = Reply { | ||
id, | ||
result: ContractResult::Ok(SubMsgExecutionResponse { | ||
events: r.events, | ||
data: r.data, | ||
events: r.events.clone(), | ||
data: r.data.clone(), | ||
}), | ||
}; | ||
// do reply and combine it with the original response | ||
let res2 = self._reply(api, router, storage, block, contract, reply)?; | ||
// override data if set | ||
if let Some(data) = res2.data { | ||
orig.data = Some(data); | ||
} | ||
// override data | ||
r.data = res2.data; | ||
// append the events | ||
orig.events.extend_from_slice(&res2.events); | ||
Ok(orig) | ||
r.events.extend_from_slice(&res2.events); | ||
} else { | ||
Ok(r) | ||
r.data = None; | ||
} | ||
|
||
Ok(r) | ||
} else if let Err(e) = res { | ||
if matches!(reply_on, ReplyOn::Always | ReplyOn::Error) { | ||
let reply = Reply { | ||
|
@@ -508,11 +506,13 @@ where | |
let AppResponse { mut events, data } = response; | ||
|
||
// recurse in all messages | ||
let data = messages.into_iter().try_fold(data, |data, resend| { | ||
let data = messages.into_iter().try_fold(data, |data, submsg| { | ||
let subres = | ||
self.execute_submsg(api, router, storage, block, contract.clone(), resend)?; | ||
self.execute_submsg(api, router, storage, block, contract.clone(), submsg)?; | ||
|
||
events.extend_from_slice(&subres.events); | ||
|
||
// Data should be overwritten if and only if replay was actually called | ||
if data.is_some() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does, just not in this very place. |
||
Ok::<_, String>(subres.data.or(data)) | ||
} else { | ||
|
There was a problem hiding this comment.
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...