github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/init/handle_init.go (about) 1 // Copyright 2021 The TrueBlocks Authors. All rights reserved. 2 // Use of this source code is governed by a license that can 3 // be found in the LICENSE file. 4 5 package initPkg 6 7 import ( 8 "fmt" 9 "os" 10 "path/filepath" 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/history" 16 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" 17 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/manifest" 18 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output" 19 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 20 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk" 21 ) 22 23 // HandleInit initializes local copy of UnchainedIndex by downloading manifests and chunks 24 func (opts *InitOptions) HandleInit(rCtx *output.RenderCtx) error { 25 // Make the code below cleaner... 26 chain := opts.Globals.Chain 27 28 // TODO: BOGUS - IF THE SCRAPER IS RUNNING, THIS WILL CAUSE PROBLEMS 29 // Make sure that the temporary scraper folders are empty, so that, when the 30 // scraper starts, it starts on the correct block. 31 cleanList := []string{"ripe", "unripe", "maps", "staging"} 32 isHeadless := os.Getenv("TB_NODE_HEADLESS") == "true" 33 if isHeadless { 34 cleanList = []string{"ripe", "unripe"} 35 } 36 _ = file.CleanFolder(chain, config.PathToIndex(chain), cleanList) 37 38 existing, err := manifest.LoadManifest(chain, opts.PublisherAddr, manifest.LocalCache) 39 if err != nil { 40 return err 41 } 42 43 remote, err := manifest.LoadManifest(chain, opts.PublisherAddr, manifest.FromContract) 44 if err != nil { 45 return err 46 } 47 48 if err = opts.updateLocalManifest(existing, remote); err != nil { 49 return err 50 } 51 52 // Get the list of things we need to download 53 chunksToDownload, nToDownload, nDeleted, err := opts.prepareDownloadList(chain, remote, []base.Blknum{}) 54 if err != nil { 55 return err 56 } 57 58 // Tell the user what we're doing 59 logger.InfoTable("Unchained Index:", config.GetUnchained().SmartContract) 60 logger.InfoTable("PreferredPublisher:", opts.Publisher) 61 logger.InfoTable("Specification:", manifest.Specification()) 62 logger.InfoTable("Config Folder:", config.MustGetPathToChainConfig(chain)) 63 logger.InfoTable("Index Folder:", config.PathToIndex(chain)) 64 logger.InfoTable("Chunks in manifest:", fmt.Sprintf("%d", len(remote.Chunks))) 65 logger.InfoTable("Files deleted:", fmt.Sprintf("%d", nDeleted)) 66 logger.InfoTable("Files downloaded:", fmt.Sprintf("%d", nToDownload)) 67 68 historyFile := filepath.Join(config.PathToCache(chain), "tmp/history.txt") 69 if opts.All && !history.FromHistoryBool(historyFile, "init") { 70 _ = history.ToHistory(historyFile, "init", "true") 71 } 72 73 // Open a channel to receive a message when all the blooms have been downloaded... 74 bloomsDoneChannel := make(chan bool) 75 defer close(bloomsDoneChannel) 76 77 // Open a channel to receive a message when all the indexes have been downloaded (if we're downloading them) 78 indexDoneChannel := make(chan bool) 79 defer close(indexDoneChannel) 80 81 getChunks := func(chunkType walk.CacheType) { 82 failedChunks, cancelled := opts.downloadAndReportProgress(chunksToDownload, chunkType, nToDownload) 83 if cancelled { 84 // The user hit the control+c, we don't want to continue... 85 return 86 } 87 88 // The download finished... 89 if len(failedChunks) > 0 { 90 // ...if there were failed downloads, try them again (3 times if necessary)... 91 retry(failedChunks, 3, func(items []types.ChunkRecord) ([]types.ChunkRecord, bool) { 92 logger.Info("Retrying", len(items), "bloom(s)") 93 return opts.downloadAndReportProgress(items, chunkType, nToDownload) 94 }) 95 } 96 } 97 98 // Set up a go routine to download the bloom filters... 99 go func() { 100 getChunks(walk.Index_Bloom) 101 bloomsDoneChannel <- true 102 }() 103 104 // TODO: BOGUS - WHY DOES THERE NEED TO BE TWO OF THESE? 105 // Set up another go routine to download the index chunks if the user told us to... 106 go func() { 107 getChunks(walk.Index_Final) 108 indexDoneChannel <- true 109 }() 110 111 // Wait for the index to download. This will block until getChunks for index chunks returns 112 <-indexDoneChannel 113 114 // Wait for the bloom filters to download. This will block until getChunks for blooms returns 115 <-bloomsDoneChannel 116 117 if nDeleted+nToDownload > 0 { 118 logger.Warn("The on-disk index has changed. You must invalidate your monitor cache by removing it.") 119 } 120 121 return nil 122 } 123 124 // HandleShow initializes local copy of UnchainedIndex by downloading manifests and chunks 125 func (opts *InitOptions) HandleShow(rCtx *output.RenderCtx) error { 126 return opts.HandleInit(rCtx) 127 }