def target(DB, length=0): #returns the target difficulty at a paticular blocklength. inflection=0.985#This constant is selected such that the 50 most recent blocks count for 1/2 the total weight. history_length=400#How far back in history do we compute the target from. if length==0: length=DB['length'] if length<4: return '0'*4+'f'*60#use same difficulty for first few blocks. if length<=DB['length']: return targets[str(length)]#don't calculate same difficulty twice. def targetTimesFloat(target, number): return buffer(str(hex(int(int(target, 16)*number)))[2:-1]) def weights(length): return [inflection**(length-i) for i in range(length)] def estimate_target(DB): def invertTarget(n): return buffer(str(hex(int('f'*128, 16)/int(n, 16)))[2:-1])#use double-size for division, to reduce information leakage. def sumTargets(l): if len(l)<1: return 0 while len(l)>1: l=[hexSum(l[0], l[1])]+l[2:] return l[0] targets=recent_blockthings('target', DB, history_length) w=weights(len(targets)) tw=sum(w) targets=map(hexInvert, targets)#invert because target is proportional to 1/(# hashes required to mine a block on average) weighted_targets=[targetTimesFloat(targets[i], w[i]/tw) for i in range(len(targets))] return hexInvert(sumTargets(weighted_targets))#invert again to fix units def estimate_time(DB): timestamps=recent_blockthings('time', DB, history_length) blocklengths=[timestamps[i]-timestamps[i-1] for i in range(1, len(timestamps))] w=weights(len(blocklengths))#geometric weighting tw=sum(w)#normalization constant return sum([w[i]*blocklengths[i]/tw for i in range(len(blocklengths))]) return targetTimesFloat(estimate_target(DB), estimate_time(DB)/custom.blocktime(length))
def target(DB, length=0): """ Returns the target difficulty at a paticular blocklength. """ if length == 0: length = DB['length'] if length < 4: return '0' * 4 + 'f' * 60 # Use same difficulty for first few blocks. if length <= DB['length'] and str(length) in targets: return targets[str( length )] # Memoized, This is a small memory leak. It takes up more space linearly over time. but every time you restart the program, it gets cleaned out. def targetTimesFloat(target, number): a = int(str(target), 16) b = int(a * number) return tools.buffer_(str(hex(b))[2:-1], 64) def weights(length): return [custom.inflection**(length - i) for i in range(length)] def estimate_target(DB): """ We are actually interested in the average number of hashes required to mine a block. number of hashes required is inversely proportional to target. So we average over inverse-targets, and inverse the final answer. """ def sumTargets(l): if len(l) < 1: return 0 while len(l) > 1: l = [hexSum(l[0], l[1])] + l[2:] return l[0] targets = recent_blockthings('target', DB, custom.history_length) w = weights(len(targets)) tw = sum(w) targets = map(hexInvert, targets) def weighted_multiply(i): return targetTimesFloat(targets[i], w[i] / tw) weighted_targets = [weighted_multiply(i) for i in range(len(targets))] return hexInvert(sumTargets(weighted_targets)) def estimate_time(DB): times = recent_blockthings('time', DB, custom.history_length) blocklengths = [times[i] - times[i - 1] for i in range(1, len(times))] w = weights(len(blocklengths)) # Geometric weighting tw = sum(w) # Normalization constant return sum( [w[i] * blocklengths[i] / tw for i in range(len(blocklengths))]) retarget = estimate_time(DB) / custom.blocktime(length) return targetTimesFloat(estimate_target(DB), retarget)
def target(DB, length=0): """ Returns the target difficulty at a paticular blocklength. """ if length == 0: length = DB['length'] if length < 4: return '0' * 4 + 'f' * 60 # Use same difficulty for first few blocks. if length <= DB['length']: return targets[str(length)] # Memoized def targetTimesFloat(target, number): a = int(str(target), 16) b = int(a * number) return tools.buffer_(str(hex(b))[2: -1], 64) def weights(length): return [custom.inflection ** (length-i) for i in range(length)] def estimate_target(DB): """ We are actually interested in the average number of hashes required to mine a block. number of hashes required is inversely proportional to target. So we average over inverse-targets, and inverse the final answer. """ def sumTargets(l): if len(l) < 1: return 0 while len(l) > 1: l = [hexSum(l[0], l[1])] + l[2:] return l[0] targets = recent_blockthings('target', DB, custom.history_length) w = weights(len(targets)) tw = sum(w) targets = map(hexInvert, targets) def weighted_multiply(i): return targetTimesFloat(targets[i], w[i]/tw) weighted_targets = [weighted_multiply(i) for i in range(len(targets))] return hexInvert(sumTargets(weighted_targets)) def estimate_time(DB): times = recent_blockthings('time', DB, custom.history_length) blocklengths = [times[i] - times[i - 1] for i in range(1, len(times))] w = weights(len(blocklengths)) # Geometric weighting tw = sum(w) # Normalization constant return sum([w[i] * blocklengths[i] / tw for i in range(len(blocklengths))]) retarget = estimate_time(DB) / custom.blocktime(length) return targetTimesFloat(estimate_target(DB), retarget)
def target(DB, length=0): #returns the target difficulty at a paticular blocklength. inflection=0.985#This constant is selected such that the 50 most recent #blocks count for 1/2 the total weight. history_length=400#How far back in history do we compute the target from. if length==0: length=DB['length'] if length<4: return '0'*4+'f'*60#use same difficulty for first few blocks. if length<=DB['length']: return targets[str(length)]#memoized def targetTimesFloat(target, number): return buffer(str(hex(int(int(target, 16)*number)))[2:-1]) def weights(length): return [inflection**(length-i) for i in range(length)] def estimate_target(DB): #We are actually interested in the average number of hashes requred #to mine a block. number of hashes required is inversely proportional #to target. So we average over inverse-targets, and inverse the final #answer. def sumTargets(l): if len(l)<1: return 0 while len(l)>1: l=[hexSum(l[0], l[1])]+l[2:] return l[0] targets=recent_blockthings('target', DB, history_length) w=weights(len(targets)) tw=sum(w) targets=map(hexInvert, targets) def weighted_multiply(i): return targetTimesFloat(targets[i], w[i]/tw) weighted_targets=[weighted_multiply(i) for i in range(len(targets))] return hexInvert(sumTargets(weighted_targets)) def estimate_time(DB): times=recent_blockthings('time', DB, history_length) blocklengths=[times[i]-times[i-1] for i in range(1, len(times))] w=weights(len(blocklengths))#geometric weighting tw=sum(w)#normalization constant return sum([w[i]*blocklengths[i]/tw for i in range(len(blocklengths))]) retarget=estimate_time(DB)/custom.blocktime(length) return targetTimesFloat(estimate_target(DB), retarget)