[stable] Backports (#8623)

* Fix account list double 0x display (#8596)

* Remove unused self import

* Fix account list double 0x display

* Trace precompiled contracts when the transfer value is not zero (#8486)

* Trace precompiled contracts when the transfer value is not zero

* Add tests for precompiled CALL tracing

* Use byzantium test machine for the new test

* Add notes in comments on why we don't trace all precompileds

* Use is_transferred instead of transferred

* Gitlab test script fixes (#8573)

* Exclude /docs from modified files.

* Ensure all references in the working tree are available

* Remove duplicated line from test script
This commit is contained in:
André Silva 2018-05-14 08:52:51 -05:00 committed by Afri Schoedon
parent 226a1d31b6
commit 39b9f1e252
3 changed files with 88 additions and 6 deletions

View File

@ -428,8 +428,14 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
self.state.discard_checkpoint();
output.write(0, &builtin_out_buffer);
// trace only top level calls to builtins to avoid DDoS attacks
if self.depth == 0 {
// Trace only top level calls and calls with balance transfer to builtins. The reason why we don't
// trace all internal calls to builtin contracts is that memcpy (IDENTITY) is a heavily used
// function.
let is_transferred = match params.value {
ActionValue::Transfer(value) => value != U256::zero(),
ActionValue::Apparent(_) => false,
};
if self.depth == 0 || is_transferred {
let mut trace_output = tracer.prepare_trace_output();
if let Some(out) = trace_output.as_mut() {
*out = output.to_owned();
@ -722,6 +728,12 @@ mod tests {
machine
}
fn make_byzantium_machine(max_depth: usize) -> EthereumMachine {
let mut machine = ::ethereum::new_byzantium_test_machine();
machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = max_depth));
machine
}
#[test]
fn test_contract_address() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
@ -814,6 +826,76 @@ mod tests {
assert_eq!(substate.contracts_created.len(), 0);
}
#[test]
fn test_call_to_precompiled_tracing() {
// code:
//
// 60 00 - push 00 out size
// 60 00 - push 00 out offset
// 60 00 - push 00 in size
// 60 00 - push 00 in offset
// 60 01 - push 01 value
// 60 03 - push 03 to
// 61 ffff - push fff gas
// f1 - CALL
let code = "60006000600060006001600361fffff1".from_hex().unwrap();
let sender = Address::from_str("4444444444444444444444444444444444444444").unwrap();
let address = Address::from_str("5555555555555555555555555555555555555555").unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.code_address = address.clone();
params.sender = sender.clone();
params.origin = sender.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from(100));
params.call_type = CallType::Call;
let mut state = get_temp_state();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default();
let machine = make_byzantium_machine(5);
let mut substate = Substate::new();
let mut tracer = ExecutiveTracer::default();
let mut vm_tracer = ExecutiveVMTracer::toplevel();
let mut ex = Executive::new(&mut state, &info, &machine);
let output = BytesRef::Fixed(&mut[0u8;0]);
ex.call(params, &mut substate, output, &mut tracer, &mut vm_tracer).unwrap();
assert_eq!(tracer.drain(), vec![FlatTrace {
action: trace::Action::Call(trace::Call {
from: "4444444444444444444444444444444444444444".into(),
to: "5555555555555555555555555555555555555555".into(),
value: 100.into(),
gas: 100_000.into(),
input: vec![],
call_type: CallType::Call
}),
result: trace::Res::Call(trace::CallResult {
gas_used: 33021.into(),
output: vec![]
}),
subtraces: 1,
trace_address: Default::default()
}, FlatTrace {
action: trace::Action::Call(trace::Call {
from: "5555555555555555555555555555555555555555".into(),
to: "0000000000000000000000000000000000000003".into(),
value: 1.into(),
gas: 66560.into(),
input: vec![],
call_type: CallType::Call
}), result: trace::Res::Call(trace::CallResult {
gas_used: 600.into(),
output: vec![]
}),
subtraces: 0,
trace_address: vec![0].into_iter().collect(),
}]);
}
#[test]
// Tracing is not suported in JIT
fn test_call_to_create() {

View File

@ -94,7 +94,7 @@ fn new(n: NewAccount) -> Result<String, String> {
let secret_store = Box::new(secret_store(dir, Some(n.iterations))?);
let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default());
let new_account = acc_provider.new_account(&password).map_err(|e| format!("Could not create new account: {}", e))?;
Ok(format!("0x{:?}", new_account))
Ok(format!("0x{:x}", new_account))
}
fn list(list_cmd: ListAccounts) -> Result<String, String> {
@ -103,7 +103,7 @@ fn list(list_cmd: ListAccounts) -> Result<String, String> {
let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default());
let accounts = acc_provider.accounts().map_err(|e| format!("{}", e))?;
let result = accounts.into_iter()
.map(|a| format!("0x{:?}", a))
.map(|a| format!("0x{:x}", a))
.collect::<Vec<String>>()
.join("\n");

View File

@ -7,8 +7,8 @@ if [[ "$CI_COMMIT_REF_NAME" = "beta" || "$CI_COMMIT_REF_NAME" = "stable" ]]; the
else
export GIT_COMPARE=master;
fi
export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ | wc -l)"
echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED"
git fetch -a
export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ -e ^docs/ | wc -l)"
echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED"
TEST_SWITCH=$1
rust_test () {