How Geth starts its server

When starting up, the Geth client begins by parsing the command line parameters. This process kicks off with the geth function: func geth(ctx *cli.Context) error at cmd/geth/main.go:326 where the geth prepares the metric if enabled. Subsequently, the makeFullNode function takes over. It reads the provided configuration file or command line flags. As a result, it returns two key components: the protocol stack and the backend API.
启动时,Geth 客户端首先解析命令行参数。此过程从以下 geth 函数开始: func geth(ctx *cli.Context) error 如果 cmd/geth/main.go:326 启用,则 geth 在准备指标的位置。随后,该功能 makeFullNode 接管。它读取提供的配置文件或命令行标志。因此,它返回两个关键组件:协议栈和后端 API。

It’s worth noting the importance of the Backend API. It establishes a myriad of interfaces, facilitating interaction with nodes and handling external RPC call limits.
值得注意的是后端 API 的重要性。它建立了无数的接口,促进了与节点的交互并处理外部 RPC 调用限制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Backend interface provides the common API services (that are provided by
// both full and light clients) with access to necessary functions.
type Backend interface {
	// General Ethereum API
	SyncProgress() ethereum.SyncProgress

	SuggestGasTipCap(ctx context.Context) (*big.Int, error)
	FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error)
	ChainDb() ethdb.Database
	AccountManager() *accounts.Manager
	ExtRPCEnabled() bool
	RPCGasCap() uint64            // global gas cap for eth_call over rpc: DoS protection
	RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection
	RPCTxFeeCap() float64         // global tx fee cap for all transaction related APIs
	UnprotectedAllowed() bool     // allows only for EIP155 transactions.

	// Blockchain API
	SetHead(number uint64)
	HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
	HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
	HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error)
	CurrentHeader() *types.Header
	CurrentBlock() *types.Header
	BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
	BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
	BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error)
	StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error)
	StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error)
	PendingBlockAndReceipts() (*types.Block, types.Receipts)
	GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
	GetTd(ctx context.Context, hash common.Hash) *big.Int
	GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) (*vm.EVM, func() error)
	SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
	SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
	SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription

	// Transaction pool API
	SendTx(ctx context.Context, signedTx *types.Transaction) error
	GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
	GetPoolTransactions() (types.Transactions, error)
	GetPoolTransaction(txHash common.Hash) *types.Transaction
	GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
	Stats() (pending int, queued int)
	TxPoolContent() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction)
	TxPoolContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction)
	SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription

	ChainConfig() *params.ChainConfig
	Engine() consensus.Engine

	// This is copied from filters.Backend
	// eth/filters needs to be initialized from this backend type, so methods needed by
	// it must also be included here.
	GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error)
	GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error)
	SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription
	SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription
	SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription
	BloomStatus() (uint64, uint64)
	ServiceFilter(ctx context.Context, session *bloombits.MatcherSession)
}

For instance, the SyncProgress() method captures the node’s status as it synchronizes with the Ethereum network.
例如,该方法 SyncProgress() 在与以太坊网络同步时捕获节点的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
type SyncProgress struct {
	StartingBlock uint64 // Block number where sync began
	CurrentBlock  uint64 // Current block number where sync is at
	HighestBlock  uint64 // Highest alleged block number in the chain

	// "fast sync" fields. These used to be sent by geth, but are no longer used
	// since version v1.10.
	PulledStates uint64 // Number of state trie entries already downloaded
	KnownStates  uint64 // Total number of state trie entries known about

	// "snap sync" fields.
	SyncedAccounts      uint64 // Number of accounts downloaded
	SyncedAccountBytes  uint64 // Number of account trie bytes persisted to disk
	SyncedBytecodes     uint64 // Number of bytecodes downloaded
	SyncedBytecodeBytes uint64 // Number of bytecode bytes downloaded
	SyncedStorage       uint64 // Number of storage slots downloaded
	SyncedStorageBytes  uint64 // Number of storage trie bytes persisted to disk

	HealedTrienodes     uint64 // Number of state trie nodes downloaded
	HealedTrienodeBytes uint64 // Number of state trie bytes persisted to disk
	HealedBytecodes     uint64 // Number of bytecodes downloaded
	HealedBytecodeBytes uint64 // Number of bytecodes persisted to disk

	HealingTrienodes uint64 // Number of state trie nodes pending
	HealingBytecode  uint64 // Number of bytecodes pending
}

