Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for golang tracers + add golang callTracer #558

Merged
merged 15 commits into from
Aug 6, 2024

Conversation

wgr523
Copy link
Collaborator

@wgr523 wgr523 commented Jun 17, 2024

Proposed changes

support for golang tracers + add golang callTracer

Types of changes

What types of changes does your code introduce to XDC network?
Put an in the boxes that apply

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update (if none of the other choices apply)
  • Regular KTLO or any of the maintaince work. e.g code style
  • CICD Improvement

Impacted Components

Which part of the codebase this PR will touch base on,

Put an in the boxes that apply

  • Consensus
  • Account
  • Network
  • Geth
  • Smart Contract
  • External components
  • Not sure (Please specify below)

Checklist

Put an in the boxes once you have confirmed below actions (or provide reasons on not doing so) that

  • This PR has sufficient test coverage (unit/integration test) OR I have provided reason in the PR description for not having test coverage
  • Provide an end-to-end test plan in the PR description on how to manually test it on the devnet/testnet.
  • Tested the backwards compatibility.
  • Tested with XDC nodes running this version co-exist with those running the previous version.
  • Relevant documentation has been updated as part of this PR
  • N/A

@wgr523
Copy link
Collaborator Author

wgr523 commented Jun 17, 2024

This PR's XXX_legacy.js tracers are not completely equal to XXX.js tracers before this PR. Shall we make XXX_legacy.js equal to prior XXX.js?

@@ -99,14 +100,19 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation,
}
}
// Make sure we don't exceed uint64 for all data combinations
if (math.MaxUint64-gas)/params.TxDataNonZeroGas < nz {
return 0, vm.ErrOutOfGas
Copy link

Choose a reason for hiding this comment

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

Why did you have to change these parts?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This change is for preparation of EIP2028. The reason we need EIP2028 is as follows:
If EIP2028 is not enabled, the test revert_reason.json will not pass unless we change the test itself. Check this commit that change the test json itself: 0a496c3
So actually this code change does not necessary belong to this PR. Do you want me to undo it?

Copy link
Collaborator

@gzliudan gzliudan Jun 19, 2024

Choose a reason for hiding this comment

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

The consensus will be changed if we enable eip-2028. I can include it in the PR of EIP-1559 if you need it.

Copy link

Choose a reason for hiding this comment

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

Yes please let's remove that from this PR. It would be a separate discussion if EIP-2028 is useful for XDC.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes please let's remove that from this PR. It would be a separate discussion if EIP-2028 is useful for XDC.

I removed it and force pushed commits.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The consensus will be changed if we enable eip-2028. I can include it in the PR of EIP-1559 if you need it.

No hurry. At the time of eip2028, we need to remember to undo this commit: e1b7ba6

)

func init() {
tracers.RegisterNativeTracer("callTracerNative", NewCallTracer)
Copy link

Choose a reason for hiding this comment

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

I think we can directly make this default callTracer

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure. Then this tracer will override js tracer with the same name. Shall we name the js tracer?

Copy link

Choose a reason for hiding this comment

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

Right callTracer should be the native tracer. IMO the old one can be kept as callTracerLegacy and the "new" JS call tracer I don't think it's really necessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changed native tracer to the default one, for call tracer and noop tracer.

@s1na
Copy link

s1na commented Jun 17, 2024

This PR's XXX_legacy.js tracers are not completely equal to XXX.js tracers before this PR. Shall we make XXX_legacy.js equal to prior XXX.js?

Can you post the diff?

@wgr523
Copy link
Collaborator Author

wgr523 commented Jun 19, 2024

This PR's XXX_legacy.js tracers are not completely equal to XXX.js tracers before this PR. Shall we make XXX_legacy.js equal to prior XXX.js?

Can you post the diff?

Sure. The diff by running diff call_tracer_legacy.js call_tracer_dev-upgrade.js -u where call_tracer_dev-upgrade.js is the one before this PR:

diff call_tracer_legacy.js call_tracer_dev-upgrade.js -u
--- call_tracer_legacy.js	2024-06-19 22:56:44.000000000 +0800
+++ call_tracer_dev-upgrade.js	2024-06-19 22:57:58.000000000 +0800
@@ -61,14 +61,7 @@
 			if (this.callstack[left-1].calls === undefined) {
 				this.callstack[left-1].calls = [];
 			}
-			this.callstack[left-1].calls.push({
-				type:    op,
-				from:    toHex(log.contract.getAddress()),
-				to:      toHex(toAddress(log.stack.peek(0).toString(16))),
-				gasIn:   log.getGas(),
-				gasCost: log.getCost(),
-				value:   '0x' + db.getBalance(log.contract.getAddress()).toString(16)
-			});
+			this.callstack[left-1].calls.push({type: op});
 			return
 		}
 		// If a new method invocation is being done, add to the call stack
@@ -139,12 +132,13 @@
 				// If the call was a contract call, retrieve the gas usage and output
 				if (call.gas !== undefined) {
 					call.gasUsed = '0x' + bigInt(call.gasIn - call.gasCost + call.gas - log.getGas()).toString(16);
-				}
-				var ret = log.stack.peek(0);
-				if (!ret.equals(0)) {
-					call.output = toHex(log.memory.slice(call.outOff, call.outOff + call.outLen));
-				} else if (call.error === undefined) {
-					call.error = "internal failure"; // TODO(karalabe): surface these faults somehow
+
+					var ret = log.stack.peek(0);
+					if (!ret.equals(0)) {
+						call.output = toHex(log.memory.slice(call.outOff, call.outOff + call.outLen));
+					} else if (call.error === undefined) {
+						call.error = "internal failure"; // TODO(karalabe): surface these faults somehow
+					}
 				}
 				delete call.gasIn; delete call.gasCost;
 				delete call.outOff; delete call.outLen;
