### Question:
ProgPoW { public static Bytes32 progPowHash( long blockNumber, long nonce, Bytes32 header, UInt32[] dag, Function<UInt32, Bytes> dagLookupFunction) { UInt32[][] mix = new UInt32[PROGPOW_LANES][PROGPOW_REGS]; Bytes32 seed_256 = Keccakf800.keccakF800Progpow(header, nonce, Bytes32.ZERO); long seed = (Integer.toUnsignedLong(seed_256.getInt(0)) << 32) | Integer.toUnsignedLong(seed_256.getInt(4)); for (int l = 0; l < PROGPOW_LANES; l++) mix[l] = fillMix(UInt64.fromBytes(Bytes.wrap(ByteBuffer.allocate(8).putLong(seed).array())), UInt32.valueOf(l)); for (int i = 0; i < PROGPOW_CNT_DAG; i++) progPowLoop(blockNumber, UInt32.valueOf(i), mix, dag, dagLookupFunction); UInt32[] digest_lane = new UInt32[PROGPOW_LANES]; for (int l = 0; l < PROGPOW_LANES; l++) { digest_lane[l] = UInt32.fromBytes(FNV_OFFSET_BASIS); for (int i = 0; i < PROGPOW_REGS; i++) digest_lane[l] = fnv1a(digest_lane[l], mix[l][i]); } UInt32[] digest = new UInt32[8]; Arrays.fill(digest, UInt32.fromBytes(FNV_OFFSET_BASIS)); for (int l = 0; l < PROGPOW_LANES; l++) { digest[l % 8] = fnv1a(digest[l % 8], digest_lane[l]); } Bytes32 bytesDigest = Bytes32.wrap(Bytes.concatenate(Stream.of(digest).map(UInt32::toBytes).toArray(Bytes[]::new))); return Keccakf800.keccakF800Progpow(header, seed, bytesDigest); }  static Bytes32 progPowHash(
      long blockNumber,
      long nonce,
      Bytes32 header,
      UInt32[] dag, // gigabyte DAG located in framebuffer - the first portion gets cached
      Function<UInt32, Bytes> dagLookupFunction); static UInt32[] createDagCache(long blockNumber, Function<UInt32, Bytes> datasetLookup);  }### Answer:
@Test void testProgPoWHash() { long blockNumber = 30000; UInt32[] cache = EthHash.mkCache(EthHash.getCacheSize(blockNumber), blockNumber); UInt32[] cDag = ProgPoW.createDagCache(blockNumber, (ind) -> EthHash.calcDatasetItem(cache, ind)); Bytes32 digest = ProgPoW .progPowHash( blockNumber, 0x123456789abcdef0L, Bytes32.fromHexString("ffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff"), cDag, (ind) -> EthHash.calcDatasetItem(cache, ind)); assertEquals(Bytes32.fromHexString("5b7ccd472dbefdd95b895cac8ece67ff0deb5a6bd2ecc6e162383d00c3728ece"), digest); }