diff --git a/core/blockchain.go b/core/blockchain.go
index 2521e0cd8e58d2df9c20ac2465e5a0a7e770aa49..2fd91de3ab38a11421a76e41bcdbbc550c3acb22 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -1445,18 +1445,25 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
 	rawdb.WriteBlock(blockBatch, block)
 	rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
 
-	// storing bor block receipt
+	// System call appends state-sync logs into state. So, `state.Logs()` contains
+	// all logs including system-call logs (state sync logs) while `logs` contains
+	// only logs generated by transactions (receipts).
+	//
+	// That means that state.Logs() can have more logs than receipt logs.
+	// In that case, we can safely assume that extra logs are from state sync logs.
+	//
+	// block logs = receipt logs + state sync logs = `state.Logs()`
 	blockLogs := state.Logs()
 	if len(blockLogs) > 0 {
 		sort.SliceStable(blockLogs, func(i, j int) bool {
 			return blockLogs[i].Index < blockLogs[j].Index
 		})
-	}
 
-	if len(blockLogs) > len(logs) {
-		rawdb.WriteBorReceipt(blockBatch, block.Hash(), block.NumberU64(), &types.BorReceiptForStorage{
-			Logs: blockLogs[len(logs):],
-		})
+		if len(blockLogs) > len(logs) {
+			rawdb.WriteBorReceipt(blockBatch, block.Hash(), block.NumberU64(), &types.BorReceiptForStorage{
+				Logs: blockLogs[len(logs):], // get state-sync logs from `state.Logs()`
+			})
+		}
 	}
 
 	rawdb.WritePreimages(blockBatch, state.Preimages())
diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go
index 3690dde9af56f9f70e9e06de5b38b8372d17bcd8..cd0bd3b9708f8fec2e5517611f5ff8cb6bc27d1b 100644
--- a/core/rawdb/freezer.go
+++ b/core/rawdb/freezer.go
@@ -115,6 +115,19 @@ func newFreezer(datadir string, namespace string) (*freezer, error) {
 		}
 		freezer.tables[name] = table
 	}
+
+	// Adjust table length for bor-receipt freezer for already synced nodes.
+	//
+	// Since, table only supports sequential data, this will fill empty-data upto current
+	// synced block (till current total header number).
+	//
+	// This way they don't have to sync again from block 0 and still be compatible
+	// for block logs for future blocks. Note that already synced nodes
+	// won't have past block logs. Newly synced node will have all the data.
+	if err := freezer.tables[freezerBorReceiptTable].Fill(freezer.tables[freezerHeaderTable].items); err != nil {
+		return nil, err
+	}
+
 	if err := freezer.repair(); err != nil {
 		for _, table := range freezer.tables {
 			table.Close()
diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go
index ae7ee0cf3b17fb67c35c8acd7f207d58dd2bc496..cfbff058ce9a8df5c2072f2b04718977bc97350a 100644
--- a/core/rawdb/freezer_table.go
+++ b/core/rawdb/freezer_table.go
@@ -648,3 +648,21 @@ func (t *freezerTable) printIndex() {
 	}
 	fmt.Printf("|-----------------|\n")
 }
+
+//
+// Bor related changes
+//
+
+// Fill adds empty data till given number (convenience method for backward compatibilty)
+func (t *freezerTable) Fill(number uint64) error {
+	if t.items < number {
+		log.Info("Filling all data into freezer for backward compatablity", "name", t.name, "items", t.items, "number", number)
+		for t.items < number {
+			if err := t.Append(t.items, nil); err != nil {
+				log.Error("Failed to fill data into freezer", "name", t.name, "items", t.items, "number", number, "err", err)
+				return err
+			}
+		}
+	}
+	return nil
+}