// targetAdjustmentBase returns the magnitude that the target should be // adjusted by before a clamp is applied. func (cs *ConsensusSet) targetAdjustmentBase(blockMap *bolt.Bucket, pb *processedBlock) *big.Rat { // Grab the block that was generated 'TargetWindow' blocks prior to the // parent. If there are not 'TargetWindow' blocks yet, stop at the genesis // block. var windowSize types.BlockHeight parent := pb.Block.ParentID current := pb.Block.ID() for windowSize = 0; windowSize < types.TargetWindow && parent != (types.BlockID{}); windowSize++ { current = parent copy(parent[:], blockMap.Get(parent[:])[:32]) } timestamp := types.Timestamp(encoding.DecUint64(blockMap.Get(current[:])[40:48])) // The target of a child is determined by the amount of time that has // passed between the generation of its immediate parent and its // TargetWindow'th parent. The expected amount of seconds to have passed is // TargetWindow*BlockFrequency. The target is adjusted in proportion to how // time has passed vs. the expected amount of time to have passed. // // The target is converted to a big.Rat to provide infinite precision // during the calculation. The big.Rat is just the int representation of a // target. timePassed := pb.Block.Timestamp - timestamp expectedTimePassed := types.BlockFrequency * windowSize return big.NewRat(int64(timePassed), int64(expectedTimePassed)) }
// setChildTarget computes the target of a blockNode's child. All children of a node // have the same target. func (cs *ConsensusSet) setChildTarget(blockMap *bolt.Bucket, pb *processedBlock) { // Fetch the parent block. var parent processedBlock parentBytes := blockMap.Get(pb.Block.ParentID[:]) err := encoding.Unmarshal(parentBytes, &parent) if build.DEBUG && err != nil { panic(err) } if pb.Height%(types.TargetWindow/2) != 0 { pb.ChildTarget = parent.ChildTarget return } adjustment := clampTargetAdjustment(cs.targetAdjustmentBase(blockMap, pb)) adjustedRatTarget := new(big.Rat).Mul(parent.ChildTarget.Rat(), adjustment) pb.ChildTarget = types.RatToTarget(adjustedRatTarget) }
func mustDelete(bucket *bolt.Bucket, key interface{}) { assertNil(bucket.Delete(encoding.Marshal(key))) }
func mustPutSet(bucket *bolt.Bucket, key interface{}) { assertNil(bucket.Put(encoding.Marshal(key), nil)) }
func mustPut(bucket *bolt.Bucket, key, val interface{}) { assertNil(bucket.Put(encoding.Marshal(key), encoding.Marshal(val))) }