-
Notifications
You must be signed in to change notification settings - Fork 1.7k
EIP-116 (214), #4833 #4851
EIP-116 (214), #4833 #4851
Conversation
ethcore/src/evm/interpreter/mod.rs
Outdated
instruction: instruction | ||
}); | ||
} | ||
|
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.
after looking at Arkadiy eip86, I guess this should be under verify_instruction
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.
Couple of issues noted.
Also one thing bothers me:
I think currently STATICCALL
will kill empty accounts when it touches them - that is arguably a state alteration. Since we don't allow empty accounts to be created any more it shouldn't cause a problem if there are no empty accounts already existing on chain, but nevertheless I think we should either avoid killing empty accounts in such case or clarify that in the specification.
ethcore/src/client/test_client.rs
Outdated
@@ -352,7 +352,7 @@ pub fn get_temp_state_db() -> GuardedTempResult<StateDB> { | |||
|
|||
impl MiningBlockChainClient for TestBlockChainClient { | |||
fn latest_schedule(&self) -> Schedule { | |||
Schedule::new_post_eip150(24576, true, true, true) |
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.
IMHO this is reaching a point where a struct would look much better than the 4 boolean flags.
Schedule::new_post_eip150(PostEip150 {
max_code_size: 24576,
fix_exp: true,
no_empty: true,
kill_empty: true,
static_call: true,
});
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 change that after #4697 is merged, cause includes the same changes
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.
ethcore/src/evm/ext.rs
Outdated
@@ -94,15 +94,15 @@ pub trait Ext { | |||
fn extcodesize(&self, address: &Address) -> trie::Result<usize>; |
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.
Shouldn't all functions here return evm::Result
instead of trie::Result
?
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 agree, it visually looks better 👍
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.
Really it should be an associated type Error
. Externalities are lower level than the machine itself, so it doesn't make that much sense to return an evm::Result
there.
ethcore/src/executive.rs
Outdated
@@ -253,13 +259,17 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { | |||
// backup used in case of running out of gas | |||
self.state.checkpoint(); | |||
|
|||
trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); | |||
if (params.call_type == CallType::StaticCall || self.static_flag) && params.value.value() > 0.into() { | |||
return Err(evm::Error::MutableCallInStaticContext); |
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.
Two issues:
- Shouldn't such calls be traced anyway?
- Seems that
state.checkpoint
is being made, but since we are notenacting_result
it will not be reverted, is that correct?
ethcore/src/executive.rs
Outdated
@@ -359,6 +369,10 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { | |||
// backup used in case of running out of gas | |||
self.state.checkpoint(); | |||
|
|||
if params.call_type == CallType::StaticCall || self.static_flag { | |||
return Err(evm::Error::MutableCallInStaticContext); |
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.
Same issues with tracing and state.checkpoint()
@@ -292,14 +292,21 @@ impl<Cost: CostType> Interpreter<Cost> { | |||
} | |||
}; | |||
}, | |||
instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL => { | |||
instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL | instructions::STATICCALL => { |
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 seems that gas calculation for staticcall
is not implemented (I suppose it should be the same as for 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 for pointing that out!
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.
imo, it actually should be the same as DELEGATECALL
, since we are not creating new accounts, nor transfering value
@@ -23,6 +23,7 @@ | |||
"maximumExtraDataSize": "0x20", | |||
"minGasLimit": "0x1388", | |||
"networkID" : "0x1", | |||
"eip116Transition": "0x7fffffffffffff", |
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.
stick to 0x7fffffffffffffff
for consistency
@@ -23,6 +23,7 @@ | |||
"maximumExtraDataSize": "0x20", | |||
"minGasLimit": "0x1388", | |||
"networkID" : "0x1", | |||
"eip116Transition": "0x7fffffffffffff", |
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.
as above
ethcore/src/evm/interpreter/mod.rs
Outdated
stack.pop_back(); | ||
let call_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is one of `CALL`/`CALLCODE`/`DELEGATECALL`; qed"); | ||
let code_address = stack.pop_back(); | ||
let code_address = u256_to_address(&code_address); | ||
|
||
let value = if instruction == instructions::DELEGATECALL { | ||
let value = if instruction == instructions::DELEGATECALL || instruction == instructions::STATICCALL { |
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.
double
after ==
ethcore/src/executive.rs
Outdated
@@ -250,6 +256,13 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { | |||
tracer: &mut T, | |||
vm_tracer: &mut V | |||
) -> evm::Result<U256> where T: Tracer, V: VMTracer { | |||
trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); | |||
if (params.call_type == CallType::StaticCall || self.static_flag) && params.value.value() > 0.into() { |
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.
params
are for this call, no? in which case, if this call type is StaticCall
(or DelegateCall
, for that matter) then it should be fine even if it is a static context (static_flag == true
)
@tomusdrw we'll have to see how the yellow paper prefers it. i think it'll end up being easier to consider |
@gavofyork touching accounts has been already clarified -> ethereum/EIPs#214 (comment)
|
edba366
to
debc1e2
Compare
pub fn apply_params(&mut self, block_number: u64, params: &CommonParams) { | ||
self.have_create2 = block_number >= params.eip86_transition; | ||
self.have_revert = block_number >= params.eip140_transition; | ||
self.have_static_call = block_number >= params.eip214_transition; |
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.
nice, this is better than have_metropolis_instructions
self.state.set_storage(&self.origin_info.address, key, value) | ||
fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { | ||
if self.static_flag { | ||
Err(evm::Error::MutableCallInStaticContext) |
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 would be interesting if the static mode just had immutable references so mutable calls could literally not be made -- but this works too.
LGTM, but tests would be nice. |
self.have_revert = block_number >= params.eip140_transition; | ||
self.have_static_call = block_number >= params.eip214_transition; | ||
if block_number >= params.eip210_transition { | ||
self.blockhash_gas = 350; |
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 think the new gas cost is 800. https://github.com/ethereum/EIPs/pull/210/files#diff-e02a92c2fb96c1a1bfb05e4c6e2ef5daR42
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, added to #5855
Everything should be working, but there are no tests. Opened a pr to test all existing tests && to get second pair of eyes on this code.
side-notes, executive / externalities types need to be decoupled from ipc types. I got the impression that some global imports are misused and it's quite annoying