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

cmd/geth: implement dev mode for post-merge #27327

Merged
merged 49 commits into from
Jul 6, 2023

Conversation

jwasinger
Copy link
Contributor

@jwasinger jwasinger commented May 23, 2023

Opening this as a draft to get eyes on it in its current state, and get feedback if there are obvious things that should be changed.

Currently works with the command: ./build/bin/geth --dev

@holiman
Copy link
Contributor

holiman commented May 24, 2023

Currently works with the command: ./build/bin/geth --http --http.api "engine" --nodiscover --authrpc.jwtsecret $(pwd)/jwt_secret --dev

Haven't looked at the code, but why would one want to pass jwtsecret? Shouldn't it just be geth --dev and done?

@jwasinger
Copy link
Contributor Author

@holiman yup. That's something I've noted in todo list above. Trying to address those today.

GasLimit: gasLimit,
BaseFee: big.NewInt(params.InitialBaseFee),
Difficulty: big.NewInt(1),
Copy link
Contributor

Choose a reason for hiding this comment

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

I find it a bit weird that the genesis block has a non-zero difficulty:

> eth.getBlock(0).difficulty
131072

Copy link
Member

Choose a reason for hiding this comment

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

it was very difficult genecizing this genesis block

Copy link
Contributor

Choose a reason for hiding this comment

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

The difficulty formula is undefined for difficulties <131072. There is a minimum difficulty, and below that, the spec can be interpreted in two different ways, depending on at what exact step one decides to apply the minimum threshold.

params/config.go Outdated Show resolved Hide resolved
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.

For testing use-cases it would be nice to also have a way of setting safe and finalized blocks through clmock. As well as pushing withdrawals. Possibly adding a dev namespace in the RPC for this purpose?

clmock/engine_api.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
@jwasinger
Copy link
Contributor Author

Okay. This is getting closer.

Two items still need to be addressed:

  • configurability of dev mode gas limit (override genesis configuration if --dev.gaslimit flag is present and there is no pre-existing chain)
  • currently panics if started up using an incompatible datadir.

Copy link
Member

@gballet gballet left a comment

Choose a reason for hiding this comment

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

Left a few questions

clmock/clmock.go Outdated Show resolved Hide resolved
core/genesis.go Show resolved Hide resolved
GasLimit: gasLimit,
BaseFee: big.NewInt(params.InitialBaseFee),
Difficulty: big.NewInt(1),
Copy link
Member

Choose a reason for hiding this comment

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

it was very difficult genecizing this genesis block

