// Called from the blockchain thread func HandleNetBlock(newbl *network.BlockRcvd) { common.CountSafe("HandleNetBlock") bl := newbl.Block common.Busy("CheckBlock " + bl.Hash.String()) e, dos, maybelater := common.BlockChain.CheckBlock(bl) if e != nil { if maybelater { network.AddBlockToCache(bl, newbl.Conn) } else { fmt.Println(dos, e.Error()) if dos { newbl.Conn.DoS("CheckBlock") } } } else { common.Busy("LocalAcceptBlock " + bl.Hash.String()) e = LocalAcceptBlock(bl, newbl.Conn) if e == nil { retryCachedBlocks = retry_cached_blocks() } else { fmt.Println("AcceptBlock:", e.Error()) newbl.Conn.DoS("LocalAcceptBl") } } }
func retry_cached_blocks() bool { if len(network.CachedBlocks) == 0 { return false } accepted_cnt := 0 for k, v := range network.CachedBlocks { common.Busy("Cache.CheckBlock " + v.Block.Hash.String()) e, dos, maybelater := common.BlockChain.CheckBlock(v.Block) if e == nil { common.Busy("Cache.AcceptBlock " + v.Block.Hash.String()) e := LocalAcceptBlock(v.Block, v.Conn) if e == nil { //fmt.Println("*** Old block accepted", common.BlockChain.BlockTreeEnd.Height) common.CountSafe("BlocksFromCache") delete(network.CachedBlocks, k) accepted_cnt++ break // One at a time should be enough } else { fmt.Println("retry AcceptBlock:", e.Error()) v.Conn.DoS("BadCachedBlock1") delete(network.CachedBlocks, k) } } else { if !maybelater { fmt.Println("retry CheckBlock:", e.Error()) common.CountSafe("BadCachedBlocks") if dos { v.Conn.DoS("BadCachedBlock2") } delete(network.CachedBlocks, k) } } } return accepted_cnt > 0 && len(network.CachedBlocks) > 0 }
func retry_cached_blocks() bool { var idx int common.CountSafe("RedoCachedBlks") for idx < len(network.CachedBlocks) { newbl := network.CachedBlocks[idx] if CheckParentDiscarded(newbl.BlockTreeNode) { common.CountSafe("DiscardCachedBlock") network.CachedBlocks = append(network.CachedBlocks[:idx], network.CachedBlocks[idx+1:]...) return len(network.CachedBlocks) > 0 } if common.BlockChain.HasAllParents(newbl.BlockTreeNode) { common.Busy("Cache.LocalAcceptBlock " + newbl.Block.Hash.String()) e := LocalAcceptBlock(newbl) if e != nil { fmt.Println("AcceptBlock:", e.Error()) newbl.Conn.DoS("LocalAcceptBl") } if usif.Exit_now { return false } // remove it from cache network.CachedBlocks = append(network.CachedBlocks[:idx], network.CachedBlocks[idx+1:]...) return len(network.CachedBlocks) > 0 } else { idx++ } } return false }
// Freshly mined block - do the inv and beeps... TODO: combine it with the other code func new_block_mined(bl *btc.Block, conn *network.OneConnection) { common.Busy("NetRouteInv") network.NetRouteInv(2, bl.Hash, conn) if common.CFG.Beeps.NewBlock { fmt.Println("\007Received block", common.BlockChain.BlockTreeEnd.Height) textui.ShowPrompt() } if common.CFG.Beeps.MinerID != "" { //_, rawtxlen := btc.NewTx(bl[bl.TxOffset:]) if bytes.Contains(bl.Txs[0].Serialize(), []byte(common.CFG.Beeps.MinerID)) { fmt.Println("\007Mined by '"+common.CFG.Beeps.MinerID+"':", bl.Hash) textui.ShowPrompt() } } if common.CFG.Beeps.ActiveFork && common.Last.Block == common.BlockChain.BlockTreeEnd { // Last block has not changed, so it must have been an orphaned block bln := common.BlockChain.BlockIndex[bl.Hash.BIdx()] commonNode := common.Last.Block.FirstCommonParent(bln) forkDepth := bln.Height - commonNode.Height fmt.Println("Orphaned block:", bln.Height, bl.Hash.String(), bln.BlockSize>>10, "KB") if forkDepth > 1 { fmt.Println("\007\007\007WARNING: the fork is", forkDepth, "blocks deep") } textui.ShowPrompt() } }
// Called from the blockchain thread func HandleNetBlock(newbl *network.BlockRcvd) { if CheckParentDiscarded(newbl.BlockTreeNode) { common.CountSafe("DiscardFreshBlockA") retryCachedBlocks = len(network.CachedBlocks) > 0 return } if !common.BlockChain.HasAllParents(newbl.BlockTreeNode) { // it's not linking - keep it for later network.CachedBlocks = append(network.CachedBlocks, newbl) common.CountSafe("BlockPostone") return } common.Busy("LocalAcceptBlock " + newbl.Hash.String()) e := LocalAcceptBlock(newbl) if e != nil { common.CountSafe("DiscardFreshBlockB") fmt.Println("AcceptBlock:", e.Error()) newbl.Conn.DoS("LocalAcceptBl") } else { //println("block", newbl.Block.Height, "accepted") retryCachedBlocks = retry_cached_blocks() } }
func LocalAcceptBlock(bl *btc.Block, from *network.OneConnection) (e error) { sta := time.Now() e = common.BlockChain.AcceptBlock(bl) if e == nil { network.MutexRcv.Lock() network.ReceivedBlocks[bl.Hash.BIdx()].TmAccept = time.Now().Sub(sta) network.MutexRcv.Unlock() for i := 1; i < len(bl.Txs); i++ { network.TxMined(bl.Txs[i].Hash) } if int64(bl.BlockTime) > time.Now().Add(-10*time.Minute).Unix() { // Freshly mined block - do the inv and beeps... common.Busy("NetRouteInv") network.NetRouteInv(2, bl.Hash, from) if common.CFG.Beeps.NewBlock { fmt.Println("\007Received block", common.BlockChain.BlockTreeEnd.Height) textui.ShowPrompt() } if common.MinedByUs(bl.Raw) { fmt.Println("\007Mined by '"+common.CFG.Beeps.MinerID+"':", bl.Hash) textui.ShowPrompt() } if common.CFG.Beeps.ActiveFork && common.Last.Block == common.BlockChain.BlockTreeEnd { // Last block has not changed, so it must have been an orphaned block bln := common.BlockChain.BlockIndex[bl.Hash.BIdx()] commonNode := common.Last.Block.FirstCommonParent(bln) forkDepth := bln.Height - commonNode.Height fmt.Println("Orphaned block:", bln.Height, bl.Hash.String()) if forkDepth > 1 { fmt.Println("\007\007\007WARNING: the fork is", forkDepth, "blocks deep") } textui.ShowPrompt() } if wallet.BalanceChanged && common.CFG.Beeps.NewBalance { fmt.Print("\007") } } common.Last.Mutex.Lock() common.Last.Time = time.Now() common.Last.Block = common.BlockChain.BlockTreeEnd common.Last.Mutex.Unlock() if wallet.BalanceChanged { wallet.BalanceChanged = false fmt.Println("Your balance has just changed") fmt.Print(wallet.DumpBalance(nil, false)) textui.ShowPrompt() } } else { fmt.Println("Warning: AcceptBlock failed. If the block was valid, you may need to rebuild the unspent DB (-r)") } 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 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", gocoin.Version) 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(false) peersdb.ClosePeerDB() sys.UnlockDatabaseDir() os.Exit(1) } }() common.InitConfig() if common.FLAG.VolatileUTXO { fmt.Println("WARNING! Using UTXO database in a volatile mode. Make sure to close the client properly (do not kill it!)") } if common.FLAG.TrustAll { fmt.Println("WARNING! Assuming all scripts inside new blocks to PASS. Verify the last block's hash when finished.") } host_init() // This will create the DB lock file and keep it open if common.FLAG.UndoBlocks > 0 { usif.Exit_now = true } if common.FLAG.Rescan && common.FLAG.VolatileUTXO { fmt.Println("UTXO database rebuilt complete in the volatile mode, so flush DB to disk and exit...") } else if !usif.Exit_now { common.RecalcAverageBlockSize(true) peersTick := time.Tick(5 * time.Minute) txPoolTick := time.Tick(time.Minute) netTick := time.Tick(time.Second) peersdb.Testnet = common.Testnet peersdb.ConnectOnly = common.CFG.ConnectOnly peersdb.Services = common.Services peersdb.InitPeers(common.GocoinHomeDir) if common.FLAG.UnbanAllPeers { var keys []qdb.KeyType var vals [][]byte peersdb.PeerDB.Browse(func(k qdb.KeyType, v []byte) uint32 { peer := utils.NewPeer(v) if peer.Banned != 0 { fmt.Println("Unban", peer.NetAddr.String()) peer.Banned = 0 keys = append(keys, k) vals = append(vals, peer.Bytes()) } return 0 }) for i := range keys { peersdb.PeerDB.Put(keys[i], vals[i]) } fmt.Println(len(keys), "peerts un-baned") } 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{TmStart: time.Unix(int64(v.Timestamp()), 0)} } network.LastCommitedHeader = common.Last.Block 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) } if common.CFG.RPC.Enabled { go rpcapi.StartServer(common.RPCPort()) } 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 rpcbl := <-rpcapi.RpcBlocks: common.CountSafe("RPCNewBlock") common.Busy("HandleRpcBlock()") HandleRpcBlock(rpcbl) case rec := <-usif.LocksChan: common.CountSafe("MainLocks") common.Busy("LockedByRequest") rec.In.Done() rec.Out.Wait() continue case newbl := <-network.NetBlocks: common.CountSafe("MainNetBlock") common.Busy("HandleNetBlock()") HandleNetBlock(newbl) case <-syncNow: common.CountSafe("MainChainSync") common.Busy("BlockChain.Sync()") common.BlockChain.Sync() case newtx := <-network.NetTxs: common.CountSafe("MainNetTx") common.Busy("network.HandleNetTx()") network.HandleNetTx(newtx, false) case <-netTick: common.CountSafe("MainNetTick") common.Busy("network.NetworkTick()") network.NetworkTick() case cmd := <-usif.UiChannel: common.CountSafe("MainUICmd") common.Busy("UI command") cmd.Handler(cmd.Param) cmd.Done.Done() continue case <-peersTick: common.Busy("peersdb.ExpirePeers()") peersdb.ExpirePeers() case <-txPoolTick: common.Busy("network.ExpireTxs()") network.ExpireTxs() case <-time.After(time.Second / 2): common.CountSafe("MainThreadTouts") if !retryCachedBlocks { if usif.DefragUTXO { usif.Exit_now = true break } common.Busy("BlockChain.Idle()") if common.BlockChain.Idle() { common.CountSafe("ChainIdleUsed") } } continue } } network.NetCloseAll() } if usif.DefragUTXO { fmt.Println("Closing blockchain while defragmenting UTXO") } else { fmt.Println("Closing blockchain") } sta := time.Now() common.CloseBlockChain(usif.DefragUTXO) fmt.Println("Blockchain closed in", time.Now().Sub(sta).String()) peersdb.ClosePeerDB() sys.UnlockDatabaseDir() }
func main() { if btc.EC_Verify == nil { fmt.Println("WARNING: EC_Verify acceleration disabled. Enable EC_Verify wrapper if possible.") } 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 // Clean up the DB lock file on exit // cache the current balance of all the addresses from the current wallet files wallet.FetchAllBalances() // ... and now switch to the dafault wallet wallet.LoadWallet(common.GocoinHomeDir + "wallet" + string(os.PathSeparator) + "DEFAULT") if wallet.MyWallet == nil { wallet.LoadWallet(common.GocoinHomeDir + "wallet.txt") } if wallet.MyWallet != nil { wallet.UpdateBalance() fmt.Print(wallet.DumpBalance(nil, false)) } 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) 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 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 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", lib.Version) 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() peersdb.ClosePeerDB() sys.UnlockDatabaseDir() os.Exit(1) } }() common.InitConfig() host_init() // This will create the DB lock file and keep it open peersTick := time.Tick(5 * time.Minute) txPoolTick := time.Tick(time.Minute) netTick := time.Tick(time.Second) peersdb.Testnet = common.Testnet peersdb.ConnectOnly = common.CFG.ConnectOnly peersdb.Services = common.Services peersdb.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: common.CountSafe("MainNetBlock") HandleNetBlock(newbl) case newtx := <-network.NetTxs: common.CountSafe("MainNetTx") network.HandleNetTx(newtx, false) case newal := <-network.NetAlerts: common.CountSafe("MainNetAlert") fmt.Println("\007" + newal) textui.ShowPrompt() case <-netTick: common.CountSafe("MainNetTick") network.NetworkTick() case cmd := <-usif.UiChannel: common.CountSafe("MainUICmd") common.Busy("UI command") cmd.Handler(cmd.Param) cmd.Done.Done() continue case <-peersTick: peersdb.ExpirePeers() case <-txPoolTick: network.ExpireTxs() case <-time.After(time.Second / 2): common.CountSafe("MainThreadTouts") if !retryCachedBlocks { common.Busy("common.BlockChain.Idle()") if common.BlockChain.Idle() { common.CountSafe("ChainIdleUsed") } } continue } } network.NetCloseAll() peersdb.ClosePeerDB() if usif.DefragBlocksDB != 0 { defrag_db() } common.CloseBlockChain() sys.UnlockDatabaseDir() }
func LocalAcceptBlock(bl *btc.Block, from *network.OneConnection) (e error) { sta := time.Now() e = common.BlockChain.AcceptBlock(bl) if e == nil { network.MutexRcv.Lock() network.ReceivedBlocks[bl.Hash.BIdx()].TmAccept = time.Now().Sub(sta) network.MutexRcv.Unlock() for i := 1; i < len(bl.Txs); i++ { network.TxMined(bl.Txs[i]) /* dupa if msg:=contains_message(bl.Txs[i]); msg!=nil { for xx:=range msg { if msg[xx]<' ' || msg[xx]>127 { msg[xx] = '.' } } fmt.Println("TX", bl.Txs[i].Hash.String(), "says:", "'" + string(msg) + "'") textui.ShowPrompt() } */ } if int64(bl.BlockTime()) > time.Now().Add(-10*time.Minute).Unix() { // Freshly mined block - do the inv and beeps... common.Busy("NetRouteInv") network.NetRouteInv(2, bl.Hash, from) if common.CFG.Beeps.NewBlock { fmt.Println("\007Received block", common.BlockChain.BlockTreeEnd.Height) textui.ShowPrompt() } if common.CFG.Beeps.MinerID != "" { //_, rawtxlen := btc.NewTx(bl[bl.TxOffset:]) if bytes.Contains(bl.Txs[0].Serialize(), []byte(common.CFG.Beeps.MinerID)) { fmt.Println("\007Mined by '"+common.CFG.Beeps.MinerID+"':", bl.Hash) textui.ShowPrompt() } } if common.CFG.Beeps.ActiveFork && common.Last.Block == common.BlockChain.BlockTreeEnd { // Last block has not changed, so it must have been an orphaned block bln := common.BlockChain.BlockIndex[bl.Hash.BIdx()] commonNode := common.Last.Block.FirstCommonParent(bln) forkDepth := bln.Height - commonNode.Height fmt.Println("Orphaned block:", bln.Height, bl.Hash.String(), bln.BlockSize>>10, "KB") if forkDepth > 1 { fmt.Println("\007\007\007WARNING: the fork is", forkDepth, "blocks deep") } textui.ShowPrompt() } if wallet.BalanceChanged && common.CFG.Beeps.NewBalance { fmt.Print("\007") } } common.Last.Mutex.Lock() common.Last.Time = time.Now() common.Last.Block = common.BlockChain.BlockTreeEnd common.Last.Mutex.Unlock() if wallet.BalanceChanged { wallet.BalanceChanged = false fmt.Println("Your balance has just changed") fmt.Print(wallet.DumpBalance(wallet.MyBalance, nil, false, true)) textui.ShowPrompt() } } else { fmt.Println("Warning: AcceptBlock failed. If the block was valid, you may need to rebuild the unspent DB (-r)") } return }