Exemple #1
0
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)
	}
}