use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BlockUtilsTest method unknowAncestorsHashesUsingUncles.
@Test
public void unknowAncestorsHashesUsingUncles() {
BlockChainBuilder blockChainBuilder = new BlockChainBuilder();
BlockGenerator blockGenerator = new BlockGenerator();
Genesis genesis = blockGenerator.getGenesisBlock();
BlockChainImpl blockChain = blockChainBuilder.setGenesis(genesis).build();
BlockStore store = new BlockStore();
genesis.setStateRoot(blockChain.getRepository().getRoot());
genesis.flushRLP();
BlockBuilder blockBuilder = new BlockBuilder(blockChain, blockGenerator);
Block block1 = blockBuilder.parent(genesis).build();
Block block1b = blockBuilder.parent(genesis).build();
Block block2 = blockBuilder.parent(block1).build();
Block uncle1 = blockBuilder.parent(block1).build();
Block uncle2 = blockBuilder.parent(block1).build();
List<BlockHeader> uncles = new ArrayList<>();
uncles.add(uncle1.getHeader());
uncles.add(uncle2.getHeader());
Block block3 = blockBuilder.parent(block2).uncles(uncles).build();
store.saveBlock(block3);
blockChain.tryToConnect(genesis);
blockChain.tryToConnect(block1);
blockChain.tryToConnect(block1b);
Set<Keccak256> hashes = BlockUtils.unknownAncestorsHashes(genesis.getHash(), blockChain, store);
Assert.assertNotNull(hashes);
Assert.assertTrue(hashes.isEmpty());
hashes = BlockUtils.unknownAncestorsHashes(block1.getHash(), blockChain, store);
Assert.assertNotNull(hashes);
Assert.assertTrue(hashes.isEmpty());
hashes = BlockUtils.unknownAncestorsHashes(block1b.getHash(), blockChain, store);
Assert.assertNotNull(hashes);
Assert.assertTrue(hashes.isEmpty());
hashes = BlockUtils.unknownAncestorsHashes(block2.getHash(), blockChain, store);
Assert.assertNotNull(hashes);
Assert.assertFalse(hashes.isEmpty());
Assert.assertEquals(1, hashes.size());
Assert.assertTrue(hashes.contains(block2.getHash()));
hashes = BlockUtils.unknownAncestorsHashes(block3.getHash(), blockChain, store);
Assert.assertNotNull(hashes);
Assert.assertFalse(hashes.isEmpty());
Assert.assertEquals(3, hashes.size());
Assert.assertTrue(hashes.contains(block2.getHash()));
Assert.assertTrue(hashes.contains(uncle1.getHash()));
Assert.assertTrue(hashes.contains(uncle2.getHash()));
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class MinerServerImpl method updateGetWork.
public MinerWork updateGetWork(@Nonnull final Block block, @Nonnull final boolean notify) {
Keccak256 blockMergedMiningHash = new Keccak256(block.getHashForMergedMining());
BigInteger targetBI = DifficultyUtils.difficultyToTarget(block.getDifficulty());
byte[] targetUnknownLengthArray = targetBI.toByteArray();
byte[] targetArray = new byte[32];
System.arraycopy(targetUnknownLengthArray, 0, targetArray, 32 - targetUnknownLengthArray.length, targetUnknownLengthArray.length);
logger.debug("Sending work for merged mining. Hash: {}", block.getShortHashForMergedMining());
return new MinerWork(blockMergedMiningHash.toJsonString(), TypeConverter.toJsonHex(targetArray), String.valueOf(block.getFeesPaidToMiner()), notify, block.getParentHashJsonString());
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class MinerServerImpl method processSolution.
private SubmitBlockResult processSolution(String blockHashForMergedMining, BtcBlock blockWithHeaderOnly, BtcTransaction coinbase, PartialMerkleTree bitcoinMergedMiningMerkleBranch, boolean lastTag) {
Block newBlock;
Keccak256 key = new Keccak256(TypeConverter.removeZeroX(blockHashForMergedMining));
synchronized (lock) {
Block workingBlock = blocksWaitingforPoW.get(key);
if (workingBlock == null) {
String message = "Cannot publish block, could not find hash " + blockHashForMergedMining + " in the cache";
logger.warn(message);
return new SubmitBlockResult("ERROR", message);
}
// clone the block
newBlock = workingBlock.cloneBlock();
logger.debug("blocksWaitingForPoW size {}", blocksWaitingforPoW.size());
}
logger.info("Received block {} {}", newBlock.getNumber(), newBlock.getHash());
newBlock.setBitcoinMergedMiningHeader(blockWithHeaderOnly.cloneAsHeader().bitcoinSerialize());
newBlock.setBitcoinMergedMiningCoinbaseTransaction(compressCoinbase(coinbase.bitcoinSerialize(), lastTag));
newBlock.setBitcoinMergedMiningMerkleProof(bitcoinMergedMiningMerkleBranch.bitcoinSerialize());
newBlock.seal();
if (!isValid(newBlock)) {
String message = "Invalid block supplied by miner: " + newBlock.getShortHash() + " " + newBlock.getShortHashForMergedMining() + " at height " + newBlock.getNumber();
logger.error(message);
return new SubmitBlockResult("ERROR", message);
} else {
ImportResult importResult = ethereum.addNewMinedBlock(newBlock);
logger.info("Mined block import result is {}: {} {} at height {}", importResult, newBlock.getShortHash(), newBlock.getShortHashForMergedMining(), newBlock.getNumber());
SubmittedBlockInfo blockInfo = new SubmittedBlockInfo(importResult, newBlock.getHash().getBytes(), newBlock.getNumber());
return new SubmitBlockResult("OK", "OK", blockInfo);
}
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BlockStore method removeBlock.
public synchronized void removeBlock(Block block) {
if (!this.hasBlock(block)) {
return;
}
Keccak256 key = block.getHash();
Keccak256 pkey = block.getParentHash();
Long nkey = Long.valueOf(block.getNumber());
this.blocks.remove(key);
removeBlockByNumber(key, nkey);
removeBlockByParent(key, pkey);
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BlockSyncService method processBlock.
public BlockProcessResult processBlock(@Nonnull Block block, MessageChannel sender, boolean ignoreMissingHashes) {
Instant start = Instant.now();
long bestBlockNumber = this.getBestBlockNumber();
long blockNumber = block.getNumber();
final Keccak256 blockHash = block.getHash();
int syncMaxDistance = syncConfiguration.getChunkSize() * syncConfiguration.getMaxSkeletonChunks();
tryReleaseStore(bestBlockNumber);
store.removeHeader(block.getHeader());
unknownBlockHashes.remove(blockHash);
if (blockNumber > bestBlockNumber + syncMaxDistance) {
logger.trace("Block too advanced {} {} from {} ", blockNumber, block.getShortHash(), sender != null ? sender.getPeerNodeID().toString() : "N/A");
return new BlockProcessResult(false, null, block.getShortHash(), Duration.between(start, Instant.now()));
}
if (sender != null) {
nodeInformation.addBlockToNode(blockHash, sender.getPeerNodeID());
}
// already in a blockchain
if (BlockUtils.blockInSomeBlockChain(block, blockchain)) {
logger.trace("Block already in a chain {} {}", blockNumber, block.getShortHash());
return new BlockProcessResult(false, null, block.getShortHash(), Duration.between(start, Instant.now()));
}
trySaveStore(block);
Set<Keccak256> unknownHashes = BlockUtils.unknownDirectAncestorsHashes(block, blockchain, store);
// We can't add the block if there are missing ancestors or uncles. Request the missing blocks to the sender.
if (!unknownHashes.isEmpty()) {
if (!ignoreMissingHashes) {
logger.trace("Missing hashes for block in process {} {}", blockNumber, block.getShortHash());
requestMissingHashes(sender, unknownHashes);
}
return new BlockProcessResult(false, null, block.getShortHash(), Duration.between(start, Instant.now()));
}
logger.trace("Trying to add to blockchain");
Map<Keccak256, ImportResult> connectResult = connectBlocksAndDescendants(sender, BlockUtils.sortBlocksByNumber(this.getParentsNotInBlockchain(block)), ignoreMissingHashes);
return new BlockProcessResult(true, connectResult, block.getShortHash(), Duration.between(start, Instant.now()));
}
Aggregations