|
|
|
@ -142,54 +142,55 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er |
|
|
|
|
if ptd == nil { |
|
|
|
|
return NonStatTy, consensus_engine.ErrUnknownAncestor |
|
|
|
|
} |
|
|
|
|
localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64()) |
|
|
|
|
externTd := new(big.Int).Add(header.Difficulty, ptd) |
|
|
|
|
// TODO: implement fork choice mechanism
|
|
|
|
|
//localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64())
|
|
|
|
|
//externTd := new(big.Int).Add(header.Difficulty, ptd)
|
|
|
|
|
|
|
|
|
|
// Irrelevant of the canonical status, write the td and header to the database
|
|
|
|
|
if err := hc.WriteTd(hash, number, externTd); err != nil { |
|
|
|
|
log.Crit("Failed to write header total difficulty", "err", err) |
|
|
|
|
} |
|
|
|
|
//if err := hc.WriteTd(hash, number, externTd); err != nil {
|
|
|
|
|
// // log.Crit("Failed to write header total difficulty", "err", err)
|
|
|
|
|
// //}
|
|
|
|
|
//rawdb.WriteHeader(hc.chainDb, header)
|
|
|
|
|
|
|
|
|
|
// If the total difficulty is higher than our known, add it to the canonical chain
|
|
|
|
|
// Second clause in the if statement reduces the vulnerability to selfish mining.
|
|
|
|
|
// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
|
|
|
|
|
if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) { |
|
|
|
|
// Delete any canonical number assignments above the new head
|
|
|
|
|
batch := hc.chainDb.NewBatch() |
|
|
|
|
for i := number + 1; ; i++ { |
|
|
|
|
hash := rawdb.ReadCanonicalHash(hc.chainDb, i) |
|
|
|
|
if hash == (common.Hash{}) { |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
rawdb.DeleteCanonicalHash(batch, i) |
|
|
|
|
} |
|
|
|
|
batch.Write() |
|
|
|
|
|
|
|
|
|
// Overwrite any stale canonical number assignments
|
|
|
|
|
var ( |
|
|
|
|
headHash = header.ParentHash |
|
|
|
|
headNumber = header.Number.Uint64() - 1 |
|
|
|
|
headHeader = hc.GetHeader(headHash, headNumber) |
|
|
|
|
) |
|
|
|
|
for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash { |
|
|
|
|
rawdb.WriteCanonicalHash(hc.chainDb, headHash, headNumber) |
|
|
|
|
|
|
|
|
|
headHash = headHeader.ParentHash |
|
|
|
|
headNumber = headHeader.Number.Uint64() - 1 |
|
|
|
|
headHeader = hc.GetHeader(headHash, headNumber) |
|
|
|
|
} |
|
|
|
|
// Extend the canonical chain with the new header
|
|
|
|
|
rawdb.WriteCanonicalHash(hc.chainDb, hash, number) |
|
|
|
|
rawdb.WriteHeadHeaderHash(hc.chainDb, hash) |
|
|
|
|
|
|
|
|
|
hc.currentHeaderHash = hash |
|
|
|
|
hc.currentHeader.Store(types.CopyHeader(header)) |
|
|
|
|
|
|
|
|
|
status = CanonStatTy |
|
|
|
|
} else { |
|
|
|
|
status = SideStatTy |
|
|
|
|
} |
|
|
|
|
//if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) {
|
|
|
|
|
// // Delete any canonical number assignments above the new head
|
|
|
|
|
// batch := hc.chainDb.NewBatch()
|
|
|
|
|
// for i := number + 1; ; i++ {
|
|
|
|
|
// hash := rawdb.ReadCanonicalHash(hc.chainDb, i)
|
|
|
|
|
// if hash == (common.Hash{}) {
|
|
|
|
|
// break
|
|
|
|
|
// }
|
|
|
|
|
// rawdb.DeleteCanonicalHash(batch, i)
|
|
|
|
|
// }
|
|
|
|
|
// batch.Write()
|
|
|
|
|
//
|
|
|
|
|
// // Overwrite any stale canonical number assignments
|
|
|
|
|
// var (
|
|
|
|
|
// headHash = header.ParentHash
|
|
|
|
|
// headNumber = header.Number.Uint64() - 1
|
|
|
|
|
// headHeader = hc.GetHeader(headHash, headNumber)
|
|
|
|
|
// )
|
|
|
|
|
// for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash {
|
|
|
|
|
// rawdb.WriteCanonicalHash(hc.chainDb, headHash, headNumber)
|
|
|
|
|
//
|
|
|
|
|
// headHash = headHeader.ParentHash
|
|
|
|
|
// headNumber = headHeader.Number.Uint64() - 1
|
|
|
|
|
// headHeader = hc.GetHeader(headHash, headNumber)
|
|
|
|
|
// }
|
|
|
|
|
// // Extend the canonical chain with the new header
|
|
|
|
|
// rawdb.WriteCanonicalHash(hc.chainDb, hash, number)
|
|
|
|
|
// rawdb.WriteHeadHeaderHash(hc.chainDb, hash)
|
|
|
|
|
//
|
|
|
|
|
// hc.currentHeaderHash = hash
|
|
|
|
|
// hc.currentHeader.Store(types.CopyHeader(header))
|
|
|
|
|
//
|
|
|
|
|
// status = CanonStatTy
|
|
|
|
|
//} else {
|
|
|
|
|
// status = SideStatTy
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
hc.headerCache.Add(hash, header) |
|
|
|
|
hc.numberCache.Add(hash, number) |
|
|
|
|