-
Notifications
You must be signed in to change notification settings - Fork 33
SC: Support read only sync call #1404
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
Conversation
…ate modifying host functions with read_only_check
…y() in native actions to support both actions and sync calls
…easier to understand
| bool sync_call_context::is_read_only()const { | ||
| return flags & static_cast<uint64_t>(sync_call_flags::read_only); | ||
| // If caller is read-only, callee must be read only too | ||
| return (is_caller_read_only || has_field(flags, sync_call_flags::read_only)); |
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.
Why is is_caller_read_only not enough?
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.
It is not enough. The caller itself can be a regular non-read-only action or sync call, but the flags for the callee can request the next call is a read-only call.
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.
Thanks. I was not thinking of the case of a non-read-only making a read-only sync-call.
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.
ah sorry maybe it's just Friday but I'm still not understanding this reasoning. It makes sense that a read only action can only execute a read only sync call, and that a read only sync call can only execute a read only sync call. But it seems like that would be enforced at the time of dispatching the sync call, not here?
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.
Now all the enforcement is done by the host function wrappers.
This is for the cases that an action is read only, far away from it in the sync call sequence, say call_n. call_n's flag is not set; this does not mean call_n will modify the state. We should let call_n run and use the host function wrapper to make sure the state is not modified during call_n's execution.
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.
The is_read_only() will return true if any of the ancestor sync calls' flag is true or if the transaction itself is a read-only transaction. We use is_read_only() to print out the read_only flag in call traces.
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.
I will make sure the call traces flags are consistent when the two PRs are merged together.
Thanks to both of you.
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.
Oh, on the current call_trace branch, the read_only function does not look at the ancestors. But on the read_only brach, it does that. When the two PRs are merged, it will work as Matt expects.
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.
I don't think it works the way described because in #1333 the call trace is populated from the flags, not the is_read_only():
spring/libraries/chain/host_context.cpp
Lines 47 to 48 in 4fd5a8c
| const bool read_only = flags & static_cast<uint64_t>(sync_call_flags::read_only); | |
| trace.call_traces.emplace_back(get_sync_call_ordinal(), call_receiver, read_only, data); |
imo this is an unintuitive way to deal with this vs doing in execute_sync_call()
if(is_read_only())
EOS_ASSERT(read_only /*(from flags)*/, "only can do read only from read only");But if this is how you want it, then should make an issue about this problem so it isn't forgotten when the PRs are eventually merged
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.
…is currently a non-implemented function
|
I think to merge this PR as is. The renaming to force_read_only is to be done in #1408. |
is_read_only()to host_context class to support both read-only transactions and read-only sync calls.Resoles #1217