func main() { fmt.Println("Gocoin blockchain downloader version", btc.SourcesTag) parse_command_line() setup_runtime_vars() if !add_ip_str(SeedNode) { println("You need to specify IP address of a fast seed node.") println("For example run it like this: downloader -s 89.31.102.237") return } load_ips() // other seed nodes 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} DefaultTcpPort = 18333 GenesisBlock = btc.NewUint256FromString("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943") fmt.Println("Using testnet3") } else { GocoinHomeDir += "btcnet" + string(os.PathSeparator) } fmt.Println("GocoinHomeDir:", GocoinHomeDir) utils.LockDatabaseDir(GocoinHomeDir) defer utils.UnlockDatabaseDir() StartTime = time.Now() if open_blockchain() { fmt.Printf("Blockchain opening aborted\n") close_blockchain() return } fmt.Println("Blockchain open in", time.Now().Sub(StartTime)) go do_usif() fmt.Println("Downloading headers from the seed peer", SeedNode) download_headers() if GlobalExit { close_blockchain() return } if DoThePings { fmt.Println("Tuning to other peers and trying to find the fastest ones.") fmt.Println("Execute command 'g' to continue to block chain download.") fmt.Println("Otherwise it will auto-continue after 15 minutes.") usif_prompt() do_pings() fmt.Println("Pings done.") usif_prompt() } var HighestTrustedBlock *btc.Uint256 if LastTrustedBlock == "all" { HighestTrustedBlock = TheBlockChain.BlockTreeEnd.BlockHash fmt.Println("Assume all blocks trusted") } else if LastTrustedBlock == "auto" { if LastBlockHeight > 6 { ha := BlocksToGet[LastBlockHeight] HighestTrustedBlock = btc.NewUint256(ha[:]) fmt.Println("Assume last trusted block as", HighestTrustedBlock.String()) } 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 fmt.Println("All the blocks up to", TrustUpTo, "are assumed trusted") break } } } else { fmt.Println("None of the blocks is to be assumed trusted (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() close_blockchain() return }
func main() { var ptr *byte if unsafe.Sizeof(ptr) < 8 { fmt.Println("WARNING: Gocoin client shall be build for 64-bit arch. It will likely crash now.") } fmt.Println("Gocoin client version", btc.SourcesTag) runtime.GOMAXPROCS(runtime.NumCPU()) // It seems that Go does not do it by default // Disable Ctrl+C signal.Notify(killchan, os.Interrupt, os.Kill) defer func() { if r := recover(); r != nil { err, ok := r.(error) if !ok { err = fmt.Errorf("pkg: %v", r) } fmt.Println("main panic recovered:", err.Error()) fmt.Println(string(debug.Stack())) network.NetCloseAll() common.CloseBlockChain() network.ClosePeerDB() utils.UnlockDatabaseDir() os.Exit(1) } }() host_init() // This will create the DB lock file and keep it open default_wallet_fn := common.GocoinHomeDir + "wallet" + string(os.PathSeparator) + wallet.DefaultFileName fi, _ := os.Stat(default_wallet_fn) if fi == nil || fi.IsDir() { fmt.Println(default_wallet_fn, "not found") old_wallet_location := common.GocoinHomeDir + "wallet.txt" // If there is wallet.txt rename it to default. fi, _ := os.Stat(old_wallet_location) if fi != nil && !fi.IsDir() { fmt.Println("Taking wallet.txt as", default_wallet_fn) os.Rename(old_wallet_location, default_wallet_fn) } else { fmt.Println("Creating empty default wallet at", default_wallet_fn) ioutil.WriteFile(default_wallet_fn, []byte(fmt.Sprintln("# Put your wallet's public addresses here")), 0660) } } // cache the current balance of all the addresses from the current wallet files wallet.FetchAllBalances() // ... and now load the dafault wallet wallet.LoadWallet(default_wallet_fn) if wallet.MyWallet != nil { wallet.UpdateBalance() fmt.Print(wallet.DumpBalance(wallet.MyBalance, nil, false, true)) } peersTick := time.Tick(5 * time.Minute) txPoolTick := time.Tick(time.Minute) netTick := time.Tick(time.Second) network.InitPeers(common.GocoinHomeDir) common.Last.Block = common.BlockChain.BlockTreeEnd common.Last.Time = time.Unix(int64(common.Last.Block.Timestamp()), 0) if common.Last.Time.After(time.Now()) { common.Last.Time = time.Now() } for k, v := range common.BlockChain.BlockIndex { network.ReceivedBlocks[k] = &network.OneReceivedBlock{Time: time.Unix(int64(v.Timestamp()), 0)} } if common.CFG.TextUI.Enabled { go textui.MainThread() } if common.CFG.WebUI.Interface != "" { fmt.Println("Starting WebUI at", common.CFG.WebUI.Interface, "...") go webui.ServerThread(common.CFG.WebUI.Interface) } for !usif.Exit_now { common.CountSafe("MainThreadLoops") for retryCachedBlocks { retryCachedBlocks = retry_cached_blocks() // We have done one per loop - now do something else if pending... if len(network.NetBlocks) > 0 || len(usif.UiChannel) > 0 { break } } common.Busy("") select { case s := <-killchan: fmt.Println("Got signal:", s) usif.Exit_now = true continue case newbl := <-network.NetBlocks: HandleNetBlock(newbl) case newtx := <-network.NetTxs: network.HandleNetTx(newtx, false) case newal := <-network.NetAlerts: fmt.Println("\007" + newal) textui.ShowPrompt() case cmd := <-usif.UiChannel: common.Busy("UI command") cmd.Handler(cmd.Param) cmd.Done.Done() continue case <-peersTick: network.ExpirePeers() case <-txPoolTick: network.ExpireTxs() case <-netTick: network.NetworkTick() case <-time.After(time.Second / 2): common.CountSafe("MainThreadTouts") if !retryCachedBlocks { common.Busy("common.BlockChain.Idle()") common.BlockChain.Idle() } continue } common.CountSafe("NetMessagesGot") } network.NetCloseAll() network.ClosePeerDB() if usif.DefragBlocksDB { defrag_db() } common.CloseBlockChain() utils.UnlockDatabaseDir() }
func host_init() { var e error BtcRootDir := utils.BitcoinHome() if common.CFG.Datadir == "" { common.GocoinHomeDir = BtcRootDir + "gocoin" + string(os.PathSeparator) } else { common.GocoinHomeDir = common.CFG.Datadir + string(os.PathSeparator) } common.Testnet = common.CFG.Testnet // So chaging this value would will only affect the behaviour after restart if common.CFG.Testnet { // testnet3 common.GenesisBlock = btc.NewUint256FromString("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943") common.Magic = [4]byte{0x0B, 0x11, 0x09, 0x07} common.GocoinHomeDir += "tstnet" + string(os.PathSeparator) BtcRootDir += "testnet3" + string(os.PathSeparator) network.AlertPubKey, _ = hex.DecodeString("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a") common.MaxPeersNeeded = 100 } else { common.GenesisBlock = btc.NewUint256FromString("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") common.Magic = [4]byte{0xF9, 0xBE, 0xB4, 0xD9} common.GocoinHomeDir += "btcnet" + string(os.PathSeparator) network.AlertPubKey, _ = hex.DecodeString("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284") common.MaxPeersNeeded = 1000 } // Lock the folder os.MkdirAll(common.GocoinHomeDir, 0770) os.MkdirAll(common.GocoinHomeDir+"wallet", 0770) utils.LockDatabaseDir(common.GocoinHomeDir) fi, e := os.Stat(common.GocoinHomeDir + "blockchain.dat") if e != nil { os.RemoveAll(common.GocoinHomeDir) fmt.Println("You seem to be running Gocoin for the fist time on this PC") fi, e = os.Stat(BtcRootDir + "blocks/blk00000.dat") if e == nil && fi.Size() > 1024*1024 { fmt.Println("There is a database from Satoshi client on your disk...") if textui.AskYesNo("Do you want to import this database into Gocoin?") { import_blockchain(BtcRootDir + "blocks") } } } fmt.Println("Opening blockchain... (Ctrl-C to interrupt)") __exit := make(chan bool) __done := make(chan bool) go func() { for { select { case s := <-killchan: fmt.Println(s) btc.AbortNow = true case <-__exit: __done <- true return } } }() sta := time.Now().UnixNano() common.BlockChain = btc.NewChain(common.GocoinHomeDir, common.GenesisBlock, common.FLAG.Rescan) sto := time.Now().UnixNano() if btc.AbortNow { fmt.Printf("Blockchain opening aborted after %.3f seconds\n", float64(sto-sta)/1e9) common.BlockChain.Close() utils.UnlockDatabaseDir() os.Exit(1) } fmt.Printf("Blockchain open in %.3f seconds\n", float64(sto-sta)/1e9) common.BlockChain.Unspent.SetTxNotify(wallet.TxNotify) common.StartTime = time.Now() __exit <- true _ = <-__done }