Call_context is used to track the correct call context that the memory, storage and stack ops are applied to.
struct CallContext {
msg_sender: EthAddress
gas_available: u256
gas_used_before_this_call: u256
// tells us if this transaction will throw or revert in the future
is_persistant: bool
is_static_call: bool
// a count of the number of storage updates that need to be undone.
revert_todo: u256
// This is the global counter minimum global counter that needs to be reverted.
gc_to_revert_to: u256
call_depth: u256
}
impl Commitable for CallContext {
fn commit(){
return (
msg_sender +
gas_available * r +
gas_used_before_this_call * r**2 +
is_persistant * r**3 +
is_static_call * r**4 +
revert_todo * r**5 +
gc_to_revert_to * r**6 +
call_depth * r**7
)
}
}
The call_context is a random linear combination of
r = hash(msg.sender .. last_call_context)
\(call\_context = msg.sender + gas\_available * r .. last\_call\_context *r ^5\)
Is a binary flag that tells us if this transaction will throw or revert in the future
Is a count of the number of storage updates that need to be undone.
This is the global counter minimum global counter that needs to be reverted.
When we reach reverts/throws we need to do two things
When we reach op
REVERT
, it is actually a special error case we should not only do above two things, but also refund left gas (other errors consume all left gas). See Q4 for all other errors.
han
TODO: Confirm this is all we need to check how far to revert ?
When we are applying storage updates if the is_persitant flag = 1 nothing happens. We apply them as is.
If it is_persistant == 0 we need to preapare to revert every storage write we do. This is done by counting every storage update that is done. We excute all sotrage update as they are defined in the smart contract. When we get to the point where the revert happens we undo all these updates.
We basically force the prover to show us todo_revert
storage writes that happened between gc
and gc_to_revert_to
.
To make this easier storage write bus mapping will contain the value before it was written and the value that was written. For each element in this list we set that storage value to the value_before for todo_revert
elements with gc
< = gc_to_revert_to
Does static call throw on state writes or does it let you make writes as long as they are not persistant ? Assuming it does not let you make writes if you do it throws. Would be good to confirm this
In
STATICCALL
, it reverts to snapshot and consumes allgas_available
when:
op
are able to modify state (SSTORE
,LOGX
,CREATEX
)CALL
with value
Reference
How does reverts get stopped does it just revert the current call or can it revert others ?
It reverts others too. See this example. The parent delegate calls to child, who later revert a call to grandchild. The child's revert reverts the grandchild's state but not the parent's.
How does throw get stopped ? Does it just revert everything until there is a tx with more gas left ?
throw
is justrevert
without keeping gas left, which is due to compiler's behavior (andthrow
is removed in solidity 0.5), they both useop
REVERT
in the end.
When any errors happen, it always reverts to the snapshot beforeCALL
,DELEGATECALL
,STATICCALL
, and only error due toREVERT
will keep thegas_available
, others just consume all given gas.
Should storage be seperated by only address instead of call cotext?
If we do multiple call to a child contract and change its storage, we need their storage to be continue, for example, contract A
tries to trigger B.counter++
multiple times, if we seperated them by different call context, the result won't be correct.
Yes
barryWhiteHat
If call context is only for seperatation (or namespacing) in state circuit, why not just use the gc
at CALL
?
In the call context now, I can see only gas_used_before_this_call
and gc_to_revert_to
are unique, others are easily to collide with other calls. For example, I can have two identical call to same child contract.
Call context is also used as a digest of parent call and last child call, so all the things we need to memorize should be inside call context.
When a call is going to end, we have an awkward situation to handle: callee doesn't explicitly halt (opcodes doesn't ended with STOP
, RETURN
, REVERT
), then evm will pad it with an explicit STOP
.
In each op_lookup(addr, pc, op)
(not sure if it's the function signature in you idea), we need prover to explicitly tell us if we should do the lookup or not. If we do, we lookup for correct op, otherwise we know it's padded STOP
and switch to parent context.
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing