dir : core/txpool/txpool.go
dirty account를 promote 대상 account로 정한다.
var promoteAddrs []common.Address
if dirtyAccounts != nil && reset == nil {
// 만약 reset이 목적이라면 모든 tx queue의 address들이 promote 되고
// flatten 작업은 진행되지 않는다.
promoteAddrs = dirtyAccounts.flatten()
}
reset 요청이 있다면 pool을 오래된 head부터 리셋하고, 재조직된 tx들을 다시 스케쥴링한다.
if reset != nil {
pool.reset(reset.oldHead, reset.newHead)
// nonce는 reset되었고, 무효화된 evt는 버려진다.
for addr := range events {
events[addr].Forward(pool.pendingNonces.get(addr))
if events[addr].Len() == 0 {
delete(events, addr)
}
}
// pool의 queue에 있던 addr들을 promote 한다.
promoteAddrs = make([]common.Address, 0, len(pool.queue))
for addr := range pool.queue {
promotesAddrs = append(promoteAddrs, addr)
}
}
각각의 account에 대해 pending tx를 확인 (promote를 진행 후, promote 된 tx들을 가져온다.)
promoted := pool.promoteExecutables(promoteAddrs)
새 블럭이 나타나면 pool의 pending tx를 검증하고, 다른 tx에 의해 무효화된 tx를 제거 후, addr들의 nonce들을 업데이트해준다.
if reset != nil {
// 처리 불가능한 tx들을 pool에서 제거
pool.demoteUnexecutables()
if reset.newHead != nil && pool.chainconfig.IsLondon(...) {
pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead)
pool.priced.SetBaseFee(pendingBaseFee)
}
// 모든 account의 nonce 값을 최신의 pending nonce로 업데이트
nonces := make(map[common.Address]uint64, len(pool.pending))
for addr, list := range pool.pending {
highestPending := list.LastElement()
nonces[addr] = highestPending.Nonce() + 1
}
pool.pendingNonce.setAll(nonces)
}
pending 중인 tx들을 초기화
pool.truncatePending()
queue에 있는 tx들을 초기화
pool.truncateQueue()