dir : miner/worker.go
작업 결과물(block)을 resultCh를 통해 받는다.
for {
select {
// 작업 결과물을 받은 경우
case block := <- w.resultCh:
// 내용물이 없다면 or 있는 block이라면 시행 종료
if block == nil { continue }
if w.chain.HasBlock(block.hash(), blockNumberU64()) { continue }
// block의 정보를 변수에 저장
var (
sealhash = w.engine.SealHash(block.header())
hash = block.hash()
)
// ...중략
// 진행중인 task 확인
task, exist := w.pendingTasks[sealhash]
// 진행중인 task가 없다면 이번 시행 종료
if !exist {
log.Error(...)
continue
}
// tx의 receipt, log 처리
var (
receipts = make([]*types.Receipt, len(task.receipts))
logs []*types.Log
)
// 처리된 tx의 receipt 처리
for i, taskReceipt := range task.receipts {
receipt := new(types.Receipt)
receipts[i] = receipt
*receipt = *taskReceipt
// add block location field
receipt.BlockHash = hash
receipt.BlockNumber = block.Number()
receipt.TransactionIndex = uint(i)
// ...log 관련 처리
logs = append(logs, receipt.Logs...)
}
// 주어진 block, 관련된 모든 state를 db에 추가 후,
// block을 새로운 cahain head로 apply
_, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true)
// > dir : core/blockchain.go
// ...중략
// block을 broadcast, chain insertion event를 announce
w.mux.Post(core.NewMinedBlockEvent{Block: block})
// confirmation을 위해 pending block 목록에 만든 block을 추가
w.unconfirmed.Insert(block.NumberU64(), block.Hash())
// dir : miner/confirmed.go
case <-w.exitCh:
return
}
}