def test_target_calculation(self): # see: https://github.com/lbryio/lbrycrd/blob/master/src/test/lbry_tests.cpp # 1 test block 1 difficulty, should be a max retarget self.assertEqual( 0x1f00e146, Headers(':memory').get_next_block_target( max_target=ArithUint256(Headers.max_target), previous={ 'timestamp': 1386475638 }, current={ 'timestamp': 1386475638, 'bits': 0x1f00ffff }).compact) # test max retarget (difficulty increase) self.assertEqual( 0x1f008ccc, Headers(':memory').get_next_block_target( max_target=ArithUint256(Headers.max_target), previous={ 'timestamp': 1386475638 }, current={ 'timestamp': 1386475638, 'bits': 0x1f00a000 }).compact) # test min retarget (difficulty decrease) self.assertEqual( 0x1f00f000, Headers(':memory').get_next_block_target( max_target=ArithUint256(Headers.max_target), previous={ 'timestamp': 1386475638 }, current={ 'timestamp': 1386475638 + 60 * 20, 'bits': 0x1f00a000 }).compact) # test to see if pow limit is not exceeded self.assertEqual( 0x1f00ffff, Headers(':memory').get_next_block_target( max_target=ArithUint256(Headers.max_target), previous={ 'timestamp': 1386475638 }, current={ 'timestamp': 1386475638 + 600, 'bits': 0x1f00ffff }).compact)
def get_next_block_target(self, max_target: ArithUint256, previous: Optional[dict], current: Optional[dict]) -> ArithUint256: # https://github.com/lbryio/lbrycrd/blob/master/src/lbry.cpp if previous is None and current is None: return max_target if previous is None: previous = current actual_timespan = current['timestamp'] - previous['timestamp'] modulated_timespan = self.target_timespan + int((actual_timespan - self.target_timespan) / 8) minimum_timespan = self.target_timespan - int(self.target_timespan / 8) # 150 - 18 = 132 maximum_timespan = self.target_timespan + int(self.target_timespan / 2) # 150 + 75 = 225 clamped_timespan = max(minimum_timespan, min(modulated_timespan, maximum_timespan)) target = ArithUint256.from_compact(current['bits']) new_target = min(max_target, (target * clamped_timespan) / self.target_timespan) return new_target
def get_proof_of_work(cls, header_hash: bytes): return ArithUint256(int(b'0x' + cls.header_hash_to_pow_hash(header_hash), 16))
def get_next_chunk_target(self, chunk: int) -> ArithUint256: return ArithUint256(self.max_target)