Procházet zdrojové kódy

大量中文注释+理解

410 před 2 roky
rodič
revize
db6d9ba02f
1 změnil soubory, kde provedl 106 přidání a 54 odebrání
  1. 106 54
      core/tx_pool.go

+ 106 - 54
core/tx_pool.go

@@ -36,21 +36,26 @@ import (
 
 const (
 	// chainHeadChanSize is the size of channel listening to ChainHeadEvent.
+	// ChainHeadEvent 事件的监听通道的大小。
 	chainHeadChanSize = 10
 
 	// txSlotSize is used to calculate how many data slots a single transaction
 	// takes up based on its size. The slots are used as DoS protection, ensuring
 	// that validating a new transaction remains a constant operation (in reality
 	// O(maxslots), where max slots are 4 currently).
+	//根据交易的大小计算单个交易占用的数据插槽数量。
+	//插槽用作防止拒绝服务(DoS)攻击的保护措施,确保验证新交易仍然是一个恒定的操作(实际上是 O(maxslots),其中 max slots 目前为 4)。
 	txSlotSize = 32 * 1024
 
 	// txMaxSize is the maximum size a single transaction can have. This field has
 	// non-trivial consequences: larger transactions are significantly harder and
 	// more expensive to propagate; larger transactions also take more resources
 	// to validate whether they fit into the pool or not.
+	//单个交易的最大大小。这个字段有着重要的影响:较大的交易在传播时更难且更昂贵;较大的交易也需要更多的资源来验证它们是否适合进入交易池。
 	txMaxSize = 4 * txSlotSize // 128KB
 
 	// txReannoMaxNum is the maximum number of transactions a reannounce action can include.
+	//重新公告(reannounce)操作中可以包含的最大交易数量。
 	txReannoMaxNum = 1024
 )
 
@@ -89,36 +94,57 @@ var (
 )
 
 var (
-	evictionInterval    = time.Minute     // Time interval to check for evictable transactions
+	//在每个时间间隔内,交易池会检查是否有过期的交易,并进行驱逐操作。
+	evictionInterval = time.Minute // Time interval to check for evictable transactions
+	//交易池统计报告的时间间隔。在每个时间间隔内,交易池会生成并报告交易池的统计信息。
 	statsReportInterval = 8 * time.Second // Time interval to report transaction pool stats
-	reannounceInterval  = time.Minute     // Time interval to check for reannounce transactions
+	//检查重新广播(reannounce)交易的时间间隔。在每个时间间隔内,交易池会检查是否有需要重新广播的交易,并进行相应的处理。
+	reannounceInterval = time.Minute // Time interval to check for reannounce transactions
 )
 
 var (
 	// Metrics for the pending pool
-	pendingDiscardMeter   = metrics.NewRegisteredMeter("txpool/pending/discard", nil)
-	pendingReplaceMeter   = metrics.NewRegisteredMeter("txpool/pending/replace", nil)
-	pendingRateLimitMeter = metrics.NewRegisteredMeter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting
-	pendingNofundsMeter   = metrics.NewRegisteredMeter("txpool/pending/nofunds", nil)   // Dropped due to out-of-funds
+	// pendingDiscardMeter 计量已决交易被丢弃的数量
+	pendingDiscardMeter = metrics.NewRegisteredMeter("txpool/pending/discard", nil)
+	// pendingReplaceMeter 计量已决交易被替换的数量
+	pendingReplaceMeter = metrics.NewRegisteredMeter("txpool/pending/replace", nil)
+	// pendingRateLimitMeter 计量由于速率限制而被丢弃的已决交易的数量
+	pendingRateLimitMeter = metrics.NewRegisteredMeter("txpool/pending/ratelimit", nil)
+	// pendingNofundsMeter 计量由于资金不足而被丢弃的已决交易的数量
+	pendingNofundsMeter = metrics.NewRegisteredMeter("txpool/pending/nofunds", nil)
 
 	// Metrics for the queued pool
-	queuedDiscardMeter   = metrics.NewRegisteredMeter("txpool/queued/discard", nil)
-	queuedReplaceMeter   = metrics.NewRegisteredMeter("txpool/queued/replace", nil)
-	queuedRateLimitMeter = metrics.NewRegisteredMeter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting
-	queuedNofundsMeter   = metrics.NewRegisteredMeter("txpool/queued/nofunds", nil)   // Dropped due to out-of-funds
-	queuedEvictionMeter  = metrics.NewRegisteredMeter("txpool/queued/eviction", nil)  // Dropped due to lifetime
+	// queuedDiscardMeter 计量排队交易被丢弃的数量
+	queuedDiscardMeter = metrics.NewRegisteredMeter("txpool/queued/discard", nil)
+	// queuedReplaceMeter 计量排队交易被替换的数量
+	queuedReplaceMeter = metrics.NewRegisteredMeter("txpool/queued/replace", nil)
+	// queuedRateLimitMeter 计量由于速率限制而被丢弃的排队交易的数量
+	queuedRateLimitMeter = metrics.NewRegisteredMeter("txpool/queued/ratelimit", nil)
+	// queuedNofundsMeter 计量由于资金不足而被丢弃的排队交易的数量
+	queuedNofundsMeter = metrics.NewRegisteredMeter("txpool/queued/nofunds", nil)
+	// queuedEvictionMeter 计量由于生命周期结束而被丢弃的排队交易的数量
+	queuedEvictionMeter = metrics.NewRegisteredMeter("txpool/queued/eviction", nil)
 
 	// General tx metrics
-	knownTxMeter       = metrics.NewRegisteredMeter("txpool/known", nil)
-	validTxMeter       = metrics.NewRegisteredMeter("txpool/valid", nil)
-	invalidTxMeter     = metrics.NewRegisteredMeter("txpool/invalid", nil)
+	// knownTxMeter 计量已知交易的数量
+	knownTxMeter = metrics.NewRegisteredMeter("txpool/known", nil)
+	// validTxMeter 计量有效交易的数量
+	validTxMeter = metrics.NewRegisteredMeter("txpool/valid", nil)
+	// invalidTxMeter 计量无效交易的数量
+	invalidTxMeter = metrics.NewRegisteredMeter("txpool/invalid", nil)
+	// underpricedTxMeter 计量低价交易的数量
 	underpricedTxMeter = metrics.NewRegisteredMeter("txpool/underpriced", nil)
-	overflowedTxMeter  = metrics.NewRegisteredMeter("txpool/overflowed", nil)
+	// overflowedTxMeter 计量溢出交易的数量
+	overflowedTxMeter = metrics.NewRegisteredMeter("txpool/overflowed", nil)
 
+	// pendingGauge 计量当前已决交易的数量
 	pendingGauge = metrics.NewRegisteredGauge("txpool/pending", nil)
-	queuedGauge  = metrics.NewRegisteredGauge("txpool/queued", nil)
-	localGauge   = metrics.NewRegisteredGauge("txpool/local", nil)
-	slotsGauge   = metrics.NewRegisteredGauge("txpool/slots", nil)
+	// queuedGauge 计量当前排队交易的数量
+	queuedGauge = metrics.NewRegisteredGauge("txpool/queued", nil)
+	// localGauge 计量当前本地交易的数量
+	localGauge = metrics.NewRegisteredGauge("txpool/local", nil)
+	// slotsGauge 计量当前交易占用的数据槽位数量
+	slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil)
 )
 
 // TxStatus is the current status of a transaction as seen by the pool.
