private void extendMainChain(Block block) { if (Arrays.equals(block.getBlockPrev(), this.lastBlock.getBlockHash())) { block.setMain(true); this.addBlock(block); this.lastBlock = block; } }
public void addSPVBlock(Block block) { // only none block need add spv block if (this.getBlockCount() == 0) { block.setMain(true); this.addBlock(block); this.lastBlock = block; } }
private void forkMainChain(Block forkStartBlock, Block lastBlock) { Block b = this.lastBlock; Block next = lastBlock; while (!Arrays.equals(b.getBlockHash(), forkStartBlock.getBlockHash())) { next = AbstractDb.blockProvider.getOrphanBlockByPrevHash(b.getBlockPrev()); AbstractDb.blockProvider.updateBlock(b.getBlockHash(), false); b = AbstractDb.blockProvider.getMainChainBlock(b.getBlockPrev()); this.lastBlock = b; } b = next; AbstractDb.blockProvider.updateBlock(next.getBlockHash(), true); this.lastBlock = next; while (!Arrays.equals(b.getBlockHash(), lastBlock.getBlockPrev())) { AbstractDb.blockProvider.updateBlock(b.getBlockHash(), true); this.lastBlock = b; b = AbstractDb.blockProvider.getOrphanBlockByPrevHash(b.getBlockHash()); } lastBlock.setMain(true); this.addBlock(lastBlock); this.lastBlock = lastBlock; }
public int relayedBlockHeadersForMainChain(List<Block> blocks) { if (blocks == null || blocks.size() == 0) { return 0; } ArrayList<Block> blocksToAdd = new ArrayList<Block>(); Block prev = getLastBlock(); if (prev == null) { log.warn("pre block is null"); return 0; } for (int i = 0; i < blocks.size(); i++) { Block block = blocks.get(i); if (!Arrays.equals(prev.getBlockHash(), block.getBlockPrev())) { Block alreadyIn = getBlock(block.getBlockHash()); if (alreadyIn != null) { log.debug("Block is already in, No." + alreadyIn.getBlockNo()); continue; } else { this.singleBlocks.put(block.getBlockHash(), block); break; } } block.setBlockNo(prev.getBlockNo() + 1); try { block.verifyDifficultyFromPreviousBlock(prev); } catch (Exception e) { e.printStackTrace(); break; } block.setMain(true); blocksToAdd.add(block); prev = block; } if (blocksToAdd.size() > 0) { addBlocks(blocksToAdd); lastBlock = blocksToAdd.get(blocksToAdd.size() - 1); } return blocksToAdd.size(); }
private void addOrphan(Block block) { block.setMain(false); this.addBlock(block); this.lastOrphanBlock = block; }
public int relayedBlocks(List<Block> blocks) throws VerificationException { if (blocks == null || blocks.size() == 0) { return 0; } Block prev = null; Block first = blocks.get(0); int rollbackBlockNo = 0; if (Arrays.equals(first.getBlockPrev(), this.getLastBlock().getBlockHash())) { prev = this.getLastBlock(); } else if (AbstractDb.blockProvider.getMainChainBlock(first.getBlockPrev()) != null) { prev = this.getSameParent(first, this.getLastBlock()); rollbackBlockNo = prev.getBlockNo(); } if (prev == null) { return 0; } for (Block block : blocks) { if (!Arrays.equals(block.getBlockPrev(), prev.getBlockHash())) { return 0; } block.setBlockNo(prev.getBlockNo() + 1); try { int transitionTime = 0; if (block.getBlockNo() % BitherjSettings.BLOCK_DIFFICULTY_INTERVAL == 0) { // We need to find a block far back in the chain. It's OK that this is expensive because // it only occurs every // two weeks after the initial block chain download. long now = System.currentTimeMillis(); Block cursor = first; for (int i = 0; i < BitherjSettings.BLOCK_DIFFICULTY_INTERVAL - block.getBlockNo() + first.getBlockNo(); i++) { if (cursor == null) { // This should never happen. If it does, it means we are following an incorrect or // busted chain. throw new VerificationException( "Difficulty transition point but we did not find a way back to the genesis block."); } cursor = getBlock(cursor.getBlockPrev()); } long elapsed = System.currentTimeMillis() - now; if (elapsed > 50) log.info("Difficulty transition traversal took {}msec", elapsed); transitionTime = cursor.getBlockTime(); } block.verifyDifficultyFromPreviousBlock(prev, transitionTime); } catch (Exception e) { e.printStackTrace(); return 0; } block.setMain(true); prev = block; } if (rollbackBlockNo > 0) { this.rollbackBlock(rollbackBlockNo); } this.addBlocks(blocks); for (Block block : blocks) { AbstractDb.txProvider.confirmTx(block.getBlockNo(), block.getTxHashes()); } this.lastBlock = blocks.get(blocks.size() - 1); return blocks.size(); }