params/config.go Outdated
Clique *CliqueConfig `json:"clique,omitempty"`
Ethash *EthashConfig `json:"ethash,omitempty"`
Clique *CliqueConfig `json:"clique,omitempty"`
Dev *DeveloperModeConfig `json:"dev,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Just my 2 cents here: I feel this is overkill, because you can just pass it as a command line option, and use that parameter when instantiating the CLMock. So you could reduce the footprint of that PR by not adding more config here, since it's really only used in one place.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes but it must be persisted in the case where dev mode is not being used ephemerally. Hence I add DeveloperModeConfig so that the period will be stored.

Copy link
Member

Choose a reason for hiding this comment

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

must it, though? if you need it to remain active, all you need to do is add --dev to your command line. Not going to die on that hill, just feel the PR could be simpler.

Copy link
Contributor Author

@jwasinger jwasinger Jun 2, 2023

Choose a reason for hiding this comment

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

In dev mode: When you specify --datadir and --dev together it persists the chain. if the datadir is omitted, the chain is ephemeral (cleared on shutdown).

Copy link
Member

Choose a reason for hiding this comment

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

I also feel this is overkill? Is there ever really a use case to have a dev mode genesis? ChainConfig is used quite a bit and so we should be confident in the addition here.

Copy link
Member

Choose a reason for hiding this comment

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

In DeveloperModeConfig , there is only a single field period. It's totally fine to use another value in the next restart I think. We can have a default value for it, e.g. 12s or so, and users can change it by CLI flag.

clmock/clmock.go Outdated Show resolved Hide resolved
@MariusVanDerWijden

This comment was marked as resolved.

@jwasinger
Copy link
Contributor Author

Alright, I've addressed the remaining issues that I listed above. Adding a few unit tests and then hopefully, this should be ready for merge.

@jwasinger jwasinger marked this pull request as ready for review June 2, 2023 11:05
@jwasinger
Copy link
Contributor Author

jwasinger commented Jun 2, 2023

It occurs to me that it probably makes sense to implement a way to shim-in support for withdrawals. I'll try to think about how this will work.

clmock/api.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/api.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
clmock/clmock.go Outdated Show resolved Hide resolved
@jwasinger jwasinger force-pushed the dev-mode-clmock branch 2 times, most recently from 23ee876 to 4645e03 Compare June 12, 2023 21:43
@jwasinger
Copy link
Contributor Author

Okay, I've addressed most of the feedback that @lightclient has provided (thanks for that!). The only remaining question is where to put the simulated_beacon package?

It can either live under internal or in cmd/geth as suggested by @lightclient .

@lightclient
Copy link
Member

I think I lean towards just putting the files into cmd/geth and not adding a new package. It's relatively lightweight and only ever instantiated in cmd/geth/config.go. If it is a package though, you should drop the underscore in the name.

@holiman
Copy link
Contributor

holiman commented Jun 13, 2023

Some UX quirks...
It opens port 8551 -- which seems unnecessary ?

INFO [06-13|11:56:39.169] IPC endpoint opened                      url=/tmp/geth.ipc
INFO [06-13|11:56:39.171] WebSocket enabled                        url=ws://127.0.0.1:8551
INFO [06-13|11:56:39.171] HTTP server started                      endpoint=127.0.0.1:8551 auth=true prefix= cors=localhost vhosts=localhost

When running it, it keep spitting out this:

INFO [06-13|11:59:40.087] Starting work on payload                 id=0x1a411adabba04e97
INFO [06-13|11:59:40.087] Updated payload                          id=0x1a411adabba04e97 number=1 hash=3970ba..f2fc01 txs=0 gas=0 fees=0 root=e642b9..90f354 elapsed="263.675µs"
INFO [06-13|11:59:52.088] Stopping work on payload                 id=0x1a411adabba04e97 reason=timeout
INFO [06-13|11:59:52.089] Starting work on payload                 id=0xa0f6fb4c31da930b
INFO [06-13|11:59:52.089] Updated payload                          id=0xa0f6fb4c31da930b number=1 hash=051b8f..e98ddc txs=0 gas=0 fees=0 root=e642b9..90f354 elapsed="60.977µs"
INFO [06-13|12:00:04.089] Stopping work on payload                 id=0xa0f6fb4c31da930b reason=timeout
INFO [06-13|12:00:04.090] Starting work on payload                 id=0x7c0f68cd6ee81a44
INFO [06-13|12:00:04.090] Updated payload                          id=0x7c0f68cd6ee81a44 number=1 hash=5cfc3d..3ca163 txs=0 gas=0 fees=0 root=e642b9..90f354 elapsed="99.294µs"
INFO [06-13|12:00:16.091] Stopping work on payload                 id=0x7c0f68cd6ee81a44 reason=timeout

And that's while I'm not doing anything, just letting it idle. Seems unnecessary?

node/node.go Outdated Show resolved Hide resolved
Comment on lines 14 to 18
func (api *API) AddWithdrawal(ctx context.Context, withdrawal *types.Withdrawal) error {
api.simBeacon.mu.Lock()
defer api.simBeacon.mu.Unlock()
return api.simBeacon.withdrawals.add(withdrawal)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is IMO a bit odd. I guess you wanted to split this up into a standalone API in order to make the distinction more clear about what is the public API-surface and what is the actual implementation?

The thing which is a bit odd, IMO, is that you have this external wrapper which reaches in and locks/unlocks an internal mutex inside teh simBeacon. Either move the mutex to this API, or, probably better, move the locking so the SimulatedBeacon controls it's own locks.

Copy link
Contributor

@holiman holiman Jun 13, 2023

Choose a reason for hiding this comment

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

So this type would be a 'pure' wrapper:

Suggested change
func (api *API) AddWithdrawal(ctx context.Context, withdrawal *types.Withdrawal) error {
api.simBeacon.mu.Lock()
defer api.simBeacon.mu.Unlock()
return api.simBeacon.withdrawals.add(withdrawal)
}
func (api *API) AddWithdrawal(ctx context.Context, withdrawal *types.Withdrawal) error {
return api.simBeacon.withdrawals.add(withdrawal)
}

You could even (maybe?) turn this whole file into

type API SimulatedBeacon

func (api *API) AddWithdrawal(ctx context.Context, withdrawal *types.Withdrawal) error {
	return api.addWithdrawal(withdrawal)
}

func (api *API) SetFeeRecipient(ctx context.Context, feeRecipient *common.Address) {
	api.feeRecipient = *feeRecipient
}

Depends on your preference I guess, but it's less code at least

The last change also requires a change here:

--- a/simulated_beacon/simulated_beacon.go
+++ b/simulated_beacon/simulated_beacon.go
@@ -216,7 +216,7 @@ func RegisterAPIs(stack *node.Node, c *SimulatedBeacon) {
        stack.RegisterAPIs([]rpc.API{
                {
                        Namespace: "dev",
-                       Service:   &API{c},
+                       Service:   (*API)(c),
                        Version:   "1.0",
                },
        })

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've moved the mutex-handling for controlling access for fee recipient and the withdrawals list into SimulatedBeacon/withdrawals and pulled them out of the api. This should make things a bit cleaner.

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

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

LGTM

@holiman holiman merged commit ea78280 into ethereum:master Jul 6, 2023
@hadv
Copy link
Contributor

hadv commented Aug 15, 2023

Hi,

  1. A random, pre-allocated developer account will be available and unlocked as
    eth.coinbase, which can be used for testing. The random dev account is temporary,
    stored on a ramdisk, and will be lost if your machine is restarted.

Using random account for testing is not a good idea, especially with automation test environment.
Can you add a flag to pre-allocate fund for specific accounts?

@jwasinger jwasinger deleted the dev-mode-clmock branch August 15, 2023 05:10
@jwasinger
Copy link
Contributor Author

@hadv if you want to fund specific accounts, transfer ether from the coinbase account. There isn't a need for the ability to pre-allocate specific accounts at genesis.

@hadv
Copy link
Contributor

hadv commented Aug 16, 2023

@hadv if you want to fund specific accounts, transfer ether from the coinbase account. There isn't a need for the ability to pre-allocate specific accounts at genesis.

When using web3j for automation testing, we need Credentials to send fund; but we didn't have Credentials of coinbase account

Tristan-Wilson added a commit to OffchainLabs/nitro that referenced this pull request Oct 4, 2023
v1.12.1 geth changes the default ChainConfig returned with
DeveloperGenesisBlock from AllCliqueProtocolChanges to
AllDevChainProtocolChanges. Since the dev chain config is not set to
clique mode and is set as post-TTD with TTD=0, there needs to be a
non-ethhash based consensus engine running in order for blocks to be
produced. See the upstream geth change here:
ethereum/go-ethereum#27327

This commit copies the initailization code for how geth is started up
in dev mode with the simulated beacon node to our test L1 setup code.
It also enables FullSync mode on the L1, since otherwise
SimluatedBeacon.sealBlock would fail when calling the
ConsensusAPI.ForkChoiceUpdatedV2 as it would still be syncing if it was
in SnapSync mode. UseMergeFinality was also disabled on the
TestDelayedSequencerConfig since the SimulatedBeacon seems to have
different finalization behavior.
@rmlearney-digicatapult
Copy link

I've just opened issue #28449 related to this issue - is it possible to run a private Shanghai-EVM-compatible PoA network without --dev?

devopsbo3 pushed a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
This change adds back the 'geth --dev' mode of operation, using a cl-mocker. 

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.