Skip to content

Commit d1e93db

Browse files
committed
core, miner: added write block method & changed mining propagation
1 parent 059a1e9 commit d1e93db

File tree

2 files changed

+95
-73
lines changed

2 files changed

+95
-73
lines changed

core/chain_manager.go

Lines changed: 67 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,58 @@ func (self *ChainManager) procFutureBlocks() {
548548
}
549549
}
550550

551+
type writeStatus byte
552+
553+
const (
554+
nonStatTy writeStatus = iota
555+
canonStatTy
556+
splitStatTy
557+
sideStatTy
558+
)
559+
560+
func (self *ChainManager) WriteBlock(block *types.Block) (status writeStatus, err error) {
561+
self.wg.Add(1)
562+
defer self.wg.Done()
563+
564+
cblock := self.currentBlock
565+
// Compare the TD of the last known block in the canonical chain to make sure it's greater.
566+
// At this point it's possible that a different chain (fork) becomes the new canonical chain.
567+
if block.Td.Cmp(self.Td()) > 0 {
568+
// chain fork
569+
if block.ParentHash() != cblock.Hash() {
570+
// during split we merge two different chains and create the new canonical chain
571+
err := self.merge(cblock, block)
572+
if err != nil {
573+
return nonStatTy, err
574+
}
575+
576+
status = splitStatTy
577+
}
578+
579+
self.mu.Lock()
580+
self.setTotalDifficulty(block.Td)
581+
self.insert(block)
582+
self.mu.Unlock()
583+
584+
self.setTransState(state.New(block.Root(), self.stateDb))
585+
self.txState.SetState(state.New(block.Root(), self.stateDb))
586+
587+
status = canonStatTy
588+
} else {
589+
status = sideStatTy
590+
}
591+
592+
// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
593+
// not in the canonical chain.
594+
self.mu.Lock()
595+
self.write(block)
596+
self.mu.Unlock()
597+
// Delete from future blocks
598+
self.futureBlocks.Delete(block.Hash())
599+
600+
return
601+
}
602+
551603
// InsertChain will attempt to insert the given chain in to the canonical chain or, otherwise, create a fork. It an error is returned
552604
// it will return the index number of the failing block as well an error describing what went wrong (for possible errors see core/errors.go).
553605
func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
@@ -641,59 +693,29 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
641693

642694
txcount += len(block.Transactions())
643695

644-
cblock := self.currentBlock
645-
// Compare the TD of the last known block in the canonical chain to make sure it's greater.
646-
// At this point it's possible that a different chain (fork) becomes the new canonical chain.
647-
if block.Td.Cmp(self.Td()) > 0 {
648-
// chain fork
649-
if block.ParentHash() != cblock.Hash() {
650-
// during split we merge two different chains and create the new canonical chain
651-
err := self.merge(cblock, block)
652-
if err != nil {
653-
return i, err
654-
}
655-
656-
queue[i] = ChainSplitEvent{block, logs}
657-
queueEvent.splitCount++
658-
}
659-
660-
self.mu.Lock()
661-
self.setTotalDifficulty(block.Td)
662-
self.insert(block)
663-
self.mu.Unlock()
664-
665-
jsonlogger.LogJson(&logger.EthChainNewHead{
666-
BlockHash: block.Hash().Hex(),
667-
BlockNumber: block.Number(),
668-
ChainHeadHash: cblock.Hash().Hex(),
669-
BlockPrevHash: block.ParentHash().Hex(),
670-
})
671-
672-
self.setTransState(state.New(block.Root(), self.stateDb))
673-
self.txState.SetState(state.New(block.Root(), self.stateDb))
674-
675-
queue[i] = ChainEvent{block, block.Hash(), logs}
676-
queueEvent.canonicalCount++
677-
696+
// write the block to the chain and get the status
697+
status, err := self.WriteBlock(block)
698+
if err != nil {
699+
return i, err
700+
}
701+
switch status {
702+
case canonStatTy:
678703
if glog.V(logger.Debug) {
679704
glog.Infof("[%v] inserted block #%d (%d TXs %d UNCs) (%x...). Took %v\n", time.Now().UnixNano(), block.Number(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart))
680705
}
681-
} else {
706+
queue[i] = ChainEvent{block, block.Hash(), logs}
707+
queueEvent.canonicalCount++
708+
case sideStatTy:
682709
if glog.V(logger.Detail) {
683710
glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart))
684711
}
685-
686712
queue[i] = ChainSideEvent{block, logs}
687713
queueEvent.sideCount++
714+
case splitStatTy:
715+
queue[i] = ChainSplitEvent{block, logs}
716+
queueEvent.splitCount++
688717
}
689-
// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
690-
// not in the canonical chain.
691-
self.write(block)
692-
// Delete from future blocks
693-
self.futureBlocks.Delete(block.Hash())
694-
695718
stats.processed++
696-
blockInsertTimer.UpdateSince(bstart)
697719
}
698720

