/** Replaced with more specific listener methods: use them instead. */ @Deprecated @SuppressWarnings("deprecation") public void addListener(BlockChainListener listener) { addListener(listener, Threading.USER_THREAD); }
/** Replaced with more specific listener methods: use them instead. */ @Deprecated public void addListener(BlockChainListener listener, Executor executor) { addReorganizeListener(executor, listener); addNewBestBlockListener(executor, listener); addTransactionReceivedListener(executor, listener); }
protected void setChainHead(StoredBlock chainHead) throws BlockStoreException { doSetChainHead(chainHead); synchronized (chainHeadLock) { this.chainHead = chainHead; } }
StoredBlock head = getChainHead(); final StoredBlock splitPoint = findSplit(newChainHead, head, blockStore); log.info("Re-organize after split at height {}", splitPoint.getHeight()); log.info("Old chain head: {}", head.getHeader().getHashAsString()); final LinkedList<StoredBlock> oldBlocks = getPartialChain(head, splitPoint, blockStore); final LinkedList<StoredBlock> newBlocks = getPartialChain(newChainHead, splitPoint, blockStore); if (shouldVerifyTransactions()) { for (StoredBlock oldBlock : oldBlocks) { try { disconnectTransactions(oldBlock); } catch (PrunedException e) { cursor = it.next(); Block cursorBlock = cursor.getHeader(); if (expensiveChecks && cursorBlock.getTimeSeconds() <= getMedianTimestampOfRecentBlocks(cursor.getPrev(blockStore), blockStore)) throw new VerificationException("Block's timestamp is too early during reorg"); TransactionOutputChanges txOutChanges; if (cursor != newChainHead || block == null) txOutChanges = connectTransactions(cursor); else txOutChanges = connectTransactions(newChainHead.getHeight(), block); storedNewHead = addToBlockStore(storedNewHead, cursorBlock.cloneAsHeader(), txOutChanges); storedNewHead = addToBlockStore(storedPrev, newChainHead.getHeader()); setChainHead(storedNewHead);
if (shouldVerifyTransactions()) { checkNotNull(block.transactions); for (Transaction tx : block.transactions) StoredBlock head = getChainHead(); if (storedPrev.equals(head)) { if (filtered && filteredTxn.size() > 0) { if (expensiveChecks && block.getTimeSeconds() <= getMedianTimestampOfRecentBlocks(head, blockStore)) throw new VerificationException("Block's timestamp is too early"); if (shouldVerifyTransactions()) txOutChanges = connectTransactions(storedPrev.getHeight() + 1, block); StoredBlock newStoredBlock = addToBlockStore(storedPrev, block.transactions == null ? block : block.cloneAsHeader(), txOutChanges); versionTally.add(block.getVersion()); setChainHead(newStoredBlock); log.debug("Chain is now {} blocks high, running listeners", newStoredBlock.getHeight()); informListenersForNewBlock(block, NewBlockType.BEST_CHAIN, filteredTxHashList, filteredTxn, newStoredBlock); } else { log.info("Block is causing a re-organize"); } else { StoredBlock splitPoint = findSplit(newBlock, head, blockStore); if (splitPoint != null && splitPoint.equals(newBlock)) { addToBlockStore(storedPrev, block); int splitPointHeight = splitPoint.getHeight(); String splitPointHash = splitPoint.getHeader().getHashAsString();
/** * Add a wallet to the BlockChain. Note that the wallet will be unaffected by any blocks received while it * was not part of this BlockChain. This method is useful if the wallet has just been created, and its keys * have never been in use, or if the wallet has been loaded along with the BlockChain. Note that adding multiple * wallets is not well tested! */ public final void addWallet(Wallet wallet) { addNewBestBlockListener(Threading.SAME_THREAD, wallet); addReorganizeListener(Threading.SAME_THREAD, wallet); addTransactionReceivedListener(Threading.SAME_THREAD, wallet); int walletHeight = wallet.getLastBlockSeenHeight(); int chainHeight = getBestChainHeight(); if (walletHeight != chainHeight) { log.warn("Wallet/chain height mismatch: {} vs {}", walletHeight, chainHeight); log.warn("Hashes: {} vs {}", wallet.getLastBlockSeenHash(), getChainHead().getHeader().getHash()); // This special case happens when the VM crashes because of a transaction received. It causes the updated // block store to persist, but not the wallet. In order to fix the issue, we roll back the block store to // the wallet height to make it look like as if the block has never been received. if (walletHeight < chainHeight && walletHeight > 0) { try { rollbackBlockStore(walletHeight); log.info("Rolled back block store to height {}.", walletHeight); } catch (BlockStoreException x) { log.warn("Rollback of block store failed, continuing with mismatched heights. This can happen due to a replay."); } } } }
if (block.equals(getChainHead().getHeader())) { return true; if (shouldVerifyTransactions() && block.transactions == null) throw new VerificationException("Got a block header while running in full-block mode"); if (shouldVerifyTransactions() && blockStore.get(block.getHash()) != null) { return true; storedPrev = getStoredBlockInCurrentScope(block.getPrevBlockHash()); if (storedPrev != null) { height = storedPrev.getHeight() + 1; if (shouldVerifyTransactions()) block.verifyTransactions(height, flags); } catch (VerificationException e) { checkDifficultyTransitions(storedPrev, block); connectBlock(block, storedPrev, shouldVerifyTransactions(), filteredTxHashList, filteredTxn); tryConnectingOrphans();
awaitingFreshFilter = new LinkedList<Sha256Hash>(); awaitingFreshFilter.add(m.getHash()); awaitingFreshFilter.addAll(blockChain.drainOrphanBlocks()); return; // Chain download process is restarted via a call to setBloomFilter. if (blockChain.add(m)) { final Block orphanRoot = checkNotNull(blockChain.getOrphanRoot(m.getHash())); blockChainDownloadLocked(orphanRoot.getHash()); } finally {
/** * Processes a received block and tries to add it to the chain. If there's something wrong with the block an * exception is thrown. If the block is OK but cannot be connected to the chain at this time, returns false. * If the block can be connected to the chain, returns true. * Accessing block's transactions in another thread while this method runs may result in undefined behavior. */ public boolean add(Block block) throws VerificationException, PrunedException { try { return add(block, true, null, null); } catch (BlockStoreException e) { // TODO: Figure out a better way to propagate this exception to the user. throw new RuntimeException(e); } catch (VerificationException e) { try { notSettingChainHead(); } catch (BlockStoreException e1) { throw new RuntimeException(e1); } throw new VerificationException("Could not verify block:\n" + block.toString(), e); } }
OrphanBlock orphanBlock = iter.next(); StoredBlock prev = getStoredBlockInCurrentScope(orphanBlock.block.getPrevBlockHash()); if (prev == null) { add(orphanBlock.block, false, orphanBlock.filteredTxHashes, orphanBlock.filteredTxn); iter.remove(); blocksConnectedThisRound++;
try { if (blockChain.add(m)) { try { if (downloadBlockBodies) { final Block orphanRoot = checkNotNull(blockChain.getOrphanRoot(m.getHash())); blockChainDownloadLocked(orphanRoot.getHash()); } else {
boolean reachedTop = blockChain.getBestChainHeight() >= vPeerVersionMessage.bestHeight; if (!passedTime && !reachedTop) { if (!vDownloadData) { return; if (blockChain.add(header)) { log.info( "Passed the fast catchup time ({}) at height {}, discarding {} headers and requesting full blocks", Utils.dateTimeFormat(fastCatchupTimeSecs * 1000), blockChain.getBestChainHeight() + 1, m.getBlockHeaders().size() - i); this.downloadBlockBodies = true;
public void setPeerGroupAndBlockChain(PeerGroup peerGroup, AbstractBlockChain chain) { this.peerGroup = peerGroup; this.blockChain = chain; hashStore = new HashStore(chain.getBlockStore()); chain.addListener(updateHeadListener); if(initializedDash) { sporkManager.setBlockChain(chain); masternodeManager.setBlockChain(chain); masternodeSync.setBlockChain(chain); instantSend.setBlockChain(chain); } params.setDIPActiveAtTip(chain.getBestChainHeight() >= params.getDIP0001BlockHeight()); }
/** * Adds a {@link NewBestBlockListener} listener to the chain. */ public void addNewBestBlockListener(NewBestBlockListener listener) { addNewBestBlockListener(Threading.USER_THREAD, listener); }
@Override public boolean add(FilteredBlock block) throws VerificationException, PrunedException { boolean success = super.add(block); if (success) { trackFilteredTransactions(block.getTransactionCount()); } return success; } }
/** * Adds a generic {@link ReorganizeListener} listener to the chain. */ public void addReorganizeListener(ReorganizeListener listener) { addReorganizeListener(Threading.USER_THREAD, listener); }
/** * Adds a generic {@link TransactionReceivedInBlockListener} listener to the chain. */ public void addTransactionReceivedListener(TransactionReceivedInBlockListener listener) { addTransactionReceivedListener(Threading.USER_THREAD, listener); }
StoredBlock head = getChainHead(); final StoredBlock splitPoint = findSplit(newChainHead, head, blockStore); log.info("Re-organize after split at height {}", splitPoint.getHeight()); log.info("Old chain head: {}", head.getHeader().getHashAsString()); final LinkedList<StoredBlock> oldBlocks = getPartialChain(head, splitPoint, blockStore); final LinkedList<StoredBlock> newBlocks = getPartialChain(newChainHead, splitPoint, blockStore); if (shouldVerifyTransactions()) { for (StoredBlock oldBlock : oldBlocks) { try { disconnectTransactions(oldBlock); } catch (PrunedException e) { cursor = it.next(); Block cursorBlock = cursor.getHeader(); if (expensiveChecks && cursorBlock.getTimeSeconds() <= getMedianTimestampOfRecentBlocks(cursor.getPrev(blockStore), blockStore)) throw new VerificationException("Block's timestamp is too early during reorg"); TransactionOutputChanges txOutChanges; if (cursor != newChainHead || block == null) txOutChanges = connectTransactions(cursor); else txOutChanges = connectTransactions(newChainHead.getHeight(), block); storedNewHead = addToBlockStore(storedNewHead, cursorBlock.cloneAsHeader(), txOutChanges); storedNewHead = addToBlockStore(storedPrev, newChainHead.getHeader()); setChainHead(storedNewHead);
if (shouldVerifyTransactions()) { checkNotNull(block.transactions); for (Transaction tx : block.transactions) StoredBlock head = getChainHead(); if (storedPrev.equals(head)) { if (filtered && filteredTxn.size() > 0) { if (expensiveChecks && block.getTimeSeconds() <= getMedianTimestampOfRecentBlocks(head, blockStore)) throw new VerificationException("Block's timestamp is too early"); if (shouldVerifyTransactions()) txOutChanges = connectTransactions(storedPrev.getHeight() + 1, block); StoredBlock newStoredBlock = addToBlockStore(storedPrev, block.transactions == null ? block : block.cloneAsHeader(), txOutChanges); versionTally.add(block.getVersion()); setChainHead(newStoredBlock); log.debug("Chain is now {} blocks high, running listeners", newStoredBlock.getHeight()); informListenersForNewBlock(block, NewBlockType.BEST_CHAIN, filteredTxHashList, filteredTxn, newStoredBlock); } else { log.info("Block is causing a re-organize"); } else { StoredBlock splitPoint = findSplit(newBlock, head, blockStore); if (splitPoint != null && splitPoint.equals(newBlock)) { addToBlockStore(storedPrev, block); int splitPointHeight = splitPoint.getHeight(); String splitPointHash = splitPoint.getHeader().getHashAsString();
/** * Add a wallet to the BlockChain. Note that the wallet will be unaffected by any blocks received while it * was not part of this BlockChain. This method is useful if the wallet has just been created, and its keys * have never been in use, or if the wallet has been loaded along with the BlockChain. Note that adding multiple * wallets is not well tested! */ public final void addWallet(Wallet wallet) { addNewBestBlockListener(Threading.SAME_THREAD, wallet); addReorganizeListener(Threading.SAME_THREAD, wallet); addTransactionReceivedListener(Threading.SAME_THREAD, wallet); int walletHeight = wallet.getLastBlockSeenHeight(); int chainHeight = getBestChainHeight(); if (walletHeight != chainHeight) { log.warn("Wallet/chain height mismatch: {} vs {}", walletHeight, chainHeight); log.warn("Hashes: {} vs {}", wallet.getLastBlockSeenHash(), getChainHead().getHeader().getHash()); // This special case happens when the VM crashes because of a transaction received. It causes the updated // block store to persist, but not the wallet. In order to fix the issue, we roll back the block store to // the wallet height to make it look like as if the block has never been received. if (walletHeight < chainHeight && walletHeight > 0) { try { rollbackBlockStore(walletHeight); log.info("Rolled back block store to height {}.", walletHeight); } catch (BlockStoreException x) { log.warn("Rollback of block store failed, continuing with mismatched heights. This can happen due to a replay."); } } } }