Regarding the protocol stack, it’s represented by the Node structure, which comprises numerous fields. Among these, the stop field plays a pivotal role as it signals the termination of the server.
关于协议栈,它由结构表示,该 Node 结构包含许多字段。其中,该 stop 字段起着关键作用,因为它发出服务器终止的信号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Node is a container on which services can be registered.
type Node struct {
	eventmux      *event.TypeMux
	config        *Config
	accman        *accounts.Manager
	log           log.Logger
	keyDir        string        // key store directory
	keyDirTemp    bool          // If true, key directory will be removed by Stop
	dirLock       *flock.Flock  // prevents concurrent use of instance directory
	stop          chan struct{} // Channel to wait for termination notifications
	server        *p2p.Server   // Currently running P2P networking layer
	startStopLock sync.Mutex    // Start/Stop are protected by an additional lock
	state         int           // Tracks state of node lifecycle

	lock          sync.Mutex
	lifecycles    []Lifecycle // All registered backends, services, and auxiliary services that have a lifecycle
	rpcAPIs       []rpc.API   // List of APIs currently provided by the node
	http          *httpServer //
	ws            *httpServer //
	httpAuth      *httpServer //
	wsAuth        *httpServer //
	ipc           *ipcServer  // Stores information about the ipc http server
	inprocHandler *rpc.Server // In-process RPC request handler to process the API requests

	databases map[*closeTrackingDB]struct{} // All open databases
}

Once all configurations are in place and prior to the server’s actual launch, you should observe the following output:
一旦所有配置都到位,在服务器实际启动之前,您应该观察到以下输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
INFO [09-13|12:46:39.391] Starting Geth on Ethereum mainnet...
INFO [09-13|12:46:39.392] Bumping default cache on mainnet         provided=1024 updated=4096
INFO [09-13|12:46:39.396] Maximum peer count                       ETH=50 LES=0 total=50
INFO [09-13|12:46:39.400] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [09-13|12:46:39.408] Set global gas cap                       cap=50,000,000
INFO [09-13|12:46:39.408] Initializing the KZG library             backend=gokzg
INFO [09-13|12:46:39.611] Allocated trie memory caches             clean=614.00MiB dirty=1024.00MiB
INFO [09-13|12:46:39.611] Using pebble as the backing database
INFO [09-13|12:46:39.611] Allocated cache and file handles         database=/home/username/.ethereum/geth/chaindata cache=2.00GiB handles=32767
INFO [09-13|12:46:39.677] Opened ancient database                  database=/home/username/.ethereum/geth/chaindata/ancient/chain readonly=false
INFO [09-13|12:46:39.681] Initialising Ethereum protocol           network=1 dbversion=8
INFO [09-13|12:46:39.681]
INFO [09-13|12:46:39.681] ---------------------------------------------------------------------------------------------------------------------------------------------------------
INFO [09-13|12:46:39.683] Chain ID:  1 (mainnet)
INFO [09-13|12:46:39.683] Consensus: Beacon (proof-of-stake), merged from Ethash (proof-of-work)
INFO [09-13|12:46:39.683]
INFO [09-13|12:46:39.683] Pre-Merge hard forks (block based):
INFO [09-13|12:46:39.683]  - Homestead:                   #1150000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)
INFO [09-13|12:46:39.683]  - DAO Fork:                    #1920000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)
INFO [09-13|12:46:39.683]  - Tangerine Whistle (EIP 150): #2463000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/tangerine-whistle.md)
INFO [09-13|12:46:39.683]  - Spurious Dragon/1 (EIP 155): #2675000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)
INFO [09-13|12:46:39.683]  - Spurious Dragon/2 (EIP 158): #2675000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)
INFO [09-13|12:46:39.683]  - Byzantium:                   #4370000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)
INFO [09-13|12:46:39.683]  - Constantinople:              #7280000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)
INFO [09-13|12:46:39.683]  - Petersburg:                  #7280000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)
INFO [09-13|12:46:39.683]  - Istanbul:                    #9069000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)
INFO [09-13|12:46:39.683]  - Muir Glacier:                #9200000  (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)
INFO [09-13|12:46:39.683]  - Berlin:                      #12244000 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)
INFO [09-13|12:46:39.683]  - London:                      #12965000 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)
INFO [09-13|12:46:39.683]  - Arrow Glacier:               #13773000 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)
INFO [09-13|12:46:39.683]  - Gray Glacier:                #15050000 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)
INFO [09-13|12:46:39.683]
INFO [09-13|12:46:39.683] Merge configurationd:
INFO [09-13|12:46:39.683]  - Hard-fork specification:    https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md
INFO [09-13|12:46:39.683]  - Network known to be merged: true
INFO [09-13|12:46:39.683]  - Total terminal difficulty:  58750000000000000000000
INFO [09-13|12:46:39.683]
INFO [09-13|12:46:39.683] Post-Merge hard forks (timestamp based):
INFO [09-13|12:46:39.684]  - Shanghai:                    @1681338455 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md)
INFO [09-13|12:46:39.684]
INFO [09-13|12:46:39.684] ---------------------------------------------------------------------------------------------------------------------------------------------------------
INFO [09-13|12:46:39.684]
INFO [09-13|12:46:39.686] Loaded most recent local block           number=0 hash=d4e567..cb8fa3 td=17,179,869,184 age=54y5mo3w
WARN [09-13|12:46:39.688] Loaded snapshot journal                  diffs=missing
INFO [09-13|12:46:39.688] Resuming state snapshot generation       root=d7f897..0f0544 accounts=0 slots=0 storage=0.00B dangling=0 elapsed="34.181µs"
INFO [09-13|12:46:39.688] Loaded local transaction journal         transactions=0 dropped=0
INFO [09-13|12:46:39.689] Regenerated local transaction journal    transactions=0 accounts=0
INFO [09-13|12:46:39.729] Chain post-merge, sync via beacon client
INFO [09-13|12:46:39.730] Gasprice oracle is ignoring threshold set threshold=2
WARN [09-13|12:46:39.738] Unclean shutdown detected                booted=2023-09-12T15:07:35+0000 age=21h39m4s
WARN [09-13|12:46:39.738] Unclean shutdown detected                booted=2023-09-13T08:02:05+0000 age=4h44m34s
WARN [09-13|12:46:39.739] Engine API enabled                       protocol=eth