699721
if (stats.queued > 0 || stats.processed > 0 || stats.ignored > 0) && bool(glog.V(logger.Info)) {
@@ -752,9 +774,9 @@ func (self *ChainManager) diff(oldBlock, newBlock *types.Block) (types.Blocks, e
752774
}
753775
}
754776

755-
if glog.V(logger.Info) {
777+
if glog.V(logger.Debug) {
756778
commonHash := commonBlock.Hash()
757-
glog.Infof("Fork detected @ %x. Reorganising chain from #%v %x to %x", commonHash[:4], numSplit, oldStart.Hash().Bytes()[:4], newStart.Hash().Bytes()[:4])
779+
glog.Infof("Chain split detected @ %x. Reorganising chain from #%v %x to %x", commonHash[:4], numSplit, oldStart.Hash().Bytes()[:4], newStart.Hash().Bytes()[:4])
758780
}
759781

760782
return newChain, nil

miner/worker.go

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -239,43 +239,35 @@ func (self *worker) wait() {
239239
continue
240240
}
241241

242-
// broadcast before waiting for validation
243-
go self.mux.Post(core.NewMinedBlockEvent{block})
244-
// insert mined block in to our own chain
245-
if _, err := self.chain.InsertChain(types.Blocks{block}); err == nil {
246-
// remove uncles we've previously inserted
247-
for _, uncle := range block.Uncles() {
248-
delete(self.possibleUncles, uncle.Hash())
249-
}
250-
251-
// check staleness and display confirmation
252-
var stale, confirm string
253-
canonBlock := self.chain.GetBlockByNumber(block.NumberU64())
254-
if canonBlock != nil && canonBlock.Hash() != block.Hash() {
255-
stale = "stale "
256-
} else {
257-
confirm = "Wait 5 blocks for confirmation"
258-
self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks)
259-
}
260-
261-
glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm)
242+
_, err := self.chain.WriteBlock(block)
243+
if err != nil {
244+
glog.V(logger.Error).Infoln("error writing block to chain", err)
245+
continue
246+
}
262247

263-
// XXX remove old structured json logging
264-
jsonlogger.LogJson(&logger.EthMinerNewBlock{
265-
BlockHash: block.Hash().Hex(),
266-
BlockNumber: block.Number(),
267-
ChainHeadHash: block.ParentHeaderHash.Hex(),
268-
BlockPrevHash: block.ParentHeaderHash.Hex(),
269-
})
248+
// check staleness and display confirmation
249+
var stale, confirm string
250+
canonBlock := self.chain.GetBlockByNumber(block.NumberU64())
251+
if canonBlock != nil && canonBlock.Hash() != block.Hash() {
252+
stale = "stale "
270253
} else {
271-
self.commitNewWork()
254+
confirm = "Wait 5 blocks for confirmation"
255+
self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks)
272256
}
257+
258+
glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm)
259+
260+
// broadcast before waiting for validation
261+
go self.mux.Post(core.NewMinedBlockEvent{block})
262+
263+
self.commitNewWork()
273264
}
274265
}
275266
}
276267

277268
func (self *worker) push() {
278269
if atomic.LoadInt32(&self.mining) == 1 {
270+
self.current.state.Sync()
279271
self.current.block.SetRoot(self.current.state.Root())
280272

281273
// push new work to agents
@@ -302,6 +294,13 @@ func (self *worker) makeCurrent() {
302294
if block.Time() <= parent.Time() {
303295
block.Header().Time = parent.Header().Time + 1
304296
}
297+
// this will ensure we're not going off too far in the future
298+
if now := time.Now().Unix(); block.Time() > now+4 {
299+
wait := time.Duration(block.Time()-now) * time.Second
300+
glog.V(logger.Info).Infoln("We are too far in the future. Waiting for", wait)
301+
time.Sleep(wait)
302+
}
303+
305304
block.Header().Extra = self.extra
306305

307306
// when 08 is processed ancestors contain 07 (quick block)
@@ -428,6 +427,7 @@ func (self *worker) commitNewWork() {
428427
self.current.block.SetUncles(uncles)
429428

430429
core.AccumulateRewards(self.current.state, self.current.block)
430+
self.current.block.Td = new(big.Int).Set(core.CalcTD(self.current.block, self.chain.GetBlock(self.current.block.ParentHash())))
431431

432432
self.current.state.Update()
433433

0 commit comments

Comments
 (0)