Output data (code) for creates.
This commit is contained in:
parent
7d93fa2533
commit
ab9b8c7bf3
@ -249,6 +249,8 @@ impl<'a> Executive<'a> {
|
|||||||
|
|
||||||
// part of substate that may be reverted
|
// part of substate that may be reverted
|
||||||
let mut unconfirmed_substate = Substate::new(substate.subtraces.is_some());
|
let mut unconfirmed_substate = Substate::new(substate.subtraces.is_some());
|
||||||
|
|
||||||
|
// transaction tracing stuff. None if there's no tracing.
|
||||||
let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_call(¶ms), self.depth));
|
let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_call(¶ms), self.depth));
|
||||||
let mut trace_output = trace_info.as_ref().map(|_| vec![]);
|
let mut trace_output = trace_info.as_ref().map(|_| vec![]);
|
||||||
|
|
||||||
@ -256,6 +258,7 @@ impl<'a> Executive<'a> {
|
|||||||
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::Return(output, trace_output.as_mut()))
|
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::Return(output, trace_output.as_mut()))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// if there's tracing, make up trace_info's result with trace_output and some arithmetic.
|
||||||
if let Some((TraceAction::Call(ref mut c), _)) = trace_info {
|
if let Some((TraceAction::Call(ref mut c), _)) = trace_info {
|
||||||
if let Some(output) = trace_output {
|
if let Some(output) = trace_output {
|
||||||
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, output));
|
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, output));
|
||||||
@ -295,14 +298,17 @@ impl<'a> Executive<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_create(¶ms), self.depth));
|
let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_create(¶ms), self.depth));
|
||||||
|
let mut trace_output = trace_info.as_ref().map(|_| vec![]);
|
||||||
let created = params.address.clone();
|
let created = params.address.clone();
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::InitContract)
|
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::InitContract(trace_output.as_mut()))
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((TraceAction::Create(ref mut c), _)) = trace_info {
|
if let Some((TraceAction::Create(ref mut c), _)) = trace_info {
|
||||||
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, created, vec![]));
|
if let Some(output) = trace_output {
|
||||||
|
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, created, output));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.enact_result(&res, substate, unconfirmed_substate, trace_info);
|
self.enact_result(&res, substate, unconfirmed_substate, trace_info);
|
||||||
|
@ -28,7 +28,7 @@ pub enum OutputPolicy<'a, 'b> {
|
|||||||
/// Used for message calls.
|
/// Used for message calls.
|
||||||
Return(BytesRef<'a>, Option<&'b mut Bytes>),
|
Return(BytesRef<'a>, Option<&'b mut Bytes>),
|
||||||
/// Init new contract as soon as `RETURN` is called.
|
/// Init new contract as soon as `RETURN` is called.
|
||||||
InitContract,
|
InitContract(Option<&'b mut Bytes>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transaction properties that externalities need to know about.
|
/// Transaction properties that externalities need to know about.
|
||||||
@ -213,7 +213,7 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
}
|
}
|
||||||
Ok(*gas)
|
Ok(*gas)
|
||||||
},
|
},
|
||||||
OutputPolicy::InitContract => {
|
OutputPolicy::InitContract(ref mut copy) => {
|
||||||
let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas);
|
let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas);
|
||||||
if return_cost > *gas {
|
if return_cost > *gas {
|
||||||
return match self.schedule.exceptional_failed_code_deposit {
|
return match self.schedule.exceptional_failed_code_deposit {
|
||||||
@ -221,6 +221,9 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
false => Ok(*gas)
|
false => Ok(*gas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle_copy(copy);
|
||||||
|
|
||||||
let mut code = vec![];
|
let mut code = vec![];
|
||||||
code.reserve(data.len());
|
code.reserve(data.len());
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -333,7 +336,7 @@ mod tests {
|
|||||||
let mut setup = TestSetup::new();
|
let mut setup = TestSetup::new();
|
||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
|
|
||||||
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
|
|
||||||
assert_eq!(ext.env_info().number, 100);
|
assert_eq!(ext.env_info().number, 100);
|
||||||
}
|
}
|
||||||
@ -342,7 +345,7 @@ mod tests {
|
|||||||
fn can_return_block_hash_no_env() {
|
fn can_return_block_hash_no_env() {
|
||||||
let mut setup = TestSetup::new();
|
let mut setup = TestSetup::new();
|
||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
|
|
||||||
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap());
|
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap());
|
||||||
|
|
||||||
@ -361,7 +364,7 @@ mod tests {
|
|||||||
env_info.last_hashes.push(test_hash.clone());
|
env_info.last_hashes.push(test_hash.clone());
|
||||||
}
|
}
|
||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
|
|
||||||
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap());
|
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap());
|
||||||
|
|
||||||
@ -373,7 +376,7 @@ mod tests {
|
|||||||
fn can_call_fail_empty() {
|
fn can_call_fail_empty() {
|
||||||
let mut setup = TestSetup::new();
|
let mut setup = TestSetup::new();
|
||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
|
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
|
||||||
@ -397,7 +400,7 @@ mod tests {
|
|||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
ext.log(log_topics, &log_data);
|
ext.log(log_topics, &log_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,7 +415,7 @@ mod tests {
|
|||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
ext.suicide(&refund_account);
|
ext.suicide(&refund_account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user