Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

[Trace] Distinguish between create and create2 #11311

Merged
merged 15 commits into from
Jan 13, 2020

Conversation

fleupold
Copy link
Contributor

@fleupold fleupold commented Dec 6, 2019

Closes #10922 and implements the approach suggested by @tomusdrw.

This PR introduces a new field on the Create struct in the trace module. This allows differentiating between create and create2 contract deployments. The information comes from the exec_instruction method inside the ethcore interpreter module (there we have access to the low level OpCode).

It's then passed on via the ActionType enum (previously CallType) on the ActionParams struct, and eventually translated into the trace object.

It looks like at the moment CREATE opcodes are stored as CallType::None. I therefore reused this subtype (persisted as 0u32) and added a new one for CREATE2.

Test plan

  1. Checkout master (not this PR), compile and run private test chain
./target/debug/parity --config dev --tracing=on --unlock="0x00a329c0648769a73afac7f9381e08fb43dbea72" --password=./password
  1. Checkout this test repo with a simple deploy2 factory
    • npm ci
    • make deploy
    • make test (capture block number that is printed)
  2. Get trace of that block
curl -w "\n" -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"trace_replayBlockTransactions","params":["<block_number>",["trace"]],"id":67}' http://localhost:8545 | python -m json.tool
  1. See no creation type in json output
  2. Checkout this PR, build and run on same private chain
  3. Rerun the rpc call with the same block number
  4. Now observe "create_type": "create2", in output
  5. The trace of block_number - 1 should have a "create_type": "create",
  6. Same will work if you run make test again

@parity-cla-bot
Copy link

It looks like @fleupold hasn't signed our Contributor License Agreement, yet.

The purpose of a CLA is to ensure that the guardian of a project's outputs has the necessary ownership or grants of rights over all contributions to allow them to distribute under the chosen licence.
Wikipedia

You can read and sign our full Contributor License Agreement at the following URL: https://cla.parity.io

Once you've signed, please reply to this thread with [clabot:check] to prove it.

Many thanks,

Parity Technologies CLA Bot

@parity-cla-bot
Copy link

It looks like @fleupold signed our Contributor License Agreement. 👍

Many thanks,

Parity Technologies CLA Bot

@dvdplm dvdplm added A0-pleasereview 🤓 Pull request needs code review. B0-patch-stable 🕷 Pull request should also be back-ported to the stable branch. B1-patch-beta 🕷🕷 M4-core ⛓ Core client code / Rust. labels Dec 6, 2019
@dvdplm dvdplm requested a review from sorpaas December 6, 2019 16:03
Copy link
Collaborator

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, a few improvements that we could do though.