@@ -214,7 +208,7 @@
 		} else if (ctx.error !== undefined) {
 			result.error = ctx.error;
 		}
-		if (result.error !== undefined && (result.error !== "execution reverted" || result.output ==="0x")) {
+		if (result.error !== undefined) {
 			delete result.output;
 		}
 		return this.finalize(result);

For other tracers, legacy tracer and dev-upgrade tracer are the same.

@s1na
Copy link

s1na commented Jun 20, 2024

The diff by running diff call_tracer_legacy.js call_tracer_dev-upgrade.js -u where call_tracer_dev-upgrade.js is the one before this PR

between those two files call_tracer_legacy.js seems more correct.

@wgr523
Copy link
Collaborator Author

wgr523 commented Jun 21, 2024

The diff by running diff call_tracer_legacy.js call_tracer_dev-upgrade.js -u where call_tracer_dev-upgrade.js is the one before this PR

between those two files call_tracer_legacy.js seems more correct.

So I guess call_tracer_legacy.js is already ready in this PR. No further change is needed.

@gzliudan
Copy link
Collaborator

gzliudan commented Jul 9, 2024

Request:

curl -s -X POST -H "Content-Type: application/json" ${RPC} -d '{
  "jsonrpc": "2.0",
  "id": 1001,
  "method": "debug_traceBlockByNumber",
  "params": [
    "latest", 
    {"tracer":"callTracer"}
  ]
}' | jq

Response:

{
  "jsonrpc": "2.0",
  "id": 1001,
  "result": [
    {
      "result": {
        "type": "CALL",
        "from": "xdc4398241671b3dd484fe3213a4fb7511f30e7d7c0",
        "to": "xdc0000000000000000000000000000000000000089",
        "value": "0x0",
        "gas": "0x2b068",
        "gasUsed": "0x147ce",
        "input": "0xe341eaa400000000000000000000000000000000000000000000000000000000002b85b848d26996721c2750b15a0a5d37de015365ae688b0bb031e52723d6e4d73d63ae",
        "output": "0x"
      }
    }
  ]
}

Why from and to are xdc prefix ?

@@ -166,5 +166,6 @@ func uintToHex(n uint64) string {
}

func addrToHex(a common.Address) string {
return strings.ToLower(a.Hex())
s, _ := a.MarshalText()
return strings.ToLower(string(s))
Copy link
Collaborator

@gzliudan gzliudan Jul 11, 2024

Choose a reason for hiding this comment

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

Why call strings.ToLower ? I think return string(s) is enough:

  • We should keep the address is checksumed
  • reduce CPU cost and network response time

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok. Ethereum uses lower case. If we don't need lower case we can just return the string(s)

@gzliudan
Copy link
Collaborator

The callTracer handles address prefix properly now. But the callTracerLegacy returns 0x prefix for address when XDC is started with the flag --enable-xdc-prefix which should returns xdc prefix for address.

@@ -273,7 +266,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG
// sufficient balance to make the transfer happen. The first
// balance transfer may never fail.
if vmerr == vm.ErrInsufficientBalance {
return nil, 0, false, vmerr, nil
return nil, 0, false, nil, vmerr
Copy link

Choose a reason for hiding this comment

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

Can you explain this change? It is a sensitive part of the code.

Copy link

Choose a reason for hiding this comment

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

I am convinced this will introduce a bug and should be resolved.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree. I checked history geth commit: ethereum@b9df7ec
Although the variable name is vmerr, this error means no balance to pay for the tx. It should be consensus err and should be returned in 4-th err place.
I'll revert this

@@ -1,4 +1,4 @@
// Copyright 2017 The go-ethereum Authors
// Copyright 2021 The go-ethereum Authors
Copy link

Choose a reason for hiding this comment

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

I believe there is no way to access this particular tracer. It has the same name as the native callTracer. IMHO we can simply drop this (or replace the callTracerLegacy with it). Depends if we want users to still access the "old tracer".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think we can drop it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I believe there is no way to access this particular tracer. It has the same name as the native callTracer. IMHO we can simply drop this (or replace the callTracerLegacy with it). Depends if we want users to still access the "old tracer".

fixed and code pushed

Copy link

@s1na s1na left a comment

Choose a reason for hiding this comment

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

Looks good to me

@liam-lai liam-lai merged commit 52077f1 into dev-upgrade Aug 6, 2024
34 checks passed
@liam-lai liam-lai deleted the golang-tracer branch August 6, 2024 07:14
wanwiset25 pushed a commit that referenced this pull request Aug 23, 2024
* feat: rename Tracer interface to EVMLogger;
minor changes in API
refine api_tracer.go
refine Tracer interface

* fix: broken tracer tests

* feat: add BenchmarkTransactionTrace

* feat: tracer CaptureEnter CaptureExit in evm

* feat: upgrade js tracers with geth upstream

* chore: clean test

* feat: eth/tracers: support for golang tracers + add golang callTracer
cf. ethereum#23708

* chore: clean testdata json

* fix: change test due to IntrinsicGas is not upgraded

* feat: make native Tracer the default Tracer

* fix: update tracers.New in api

* fix: addr prefix in callTracer

* fix: remove `native` in BenchmarkTracers

* fix: return consensus error of InsufficientBalance for tx, instead of vmerr

* chore: drop js tracers: call and noop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants