def RandomXTest() -> None: #Generate 100 RandomX keys, and create 10 hashes with each. #As this is single threaded, it's guaranteed to be safe. keys: List[bytes] = [] hashed: List[List[bytes]] = [] hashes: List[List[bytes]] = [] for _ in range(100): keys.append(bytes(getrandbits(8) for _ in range(32))) setRandomXKey(keys[-1]) hashed.append([]) hashes.append([]) for _ in range(10): hashed[-1].append( bytes(getrandbits(8) for _ in range(getrandbits(8)))) hashes[-1].append(RandomX(hashed[-1][-1])) def rxThread(t: int) -> None: for k in range(t * 25, (t + 1) * 25): setRandomXKey(keys[k]) for h in range(len(hashed[k])): if RandomX(hashed[k][h]) != hashes[k][h]: raise TestError( "Threaded RandomX returned a different result than the single-threaded version." ) #Now, spawn 4 threads and re-iterate over every hash. threads: List[Thread] = [] for t in range(4): threads.append(Thread(None, rxThread, "RX-" + str(t), [t])) threads[-1].start() for thread in threads: thread.join()
def rxThread(t: int) -> None: for k in range(t * 25, (t + 1) * 25): setRandomXKey(keys[k]) for h in range(len(hashed[k])): if RandomX(hashed[k][h]) != hashes[k][h]: raise TestError( "Threaded RandomX returned a different result than the single-threaded version." )
def add(self, block: Block) -> None: self.blocks.append(block) if len(self.blocks) % 384 == 0: self.upcomingKey = block.header.hash elif len(self.blocks) % 384 == 12: setRandomXKey(self.upcomingKey) if len(self.blocks) < 6: self.difficulties.append(self.difficulties[0]) else: windowLength: int = 72 if len(self.blocks) < 4320: windowLength = 5 elif len(self.blocks) < 12960: windowLength = 9 elif len(self.blocks) < 25920: windowLength = 18 elif len(self.blocks) < 52560: windowLength = 36 window: List[Block] = self.blocks[len(self.blocks) - windowLength:len(self.blocks)] windowDifficulties: List[int] = self.difficulties[ len(self.difficulties) - (windowLength - 1):len(self.difficulties)] windowDifficulties.sort() median: int = windowDifficulties[len(windowDifficulties) // 2] for _ in range(len(windowDifficulties) // 10): if (median - windowDifficulties[0]) > (windowDifficulties[-1] - median): del windowDifficulties[0] elif (median - windowDifficulties[0]) == (windowDifficulties[-1] - median): del windowDifficulties[0] elif (median - windowDifficulties[0]) < ( windowDifficulties[-1] - median): del windowDifficulties[-1] self.difficulties.append( max( sum(windowDifficulties) * 60 // (window[-1].header.time - window[0].header.time), 1)) if block.header.newMiner: self.difficulties[-1] = self.difficulties[-1] * 11 // 10 if block.header.newMiner: self.keys[block.header.minerKey] = len(self.keys)
def __init__(self) -> None: self.genesis: bytes = b"MEROS_DEVELOPER_NETWORK".ljust(32, b'\0') self.upcomingKey: bytes = self.genesis setRandomXKey(self.upcomingKey) self.blockTime: int = 60 self.difficulties: List[int] = [100] self.keys: Dict[bytes, int] = {} self.blocks: List[Block] = [ Block( BlockHeader(0, self.genesis, bytes(32), 0, bytes(4), bytes(32), PublicKey().serialize(), 0), BlockBody()) ]