ethcore/machine/src/externalities.rs Outdated Show resolved Hide resolved
ethcore/trace/src/types/trace.rs Outdated Show resolved Hide resolved
ethcore/wasm/src/runtime.rs Outdated Show resolved Hide resolved
rpc/src/v1/types/trace.rs Outdated Show resolved Hide resolved
rpc/src/v1/types/trace.rs Outdated Show resolved Hide resolved
rpc/src/v1/types/trace.rs Outdated Show resolved Hide resolved
@@ -89,7 +89,7 @@ pub struct ActionParams {
/// Input data.
pub data: Option<Bytes>,
/// Type of call
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs here could be more helpful maybe?

ethcore/trace/src/types/trace.rs Outdated Show resolved Hide resolved
@@ -122,6 +124,7 @@ impl From<ActionParams> for Create {
value: p.value.value(),
gas: p.gas,
init: p.code.map_or_else(Vec::new, |c| (*c).clone()),
create_type: p.call_type,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads a bit awkwardly imo, "is it a create type or a call type?", so maybe it should be renamed action_type in ActionParams?

@@ -130,7 +130,7 @@ impl From<ethjson::vm::Transaction> for ActionParams {
gas: t.gas.into(),
gas_price: t.gas_price.into(),
value: ActionValue::Transfer(t.value.into()),
call_type: match address.is_zero() { true => CallType::None, false => CallType::Call }, // TODO @debris is this correct?
call_type: if address.is_zero() { ActionType::Create } else { ActionType::Call },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a dumb q but is it true that a vm::Transaction with a CREATE2 is indistinguishable from one with CREATE?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually not quite sure whether ActionType::Create is right here. The type json::vm::Transaction is for the legacy vmTests in jsontests. It should not deal with call/create, but only the internal execution of EVM, and thus, it should always be just plain ActionType::Call?

Anyway, I'm not entirely sure either, but it won't matter too much -- the legacy vmtests is in the process of being removed and we might be able to remove this function really soon!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what's the best way forward? Should I unconditionally use ActionType::Call or leave as is?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My recommendation is to unconditionally use ActionType::Call, because that is, based on my understanding, how vmtests works. (I would appreciate it if someone else can take a glance on this again, just in case if I'm wrong.)

Practically as long as we're passing all vmtests everything should be fine.

Copy link
Collaborator

@dvdplm dvdplm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm modulo minor documentation grumbles.

@@ -33,6 +33,56 @@ pub struct CallResult {
pub output: Bytes,
}

/// `Call` type
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can do better here. Please document what the CallType is and what it is used for.

@@ -51,6 +101,48 @@ impl CreateResult {
}
}

/// `Create` method
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// `Create` method
/// Distinguish between use of `CREATE` and `CREATE2` opcodes in an action.

@fleupold
Copy link
Contributor Author

@sorpaas would you be able to take another look?

@@ -130,7 +130,7 @@ impl From<ethjson::vm::Transaction> for ActionParams {
gas: t.gas.into(),
gas_price: t.gas_price.into(),
value: ActionValue::Transfer(t.value.into()),
call_type: match address.is_zero() { true => CallType::None, false => CallType::Call }, // TODO @debris is this correct?
action_type: if address.is_zero() { ActionType::Create } else { ActionType::Call },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still believe that ActionType::Create here may not be correct. All vmtests are raw VM calls.

@fleupold
Copy link
Contributor Author

fleupold commented Jan 3, 2020

@sorpaas Would you be able to take another look?

Copy link
Collaborator

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Looks good to me, I'd only add skip_serializing_if for creationMethod and it should be good to go!

}

impl CreationMethod {
fn maybe_new(action_type: ActionType) -> Option<Self> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of the fn maybe_new methods look more like they could be a TryFrom implementation, but I don't mind the current.

Just checked that it was me suggesting fn new() -> Option<Self> 😂

@@ -223,6 +223,8 @@ pub struct Create {
gas: U256,
/// Initialization code
init: Bytes,
// Create Type
creation_method: Option<CreationMethod>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we still add #[serde_skip_serializing_if="Option::is_none"]?

Copy link
Collaborator

@sorpaas sorpaas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after what @tomusdrw said!

@ordian ordian added this to the 2.7 milestone Jan 10, 2020
@ordian
Copy link
Collaborator

ordian commented Jan 10, 2020

cargo audit check is fixed #11378, merge with master after that PR is merged and we're good to go :)

@ordian ordian merged commit 87e1080 into openethereum:master Jan 13, 2020
@ordian
Copy link
Collaborator

ordian commented Jan 13, 2020

Thanks!

ordian added a commit that referenced this pull request Jan 30, 2020
dvdplm added a commit that referenced this pull request Jan 30, 2020
dvdplm added a commit that referenced this pull request Jan 30, 2020
dvdplm added a commit that referenced this pull request Jan 30, 2020
ordian pushed a commit that referenced this pull request Jan 30, 2020
* Revert "[Trace] Distinguish between `create` and `create2` (#11311)" (#11427)

This reverts commit 87e1080.

* Bump version

* Changelog

* Update publish-docker.sh (#11428)

Add :latest tag to building stable releases

Co-authored-by: s3krit <pugh@s3kr.it>
ordian added a commit that referenced this pull request Feb 4, 2020
dvdplm added a commit that referenced this pull request Feb 4, 2020
…pstream

* master:
  Avoid long state queries when serving GetNodeData requests (#11444)
  Cargo.lock: cargo update -p kvdb-rocksdb (#11447)
  rlp_derive: cleanup (#11446)
  chore: remove unused dependencies (#11432)
  update kvdb-rocksdb to 0.4 (#11442)
  Rough architecutre diagram. (#11396)
  ethjson: impl Copy for hash type wrapper (#11423)
  Remove dead bootnodes, add new geth bootnodes (#11441)
  goerli: replace foundation bootnode (#11433)
  Update publish-docker.sh (#11428)
  Revert "[Trace] Distinguish between `create` and `create2` (#11311)" (#11427)
dvdplm pushed a commit that referenced this pull request Feb 5, 2020
* rlp_derive: update syn & co

* rlp_derive: remove dummy_const

* rlp_derive: remove unused attirubutes

* rlp-derive: change authors

* rlp_derive: add rlp(default) attribute

* Revert "Revert "[Trace] Distinguish between `create` and `create2` (#11311)" (#11427)"

This reverts commit 5d4993b.

* trace: backwards compatible call_type and creation_method

* trace: add rlp backward compatibility tests

* cleanup

* i know, i hate backwards compatibility too

* address review grumbles
s3krit pushed a commit that referenced this pull request Feb 5, 2020
* rlp_derive: update syn & co

* rlp_derive: remove dummy_const

* rlp_derive: remove unused attirubutes

* rlp-derive: change authors

* rlp_derive: add rlp(default) attribute

* Revert "Revert "[Trace] Distinguish between `create` and `create2` (#11311)" (#11427)"

This reverts commit 5d4993b.

* trace: backwards compatible call_type and creation_method

* trace: add rlp backward compatibility tests

* cleanup

* i know, i hate backwards compatibility too

* address review grumbles
s3krit added a commit that referenced this pull request Feb 5, 2020
* update classic testnet bootnodes (#11398)

* update classic testnet bootnodes

* Update kotti.json

* Update kotti.json

* Update kotti.json

* Update mordor.json

* verification: fix race same block + misc (#11400)

* ethcore: fix race in verification

* verification: fix some nits

* verification: refactor err type `Kind::create`

* fix: tests

* address grumbles

* address grumbles: don't panic

* fix: export hardcoded sync format (#11416)

* fix: export hardcoded sync format

* address grumbles

* make tests compile with rustc_hex 2.0

* fix grumbles: impl LowerHex for encoded Header

* goerli: replace foundation bootnode (#11433)

* Remove dead bootnodes, add new geth bootnodes (#11441)

* update kvdb-rocksdb to 0.4 (#11442)

* Avoid long state queries when serving GetNodeData requests (#11444)

* Remove dead bootnodes, add new geth bootnodes

* More granular locking when fetching state
Finish GetDataNode requests early if queries take too long

* typo

* Use latest kvdb-rocksdb

* Cleanup

* Update ethcore/sync/src/chain/supplier.rs

Co-Authored-By: Andronik Ordian <write@reusable.software>

* Address review grumbles

* Fix compilation

* Address review grumbles

Co-authored-by: Andronik Ordian <write@reusable.software>

* rlp_derive: cleanup (#11446)

* rlp_derive: update syn & co

* rlp_derive: remove dummy_const

* rlp_derive: remove unused attirubutes

* rlp-derive: change authors

* Cargo.lock: cargo update -p kvdb-rocksdb (#11447)

* Cargo.lock: new lockfile format

Manual backport of #11448

* gcc to clang (#11453)

* gcc to clang

test
```
export CC="sccache "$CC
export CXX="sccache "$CXX
```
darwin build
```
CC=clang
CXX=clang
```

* darwin - > default clang

* Bump version and CHANGELOG.md

* chore: remove unused dependencies (#11432)

* fix: compiler warnings

* chore: remove unused dependencies

* Update CHANGELOG.md

* update Cargo.lock

* update CHANGELOG.md

* backwards compatible call_type creation_method (#11450)

* rlp_derive: update syn & co

* rlp_derive: remove dummy_const

* rlp_derive: remove unused attirubutes

* rlp-derive: change authors

* rlp_derive: add rlp(default) attribute

* Revert "Revert "[Trace] Distinguish between `create` and `create2` (#11311)" (#11427)"

This reverts commit 5d4993b.

* trace: backwards compatible call_type and creation_method

* trace: add rlp backward compatibility tests

* cleanup

* i know, i hate backwards compatibility too

* address review grumbles

* update CHANGELOG.md

* just to make sure we don't screw up this again (#11455)

* Update CHANGELOG.md

Co-authored-by: Talha Cross <47772477+soc1c@users.noreply.github.com>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: David <dvdplm@gmail.com>
Co-authored-by: Andronik Ordian <write@reusable.software>
Co-authored-by: Denis S. Soldatov aka General-Beck <general.beck@gmail.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-pleasereview 🤓 Pull request needs code review. B0-patch-stable 🕷 Pull request should also be back-ported to the stable branch. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

trace_replayBlockTransactions doesn't distinguish between create and create2
6 participants