func dbCalculateBlockFacts(tx *bolt.Tx, cs modules.ConsensusSet, block types.Block) blockFacts { // get the parent block facts var bf blockFacts err := dbGetAndDecode(bucketBlockFacts, block.ParentID, &bf)(tx) assertNil(err) // get target target, exists := cs.ChildTarget(block.ParentID) if !exists { panic(fmt.Sprint("ConsensusSet is missing target of known block", block.ParentID)) } // update fields bf.BlockID = block.ID() bf.Height++ bf.Difficulty = target.Difficulty() bf.Target = target bf.Timestamp = block.Timestamp bf.TotalCoins = types.CalculateNumSiacoins(bf.Height) // calculate maturity timestamp var maturityTimestamp types.Timestamp if bf.Height > types.MaturityDelay { oldBlock, exists := cs.BlockAtHeight(bf.Height - types.MaturityDelay) if !exists { panic(fmt.Sprint("ConsensusSet is missing block at height", bf.Height-types.MaturityDelay)) } maturityTimestamp = oldBlock.Timestamp } bf.MaturityTimestamp = maturityTimestamp // calculate hashrate by averaging last 'hashrateEstimationBlocks' blocks var estimatedHashrate types.Currency if bf.Height > hashrateEstimationBlocks { var totalDifficulty = bf.Target var oldestTimestamp types.Timestamp for i := types.BlockHeight(1); i < hashrateEstimationBlocks; i++ { b, exists := cs.BlockAtHeight(bf.Height - i) if !exists { panic(fmt.Sprint("ConsensusSet is missing block at height", bf.Height-hashrateEstimationBlocks)) } target, exists := cs.ChildTarget(b.ParentID) if !exists { panic(fmt.Sprint("ConsensusSet is missing target of known block", b.ParentID)) } totalDifficulty = totalDifficulty.AddDifficulties(target) oldestTimestamp = b.Timestamp } secondsPassed := bf.Timestamp - oldestTimestamp estimatedHashrate = totalDifficulty.Difficulty().Div64(uint64(secondsPassed)) } bf.EstimatedHashrate = estimatedHashrate bf.MinerPayoutCount += uint64(len(block.MinerPayouts)) bf.TransactionCount += uint64(len(block.Transactions)) for _, txn := range block.Transactions { bf.SiacoinInputCount += uint64(len(txn.SiacoinInputs)) bf.SiacoinOutputCount += uint64(len(txn.SiacoinOutputs)) bf.FileContractCount += uint64(len(txn.FileContracts)) bf.FileContractRevisionCount += uint64(len(txn.FileContractRevisions)) bf.StorageProofCount += uint64(len(txn.StorageProofs)) bf.SiafundInputCount += uint64(len(txn.SiafundInputs)) bf.SiafundOutputCount += uint64(len(txn.SiafundOutputs)) bf.MinerFeeCount += uint64(len(txn.MinerFees)) bf.ArbitraryDataCount += uint64(len(txn.ArbitraryData)) bf.TransactionSignatureCount += uint64(len(txn.TransactionSignatures)) for _, fc := range txn.FileContracts { bf.TotalContractCost = bf.TotalContractCost.Add(fc.Payout) bf.TotalContractSize = bf.TotalContractSize.Add(types.NewCurrency64(fc.FileSize)) } for _, fcr := range txn.FileContractRevisions { bf.TotalContractSize = bf.TotalContractSize.Add(types.NewCurrency64(fcr.NewFileSize)) bf.TotalRevisionVolume = bf.TotalRevisionVolume.Add(types.NewCurrency64(fcr.NewFileSize)) } } return bf }