Following this, the startNode function executes, paving the way for StartNode, which is responsible for actually initiating the server. The method stack.Start() found in cmd/utils/cmd.go:72 will launch the node. Once the server is up and running, the Geth client keeps tabs on the disk space and monitors system signals to determine when to terminate the server.
在此之后, startNode 函数执行,为 StartNode 负责实际启动服务器铺平了道路。在中找到 cmd/utils/cmd.go:72 的方法 stack.Start() 将启动节点。服务器启动并运行后,Geth 客户端会密切关注磁盘空间并监视系统信号以确定何时终止服务器。

Within the Start() method, the line err := n.openEndpoints() is responsible to open networking and RPC endpoint. Meanwhile, the n.server.Start() method, located at node/node.go:269 initiates the p2p discovery and handshake processes. Concurrently, the line err := n.startRPC() located at node/node.go:273 brings the RPC endpoint to life. The output should resemble the following:
在 Start() 该方法中,该行 err := n.openEndpoints() 负责打开网络和 RPC 终结点。同时, n.server.Start() 位于 的方法 node/node.go:269 启动 p2p 发现和握手过程。同时,位于 的 node/node.go:273 线路 err := n.startRPC() 使 RPC 终结点栩栩如生。输出应类似于以下内容:

1
2
3
4
5
6
7
8
9
INFO [09-13|13:56:00.514] Starting peer-to-peer node               instance=Geth/v1.12.1-unstable-60ce4e8d-20230810/linux-amd64/go1.20.6
INFO [09-13|13:56:04.989] New local node record                    seq=1,694,613,193,948 id=72f98ebcedb92640 ip=127.0.0.1 udp=35555 tcp=35555
INFO [09-13|13:56:05.083] Started P2P networking                   self=enode://9fc6b61a19d99e8a78ae8f8dbd12f27d208ce9b01dd52177fbfee1812a37467b3c3bab49c181b26b240f52bf1ac8afe64915f9b89465a540a74fdcb5e37f2abd@127.0.0.1:35555
INFO [09-13|13:56:05.325] Generating state snapshot                root=d7f897..0f0544 at=9a53a5..ad4ba5 accounts=5375 slots=0 storage=247.62KiB dangling=0 elapsed=8.003s     eta=28.97s
INFO [09-13|13:56:10.187] IPC endpoint opened                      url=/home/username/.ethereum/geth.ipc
INFO [09-13|13:56:10.200] Loaded JWT secret file                   path=/home/username/.ethereum/geth/jwtsecret crc32=0x3392b636
INFO [09-13|13:56:11.116] WebSocket enabled                        url=ws://127.0.0.1:8553
INFO [09-13|13:56:11.121] HTTP server started                      endpoint=127.0.0.1:8553 auth=true prefix= cors=localhost vhosts=localhost