@@ -141,23 +167,23 @@ type blockChain interface {
 	SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
 }
 
-// TxPoolConfig are the configuration parameters of the transaction pool.
+// TxPoolConfig 是交易池的配置参数。
 type TxPoolConfig struct {
-	Locals    []common.Address // Addresses that should be treated by default as local
-	NoLocals  bool             // Whether local transaction handling should be disabled
-	Journal   string           // Journal of local transactions to survive node restarts
-	Rejournal time.Duration    // Time interval to regenerate the local transaction journal
+	Locals    []common.Address // 默认情况下应被视为本地交易的地址列表
+	NoLocals  bool             // 是否禁用本地交易处理
+	Journal   string           // 本地交易日志,用于在节点重启后恢复
+	Rejournal time.Duration    // 重新生成本地交易日志的时间间隔
 
-	PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool
-	PriceBump  uint64 // Minimum price bump percentage to replace an already existing transaction (nonce)
+	PriceLimit uint64 // 最小的 gas 价格以确保交易被接受到交易池中
+	PriceBump  uint64 // 用于替换已存在交易的最小价格增幅百分比(按 nonce 排序)
 
-	AccountSlots uint64 // Number of executable transaction slots guaranteed per account
-	GlobalSlots  uint64 // Maximum number of executable transaction slots for all accounts
-	AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account
-	GlobalQueue  uint64 // Maximum number of non-executable transaction slots for all accounts
+	AccountSlots uint64 // 每个账户保证的可执行交易槽位数量
+	GlobalSlots  uint64 // 所有账户可执行交易槽位的最大数量
+	AccountQueue uint64 // 每个账户允许的非可执行交易槽位的最大数量
+	GlobalQueue  uint64 // 所有账户非可执行交易槽位的最大数量
 
-	Lifetime       time.Duration // Maximum amount of time non-executable transaction are queued
-	ReannounceTime time.Duration // Duration for announcing local pending transactions again
+	Lifetime       time.Duration // 非可执行交易在排队中的最大时间
+	ReannounceTime time.Duration // 本地已决交易再次宣布的时间间隔
 }
 
 // DefaultTxPoolConfig contains the default configurations for the transaction
