func CurrentHeight(name string) uint32 { coin := Config.GetCoin(name) // Caches currentHeight for 10 seconds. if coin.CurrentHeightTime == 0 || coin.CurrentHeightTime+CURRENT_HEIGHT_CACHE_SEC < time.Now().Unix() { currentHeight := rpc.GetCurrentHeight(coin.Name) coin.CurrentHeight = currentHeight coin.CurrentHeightTime = time.Now().Unix() } return coin.CurrentHeight }
// Continually polls for updates from bitcoin daemon & updates things as necessary. // Meant to run in a goroutine. func Sync(coin string) { defer Recover("Daemon::Sync(" + coin + ")") Info("[%v] Sync()", coin) c := Config.GetCoin(coin) for { // Compute how many blocks have been orphaned, how many are good. orphaned, good := LoadAndAssessLastBlocks(coin) // TODO: if there are too many that were orphaned, call OnDisaster() // If any blocks have been orphaned, process just the last one and continue. if len(orphaned) > 0 { orphanBlock(orphaned[0]) continue } // We have no blocks to orphan. // If any of the good are STATUS_PROCESSING, finish processing as good. if len(good) > 0 && good[0].Status == BLOCK_STATUS_PROCESSING { // There shouldn't be more than one such good block. for _, block := range good[1:] { if block.Status != BLOCK_STATUS_GOOD && block.Status != BLOCK_STATUS_GOOD_CREDITED { panic(NewError("Unexpected status for what should be a good block: %v", block.Hash)) } } processBlock(good[0]) continue } // Get the next new block and process that. var nextHeight = uint32(0) if len(good) > 0 { nextHeight = good[0].Height + 1 } else { nextHeight = rpc.GetCurrentHeight(coin) } next := rpc.GetBlock(coin, nextHeight) if next != nil { // First, process the block ReqConf down, // those payments should be credited. creditDepositsForBlockAtHeight(coin, nextHeight-c.ReqConf+1) // Create the new block, or unorphan an existing one. block := createOrUnorphanBlock(next) // Process the next block which is now in STATUS_PROCESSING. processBlock(block) continue } // There are no blocks to process, so sync from the mempool. syncMempool(coin, nextHeight) } }
// Looks for updates from the mempool from bitcoin daemon. // Stops when the height changes. func syncMempool(coin string, nextHeight uint32) { for { newHeight := rpc.GetCurrentHeight(coin) if nextHeight <= newHeight { // TODO: well, not all tx's will have been confirmed. mempoolTxHashes.Clear() return } syncMempoolOnce(coin) // Wait a bit time.Sleep(30 * time.Second) } }