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 test_arithunit256(self): # https://github.com/bitcoin/bitcoin/blob/master/src/test/arith_uint256_tests.cpp from_compact = ArithUint256.from_compact eq = self.assertEqual eq(from_compact(0).value, 0) eq(from_compact(0x00123456).value, 0) eq(from_compact(0x01003456).value, 0) eq(from_compact(0x02000056).value, 0) eq(from_compact(0x03000000).value, 0) eq(from_compact(0x04000000).value, 0) eq(from_compact(0x00923456).value, 0) eq(from_compact(0x01803456).value, 0) eq(from_compact(0x02800056).value, 0) eq(from_compact(0x03800000).value, 0) eq(from_compact(0x04800000).value, 0) # Make sure that we don't generate compacts with the 0x00800000 bit set uint = ArithUint256(0x80) eq(uint.compact, 0x02008000) uint = from_compact(0x01123456) eq(uint.value, 0x12) eq(uint.compact, 0x01120000) uint = from_compact(0x01fedcba) eq(uint.value, 0x7e) eq(uint.negative, 0x01fe0000) uint = from_compact(0x02123456) eq(uint.value, 0x1234) eq(uint.compact, 0x02123400) uint = from_compact(0x03123456) eq(uint.value, 0x123456) eq(uint.compact, 0x03123456) uint = from_compact(0x04123456) eq(uint.value, 0x12345600) eq(uint.compact, 0x04123456) uint = from_compact(0x04923456) eq(uint.value, 0x12345600) eq(uint.negative, 0x04923456) uint = from_compact(0x05009234) eq(uint.value, 0x92340000) eq(uint.compact, 0x05009234) uint = from_compact(0x20123456) eq(uint.value, 0x1234560000000000000000000000000000000000000000000000000000000000) eq(uint.compact, 0x20123456)
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_next_chunk_target(self, chunk: int) -> ArithUint256: return ArithUint256(self.max_target)
def get_proof_of_work(header_hash: bytes) -> ArithUint256: return ArithUint256(int(b'0x' + header_hash, 16))