@@ -221,39 +247,37 @@ func (config *TxPoolConfig) sanitize() TxPoolConfig {
 	return conf
 }
 
-// TxPool contains all currently known transactions. Transactions
-// enter the pool when they are received from the network or submitted
-// locally. They exit the pool when they are included in the blockchain.
+// TxPool 包含了当前已知的所有交易。当交易从网络接收或本地提交时,它们会进入交易池。
+// 当交易被包含在区块链中时,它们会从交易池中移除。
 //
-// The pool separates processable transactions (which can be applied to the
-// current state) and future transactions. Transactions move between those
-// two states over time as they are received and processed.
+// 交易池将交易分为可处理交易(可应用于当前状态)和未来交易。
+// 随着交易的接收和处理,交易会在这两种状态之间移动。
 type TxPool struct {
 	config       TxPoolConfig
 	chainconfig  *params.ChainConfig
 	chain        blockChain
 	gasPrice     *big.Int
 	txFeed       event.Feed
-	reannoTxFeed event.Feed // Event feed for announcing transactions again
+	reannoTxFeed event.Feed // 用于重新宣布交易的事件订阅
 	scope        event.SubscriptionScope
 	signer       types.Signer
 	mu           sync.RWMutex
 
-	istanbul bool // Fork indicator whether we are in the istanbul stage.
-	eip2718  bool // Fork indicator whether we are using EIP-2718 type transactions.
+	istanbul bool // 是否处于伊斯坦布尔阶段的标志。
+	eip2718  bool // 是否使用 EIP-2718 类型的交易的标志。
 
-	currentState  *state.StateDB // Current state in the blockchain head
-	pendingNonces *txNoncer      // Pending state tracking virtual nonces
-	currentMaxGas uint64         // Current gas limit for transaction caps
+	currentState  *state.StateDB // 区块链头中的当前状态
+	pendingNonces *txNoncer      // 跟踪虚拟 nonce 的待处理状态
+	currentMaxGas uint64         // 当前的 gas 限制,用于交易费用上限
 
-	locals  *accountSet // Set of local transaction to exempt from eviction rules
-	journal *txJournal  // Journal of local transaction to back up to disk
+	locals  *accountSet // 免受淘汰规则限制的本地交易集合
+	journal *txJournal  // 本地交易日志,用于备份到磁盘
 
-	pending map[common.Address]*txList   // All currently processable transactions
-	queue   map[common.Address]*txList   // Queued but non-processable transactions
-	beats   map[common.Address]time.Time // Last heartbeat from each known account
-	all     *txLookup                    // All transactions to allow lookups
-	priced  *txPricedList                // All transactions sorted by price
+	pending map[common.Address]*txList   // 当前所有可处理交易
+	queue   map[common.Address]*txList   // 排队但无法处理的交易
+	beats   map[common.Address]time.Time // 每个已知账户的最后心跳时间
+	all     *txLookup                    // 所有交易,用于快速查找
+	priced  *txPricedList                // 按价格排序的所有交易
 
 	chainHeadCh     chan ChainHeadEvent
 	chainHeadSub    event.Subscription
@@ -261,8 +285,8 @@ type TxPool struct {
 	reqPromoteCh    chan *accountSet
 	queueTxEventCh  chan *types.Transaction
 	reorgDoneCh     chan chan struct{}
-	reorgShutdownCh chan struct{}  // requests shutdown of scheduleReorgLoop
-	wg              sync.WaitGroup // tracks loop, scheduleReorgLoop
+	reorgShutdownCh chan struct{}  // 请求关闭 scheduleReorgLoop
+	wg              sync.WaitGroup // 追踪循环和 scheduleReorgLoop
 }
 
 type txpoolResetRequest struct {
@@ -819,10 +843,9 @@ func (pool *TxPool) AddLocal(tx *types.Transaction) error {
 }
 
 func (pool *TxPool) AddLocalFast(tx *types.Transaction) error {
-	pool.mu.Lock()
 	//这里进行tx的添加插播
+	pool.mu.Lock()
 	pool.all.Add(tx, true)
-	pool.priced.Put(tx, true)
 	pool.queueTxEvent(tx)
 	pool.mu.Unlock()
 	return nil
@@ -1039,6 +1062,17 @@ func (pool *TxPool) requestPromoteExecutables(set *accountSet) chan struct{} {
 }
 
 // queueTxEvent enqueues a transaction event to be sent in the next reorg run.
+// 函数 queueTxEvent 用于将交易事件加入到下一次重新组织(reorg)运行中。
+// 在以太坊中,重新组织是指区块链的分叉和重组过程。当发生区块链重组时,之前加入交易池但尚未执行的交易可能会发生状态变化。
+// 因此,在重新组织过程中,需要重新处理这些交易。
+//
+// 具体而言,queueTxEvent 函数将交易对象 tx 加入到交易事件队列 pool.queueTxEventCh 中。
+// 该队列用于存储待处理的交易事件。当交易池进行重新组织时,会处理这些交易事件以确保交易状态的一致性。
+//
+// 在函数的实现中,使用了一个非阻塞的 select 语句,尝试将交易事件发送到 pool.queueTxEventCh。
+// 如果成功发送,则交易事件被加入到队列中。如果在发送时发现 pool.reorgShutdownCh 通道已关闭(即重新组织过程被关闭),则会立即退出函数。
+//
+// 总之,queueTxEvent 函数用于将待处理的交易事件加入到队列中,以便在重新组织过程中进行处理。这有助于保持交易池中交易状态的一致性。
 func (pool *TxPool) queueTxEvent(tx *types.Transaction) {
 	select {
 	case pool.queueTxEventCh <- tx:
@@ -1627,6 +1661,13 @@ func (as *accountSet) merge(other *accountSet) {
 //
 // This lookup set combines the notion of "local transactions", which is useful
 // to build upper-level structure.
+
+// txLookup 被 TxPool 内部用于在不使用互斥锁竞争的情况下跟踪交易并允许查找。
+//
+// 注意,尽管这个类型在并发访问方面受到适当的保护,但它**不是**一种应该被修改甚至在事务池之外暴露的类型,因为它的内部状态与池的内部机制紧密耦合。
+// 这个类型的唯一目的是允许在不必获取广泛范围的 TxPool.mu 互斥锁的情况下,在 TxPool.Get 中对池进行超出边界的查看。
+//
+// 这个查找集合结合了“本地交易”的概念,对于构建上层结构非常有用。
 type txLookup struct {
 	slots   int
 	lock    sync.RWMutex
@@ -1725,6 +1766,17 @@ func (t *txLookup) Slots() int {
 }
 
 // Add adds a transaction to the lookup.
+// 函数 `Add` 用于向查找表(txLookup)中添加一个交易。
+//
+// 具体而言,该函数执行以下操作:
+// 1. 获取查找表的互斥锁(t.lock)以确保并发安全。
+// 2. 根据交易的类型(local 或 remote),将交易添加到相应的映射表中。
+// - 如果交易被标记为 local,则将其添加到 `t.locals` 映射表中,使用交易的哈希(tx.Hash())作为键,交易对象(tx)作为值。
+// - 如果交易被标记为 remote,则将其添加到 `t.remotes` 映射表中,使用交易的哈希作为键,交易对象作为值。
+// 3. 更新查找表的插槽计数(t.slots),增加交易的插槽数(numSlots(tx))。
+// 4. 更新插槽计数的度量指标(slotsGauge)。
+//
+// 通过这些操作,函数将交易添加到查找表中,并相应地更新计数和度量指标。查找表可用于高效地查找和管理交易,并根据交易类型进行分类。
 func (t *txLookup) Add(tx *types.Transaction, local bool) {
 	t.lock.Lock()
 	defer t.lock.Unlock()