func setup_runtime_vars() { runtime.GOMAXPROCS(runtime.NumCPU()) // It seems that Go does not do it by default if GCPerc > 0 { debug.SetGCPercent(GCPerc) } qdb.SetDefragPercent(300) //qdb.SetMaxPending(1000, 10000) }
func defrag_db() { if (usif.DefragBlocksDB & 1) != 0 { qdb.SetDefragPercent(1) fmt.Print("Defragmenting UTXO database") for { if !common.BlockChain.Unspent.Idle() { break } fmt.Print(".") } fmt.Println("done") } if (usif.DefragBlocksDB & 2) != 0 { fmt.Println("Creating empty database in", common.GocoinHomeDir+"defrag", "...") os.RemoveAll(common.GocoinHomeDir + "defrag") defragdb := chain.NewBlockDB(common.GocoinHomeDir + "defrag") fmt.Println("Defragmenting the database...") blk := common.BlockChain.BlockTreeRoot for { blk = blk.FindPathTo(common.BlockChain.BlockTreeEnd) if blk == nil { fmt.Println("Database defragmenting finished successfully") fmt.Println("To use the new DB, move the two new files to a parent directory and restart the client") break } if (blk.Height & 0xff) == 0 { fmt.Printf("%d / %d blocks written (%d%%)\r", blk.Height, common.BlockChain.BlockTreeEnd.Height, 100*blk.Height/common.BlockChain.BlockTreeEnd.Height) } bl, trusted, er := common.BlockChain.Blocks.BlockGet(blk.BlockHash) if er != nil { fmt.Println("FATAL ERROR during BlockGet:", er.Error()) break } nbl, er := btc.NewBlock(bl) if er != nil { fmt.Println("FATAL ERROR during NewBlock:", er.Error()) break } nbl.Trusted = trusted defragdb.BlockAdd(blk.Height, nbl) } defragdb.Sync() defragdb.Close() } }
func main() { fmt.Println("Gocoin blockchain downloader version", lib.Version) parse_command_line() setup_runtime_vars() if len(GocoinHomeDir) > 0 && GocoinHomeDir[len(GocoinHomeDir)-1] != os.PathSeparator { GocoinHomeDir += string(os.PathSeparator) } if Testnet { GocoinHomeDir += "tstnet" + string(os.PathSeparator) Magic = [4]byte{0x0B, 0x11, 0x09, 0x07} GenesisBlock = btc.NewUint256FromString("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943") fmt.Println("Using testnet3") } else { GocoinHomeDir += "btcnet" + string(os.PathSeparator) } fmt.Println("GocoinHomeDir:", GocoinHomeDir) sys.LockDatabaseDir(GocoinHomeDir) defer sys.UnlockDatabaseDir() peersdb.Testnet = Testnet peersdb.InitPeers(GocoinHomeDir) StartTime = time.Now() if open_blockchain() { fmt.Printf("Blockchain opening aborted\n") return } fmt.Println("Blockchain open in", time.Now().Sub(StartTime)) go do_usif() download_headers() if GlobalExit() { TheBlockChain.Close() return } var HighestTrustedBlock *btc.Uint256 if LastTrustedBlock == "all" { HighestTrustedBlock = TheBlockChain.BlockTreeEnd.BlockHash fmt.Println("Assume all blocks trusted") } else if LastTrustedBlock == "auto" { if LastBlockHeight > 6 { use := LastBlockHeight - 6 ha := BlocksToGet[use] HighestTrustedBlock = btc.NewUint256(ha[:]) fmt.Println("Assume last trusted block as", HighestTrustedBlock.String(), "at", use) } else { fmt.Println("-t=auto ignored since LastBlockHeight is only", LastBlockHeight) } } else if LastTrustedBlock != "" { HighestTrustedBlock = btc.NewUint256FromString(LastTrustedBlock) } if HighestTrustedBlock != nil { for k, h := range BlocksToGet { if bytes.Equal(h[:], HighestTrustedBlock.Hash[:]) { TrustUpTo = k break } } } else { fmt.Println("WARNING: The trusted block not found (it will be very slow).") } for n := TheBlockChain.BlockTreeEnd; n != nil && n.Height > TheBlockChain.BlockTreeEnd.Height-BSLEN; n = n.Parent { blocksize_update(int(n.BlockSize)) } fmt.Println("Downloading blocks - BlocksToGet:", len(BlocksToGet), " avg_size:", avg_block_size()) usif_prompt() StartTime = time.Now() get_blocks() fmt.Println("Up to block", TheBlockChain.BlockTreeEnd.Height, "in", time.Now().Sub(StartTime).String()) close_all_connections() peersdb.ClosePeerDB() StartTime = time.Now() fmt.Print("All blocks done - defrag unspent") qdb.SetDefragPercent(100) for { if !TheBlockChain.Unspent.Idle() { break } fmt.Print(".") } fmt.Println("\nDefrag unspent done in", time.Now().Sub(StartTime).String()) TheBlockChain.Close() return }