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

core/tracing: register live tracer APIs #30308

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

jsvisa
Copy link
Contributor

@jsvisa jsvisa commented Aug 16, 2024

Hi @s1na, could you please review this pre-PR for the live trace_xxx RPC? Below are the main points covered in this PR:

  1. The live tracer is registered with the tracing.Backend interface, which will be utilized internally.
  2. Within the live tracer, I’ve added another field, which is []rpc.API, so we can use stack.RegisterAPIs to register the JSON-RPC interfaces.
  3. A new function BlockChain.SetLogger, has been added to enable setting the live tracer once it is fully initialized.

cmd/utils/flags.go Outdated Show resolved Hide resolved
cmd/utils/flags.go Outdated Show resolved Hide resolved
@jsvisa jsvisa requested a review from s1na August 22, 2024 03:16
@jsvisa jsvisa changed the title cmd,eth: lazy initialize and register live tracer rpc cmd,eth: register live tracer RPCs Aug 22, 2024
Signed-off-by: jsvisa <[email protected]>
This reverts commit c378326.

Signed-off-by: jsvisa <[email protected]>
This reverts commit 3d5a8b3.

Signed-off-by: jsvisa <[email protected]>
This reverts commit 0bdbcba.

Signed-off-by: jsvisa <[email protected]>
This reverts commit d33b24c.

Signed-off-by: jsvisa <[email protected]>
This reverts commit 9e1d9ec.

Signed-off-by: jsvisa <[email protected]>
core/tracing/hooks.go Outdated Show resolved Hide resolved
core/tracing/hooks.go Outdated Show resolved Hide resolved
@s1na s1na requested a review from fjl as a code owner October 1, 2024 11:07
@s1na
Copy link
Contributor

s1na commented Oct 1, 2024

I pushed a change to allow tracers to add their API methods to the console. the rpc.API type has now a ConsoleExtension field for this purpose.

@s1na
Copy link
Contributor

s1na commented Oct 2, 2024

I tested with the following tracer and it correctly registers the API. The method is also invokable through the console.

package live

import (
	"encoding/json"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/tracing"
	"github.com/ethereum/go-ethereum/eth/tracers"
	"github.com/ethereum/go-ethereum/rpc"
)

func init() {
	tracers.LiveDirectory.Register("chainTracker", newChainTracker)
}

type chainTracker struct {
	lastBlockHash common.Hash
}

func newChainTracker(_ json.RawMessage, node tracers.LiveApiRegister, _ tracing.Backend) (*tracing.Hooks, error) {
	t := &chainTracker{}
	node.RegisterAPIs([]rpc.API{
		{
			Namespace: "eth",
			Version:   "1.0",
			Service:   &chainAPI{tracer: t},
			Public:    true,
			ConsoleExtension: `
web3._extend({
	property: 'eth',
	methods: [
		new web3._extend.Method({
			name: 'lastBlockHash',
			call: 'eth_lastBlockHash',
			params: 0,
		})
	]
});
`,
		},
	})
	return &tracing.Hooks{
		OnBlockStart: t.OnBlockStart,
	}, nil
}

type chainAPI struct {
	tracer *chainTracker
}

func (api *chainAPI) LastBlockHash() string {
	return api.tracer.lastBlockHash.Hex()
}

func (t *chainTracker) OnBlockStart(event tracing.BlockEvent) {
	t.lastBlockHash = event.Block.Hash()
}

RegisterAPIs(apis []rpc.API)
}

type ctorFunc func(config json.RawMessage, stack LiveApiRegister, backend tracing.Backend) (*tracing.Hooks, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes me realize the whole tracing interface is in one place (tracing/hooks.go) except for the constructor. It is harder to catch backwards-incompatible changes to the interface because of this. Gonna move it out.

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, agree with it, move the apis into one place(hooks.go) will make it more obvious.

Copy link
Contributor

@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.

LGTM

@s1na s1na changed the title cmd,eth: register live tracer RPCs core/tracing: register live tracer APIs Oct 2, 2024
@s1na s1na added this to the 1.14.12 milestone Oct 2, 2024
@s1na
Copy link
Contributor

s1na commented Oct 2, 2024

@fjl PTAL

HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error)
Copy link
Contributor

@fjl fjl Oct 7, 2024

Choose a reason for hiding this comment

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

This GetTransaction method is not great for several reasons. First, it requires us to have an index of txhash -> tx, which is strictly optional. The index we have is not complete, we only keep a limited horizon worth of blocks in it. The indexing is also async with block execution and so it may not lead to a repeatable tracing result.

Another problem is the amount of return values. A signature with this number of return values implies there may be more values returned in the future. If we wanted to change this, it would break the interface. So we need to either define a new struct which is to be returned by this method, or break it up into multiple methods.

I also wonder why a tracer would need to query transactions by hash. I think it's a niche use case and we might be better off not allowing it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

I also wonder why a tracer would need to query transactions by hash.

I think a tracer will almost never need this in and out of itself. Only in the case where the tracer is exposing an API. Which makes me think if live tracers exposing an API is a good abstraction. It is easy to abuse the live tracing interface to expose an API that doesn't need tracing hooks at all. I wonder if we should introduce plugins that can also register live tracers and/or APIs instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder if we should introduce plugins that can also register live tracers and/or APIs instead.

agree with it, plugins will be more flexible and useful for different use cases.

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.

3 participants