Skip to content

core, eth: use tracing.Hooks by value #32185

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

omerfirmak
Copy link
Contributor

@omerfirmak omerfirmak commented Jul 10, 2025

the main motivation was to make Contract.UseGas and Contract.RefundGas inlinable. But it also has the nice side affect of getting rid of the verbose if tracer != nil && tracer.OnSomeEvent != nil pattern.

@@ -217,6 +217,16 @@ type Hooks struct {
OnBlockHashRead BlockHashReadHook
}

// HooksState returns if any of the state events are being hooked
func (h *Hooks) HooksState() bool {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe HasStateHooks ? HooksState is correct, but sounds a bit weird (double meaning of hooks and Hooks)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeap, that definitely is easier to understand.

@@ -217,6 +217,16 @@ type Hooks struct {
OnBlockHashRead BlockHashReadHook
}

// HooksState returns if any of the state events are being hooked
func (h *Hooks) HooksState() bool {
return h.OnBalanceChange != nil ||
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering if there's a way to do this, s.th. we can be sure that we will not forget about it, if we add new hooks

Copy link
Contributor Author

@omerfirmak omerfirmak Jul 11, 2025

Choose a reason for hiding this comment

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

Yeah, I wanted to achieve something more foolproof as well. My first choice was to compare against some zero value like h != Hooks{}, but that doesn't work when the type has function pointers inside.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added a caution comment

Copy link
Member

Choose a reason for hiding this comment

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

How about we define a bitmaps in the Hook struct and avoid the construction by struct assignment directly?

Then we should have the ability to check if State hooks, Chain hooks, Vm hooks have been specified somehow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

can be sure that we will not forget about it, if we add new hooks

how would bitmaps help with the issue above?

core/vm/evm.go Outdated
evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err)
}(gas)
}
evm.captureBegin(evm.depth, CALL, caller, addr, input, gas, value.ToBig())
Copy link
Member

Choose a reason for hiding this comment

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

It means the tracer will be checked for every Call/Callcode/StaticCall, ... opcodes.
which was a single pointer check.

Not sure about the overhead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, put them behind an if check again. f3bae51

@omerfirmak omerfirmak closed this Jul 18, 2025
@omerfirmak omerfirmak reopened this Jul 21, 2025
the main motivation was to make Contract.UseGas and
Contract.RefundGas inlinable.
@@ -126,24 +126,24 @@ func (c *Contract) Caller() common.Address {
}

// UseGas attempts the use gas and subtracts it and returns true on success
func (c *Contract) UseGas(gas uint64, logger *tracing.Hooks, reason tracing.GasChangeReason) (ok bool) {
func (c *Contract) UseGas(gas uint64, onGasChange tracing.GasChangeHook, reason tracing.GasChangeReason) (ok bool) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The PR's motivation says it's about making UseGas inlinable. The diff here doesn't seem to necessitate changing Hooks to a value.

Copy link
Contributor Author

@omerfirmak omerfirmak Jul 22, 2025

Choose a reason for hiding this comment

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

What made UseGas not inlinable is the additional logger != nil check and the pointer de-referencing (logger.OnGasChange). I could've moved these to every callsite, but that ends up creating a mess everywhere. So ended up getting rid of the culprits (nil-check and de-referencing) entirely.

@omerfirmak omerfirmak force-pushed the dynamic-gas-trace branch 2 times, most recently from 61b6449 to 57fa10b Compare July 24, 2025 13:38
@omerfirmak omerfirmak marked this pull request as draft July 24, 2025 13:38
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