Once the p2p network layer has been executed successfully, the crucial Ethereum protocol initiates and remains active. Two essential components stand out:
一旦 p2p 网络层成功执行,关键的以太坊协议就会启动并保持活动状态。两个基本组成部分很突出:

  • txPool: This manages transactions according to a specified strategy.
    txPool :根据指定的策略管理事务。
  • blockchain: This encompasses the EVM (Ethereum Virtual Machine) and upholds the chain structure of the blockchain.
    blockchain :这包括EVM(以太坊虚拟机)并维护区块链的链结构。

The rationale for defining the subprotocol as a slice of lifecycle is that Geth also supports other protocols layered over the Devp2p protocol.
将子协议定义为生命周期切片的基本原理是,Geth还支持在Devp2p协议上分层的其他协议。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Ethereum implements the Ethereum full node service.
type Ethereum struct {
	config *ethconfig.Config

	// Handlers
	txPool *txpool.TxPool

	blockchain         *core.BlockChain
	handler            *handler
	ethDialCandidates  enode.Iterator
	snapDialCandidates enode.Iterator
	merger             *consensus.Merger

	// DB interfaces
	chainDb ethdb.Database // Block chain database

	eventMux       *event.TypeMux
	engine         consensus.Engine
	accountManager *accounts.Manager

	bloomRequests     chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
	bloomIndexer      *core.ChainIndexer             // Bloom indexer operating during block imports
	closeBloomHandler chan struct{}

	APIBackend *EthAPIBackend

	miner     *miner.Miner
	gasPrice  *big.Int
	etherbase common.Address

	networkID     uint64
	netRPCService *ethapi.NetAPI

	p2pServer *p2p.Server

	lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)

	shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully
}

To summarize, the steps for starting a Geth client are as follows:
总而言之,启动 Geth 客户端的步骤如下:

  1. Command Line Parsing: The parser breaks down flags, subcommands, or the configuration file into a context.
    命令行解析:解析器将标志、子命令或配置文件分解为 context .
  2. Process Context: The command line context is processed, establishing memory cache allowances and, if enabled, metrics that monitor the runtime environment.
    处理上下文:处理命令行上下文,建立内存缓存限额,如果启用,则建立监视运行时环境的指标。
  3. Protocol Stack Assembly: Based on the provided configuration, the protocol stack is assembled into a node struct. Concurrently, interaction methods are incorporated into ethapi.Backend.
    协议栈组装:根据提供的配置,协议栈组装成节点结构。同时,交互方法被合并到 ethapi.Backend .
  4. Node Initialization:
    1. P2P Network Layer: Initiates the p2p network layer for node discovery and facilitates basic pre-subprotocol (devp2p) message exchange.
      P2P网络层:启动P2P网络层进行节点发现,促进基本的预子协议(devp2p)消息交换。
    2. RPC Endpoint: This step starts the RPC endpoint.
      RPC 终结点:此步骤启动 RPC 终结点。
    3. Subprotocols Activation: All the specified subprotocols in the lifecycles of the local node are initiated.
      子协议激活:启动本地节点生命周期内所有指定的子协议。
    4. Monitoring: Upon successful initialization, the system begins monitoring disk space and awaits system signals for termination.
      监控:成功初始化后,系统开始监控磁盘空间并等待系统信号终止。

原文始发于learner L:How Geth starts its server

版权声明:admin 发表于 2023年9月17日 下午8:51。
转载请注明:How Geth starts its server | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...