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() { if len(os.Args) < 2 { fmt.Println("Specify a path to folder containig blockchain.dat and blockchain.new") fmt.Println("Output bootstrap.dat file will be written in the current folder.") return } blks := chain.NewBlockDB(os.Args[1]) if blks == nil { return } fmt.Println("Loading block index...") bidx = make(map[[32]byte]*chain.BlockTreeNode, 300e3) blks.LoadBlockIndex(nil, walk) var tail, nd *chain.BlockTreeNode var genesis_block_hash *btc.Uint256 for _, v := range bidx { if v == tail { // skip root block (should be only one) continue } par_hash := btc.NewUint256(v.BlockHeader[4:36]) par, ok := bidx[par_hash.Hash] if !ok { genesis_block_hash = par_hash } else { v.Parent = par if tail == nil || v.Height > tail.Height { tail = v } } } if genesis_block_hash == nil { println("genesis_block_hash not found") return } var magic []byte gen_bin, _ := hex.DecodeString(GenesisBitcoin) tmp := btc.NewSha2Hash(gen_bin[:80]) if genesis_block_hash.Equal(tmp) { println("Bitcoin genesis block") magic = []byte{0xF9, 0xBE, 0xB4, 0xD9} } if magic == nil { gen_bin, _ := hex.DecodeString(GenesisTestnet) tmp = btc.NewSha2Hash(gen_bin[:80]) if genesis_block_hash.Equal(tmp) { println("Testnet3 genesis block") magic = []byte{0x0B, 0x11, 0x09, 0x07} } } if magic == nil { println("Unknow genesis block", genesis_block_hash.String()) println("Aborting since cannot figure out the magic bytes") return } var total_data, curr_data int64 for nd = tail; nd.Parent != nil; { nd.Parent.Childs = []*chain.BlockTreeNode{nd} total_data += int64(nd.BlockSize) nd = nd.Parent } fmt.Println("Writting bootstrap.dat, height", tail.Height, " magic", hex.EncodeToString(magic)) f, _ := os.Create("bootstrap.dat") f.Write(magic) binary.Write(f, binary.LittleEndian, uint32(len(gen_bin))) f.Write(gen_bin) for { bl, _, _ := blks.BlockGet(nd.BlockHash) f.Write(magic) binary.Write(f, binary.LittleEndian, uint32(len(bl))) f.Write(bl) curr_data += int64(nd.BlockSize) if (nd.Height & 0xfff) == 0 { fmt.Printf("\r%.1f%%...", 100*float64(curr_data)/float64(total_data)) } if len(nd.Childs) == 0 { break } nd = nd.Childs[0] } fmt.Println("\rDone ") }