Skip to content

BlockChain.InsertReceiptChain (TD)

Source (upstream v1.17.3) Current
File core/blockchain.go blockchain.go
Symbol BlockChain.InsertReceiptChain BlockChain.InsertReceiptChain
Ref v1.17.3 etc/v1.17.3-full-node

Modified in-place on upstream v1.17.3: writeAncient closure uses WriteAncientBlocksPoW with real TD. Function was completely rewritten between purge4 and v1.17.3 (new locking, []rlp.RawValue receipts, sort.Search split) — diff is against upstream v1.17.3, not pre-nuke.

Diff — vs upstream v1.17.3 (modified in-place)

--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -56,7 +56,9 @@
        // Ensure genesis is in the ancient store
        if blockChain[0].NumberU64() == 1 {
            if frozen, _ := bc.db.Ancients(); frozen == 0 {
-               writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList})
+               // ETC: use PoW version to write real TD
+               td := bc.genesisBlock.Difficulty()
+               writeSize, err := rawdb.WriteAncientBlocksPoW(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}, td)
                if err != nil {
                    log.Error("Error writing genesis to ancients", "err", err)
                    return 0, err
@@ -65,8 +67,22 @@
                log.Info("Wrote genesis to ancients")
            }
        }
-       // Write all chain data to ancients.
-       writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain)
+       // ETC: use PoW version to write real TD if parent TD is available.
+       // On PoW chains a missing parent TD means the ancestor is unknown
+       // (or the TD store is corrupt); falling back to the no-TD writer
+       // would leave the ancients without difficulty and break sync. Treat
+       // it as an unknown-ancestor error instead.
+       var writeSize int64
+       var err error
+       parentTd := bc.GetTd(blockChain[0].ParentHash(), blockChain[0].NumberU64()-1)
+       if parentTd != nil {
+           td := new(big.Int).Add(parentTd, blockChain[0].Header().Difficulty)
+           writeSize, err = rawdb.WriteAncientBlocksPoW(bc.db, blockChain, receiptChain, td)
+       } else if bc.chainConfig.IsPow() {
+           return 0, consensus.ErrUnknownAncestor
+       } else {
+           writeSize, err = rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain)
+       }
        if err != nil {
            log.Error("Error importing chain data to ancients", "err", err)
            return 0, err
@@ -126,6 +142,13 @@
            rawdb.WriteBlock(batch, block)
            rawdb.WriteRawReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])

+           // ETC: Write TD for PoW chains - writeLive doesn't go through
+           // InsertHeaderChain, so TD must be written here
+           if ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1); ptd != nil {
+               externTd := new(big.Int).Add(block.Difficulty(), ptd)
+               rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), externTd)
+           }
+
            // Write everything belongs to the blocks into the database. So that
            // we can ensure all components of body is completed(body, receipts)
            // except transaction indexes(will be created once sync is finished).

← Total Difficulty (TD)