github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/tslib/repair.go (about) 1 package tslib 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "fmt" 7 "io" 8 "os" 9 "path/filepath" 10 "unsafe" 11 12 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 13 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 14 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" 15 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" 16 ) 17 18 // Repair repairs a single timestamp 19 func Repair(chain string, bn base.Blknum) error { 20 cnt, err := NTimestamps(chain) 21 if err != nil { 22 return err 23 } 24 if bn >= cnt { 25 msg := fmt.Sprintf("Block number %d out of range %d", bn, cnt) 26 return errors.New(msg) 27 } 28 29 tsFn := config.PathToTimestamps(chain) 30 tmpPath := filepath.Join(config.PathToCache(chain), "tmp") 31 if backup, err := file.MakeBackup(tmpPath, tsFn); err == nil { 32 defer func() { 33 ClearCache(chain) 34 backup.Restore() 35 }() 36 37 if fp, err := os.OpenFile(tsFn, os.O_RDWR|os.O_CREATE, 0644); err == nil { 38 defer func() { // defers are last in, first out 39 fp.Close() 40 // sigintTrap.Disable(trapCh) 41 // writeMutex.Unlock() 42 }() 43 44 recordSize := int64(unsafe.Sizeof(uint32(0))) * 2 45 pos := (recordSize * int64(bn)) 46 _, _ = fp.Seek(pos, io.SeekStart) 47 48 conn := rpc.TempConnection(chain) 49 block, _ := conn.GetBlockHeaderByNumber(bn) 50 record := TimestampRecord{Bn: uint32(block.BlockNumber), Ts: uint32(block.Timestamp)} 51 err = binary.Write(fp, binary.LittleEndian, &record) 52 if err != nil { 53 return err 54 } 55 _ = fp.Sync() // probably redundant 56 57 backup.Clear() 58 return nil 59 } else { 60 return err 61 } 62 } else { 63 return err 64 } 65 }