This is broken for blocks that do not pass BIP30, so all BIP30-failing blocks which are allowed to fail BIP30
must be checkpointed.
327410
@Override
    protected void disconnectTransactions(StoredBlock oldBlock) throws PrunedException, BlockStoreException {
        checkState(lock.isHeldByCurrentThread());
        blockStore.beginDatabaseBatchWrite();
        try {
            StoredUndoableBlock undoBlock = blockStore.getUndoBlock(oldBlock.getHeader().getHash());
            if (undoBlock == null) throw new PrunedException(oldBlock.getHeader().getHash());
            TransactionOutputChanges txOutChanges = undoBlock.getTxOutChanges();
            for (UTXO out : txOutChanges.txOutsSpent)
                blockStore.addUnspentTransactionOutput(out);
            for (UTXO out : txOutChanges.txOutsCreated)
                blockStore.removeUnspentTransactionOutput(out);
        } catch (PrunedException e) {
            blockStore.abortDatabaseBatchWrite();
            throw e;
        } catch (BlockStoreException e) {
            blockStore.abortDatabaseBatchWrite();
            throw e;
        }
    }
63669
private void readBlock() throws IOException {
    int blockSize = readInt(in);
    final boolean compressed = (blockSize & LZ4FrameOutputStream.LZ4_FRAME_INCOMPRESSIBLE_MASK) == 0;
    blockSize &= ~LZ4FrameOutputStream.LZ4_FRAME_INCOMPRESSIBLE_MASK;

    // Check for EndMark
    if (blockSize == 0) {
      if (frameInfo.isEnabled(LZ4FrameOutputStream.FLG.Bits.CONTENT_CHECKSUM)) {
        final int contentChecksum = readInt(in);
        if (contentChecksum != frameInfo.currentStreamHash()) {
          throw new IOException("Content checksum mismatch");
        }
      }
      if (frameInfo.isEnabled(LZ4FrameOutputStream.FLG.Bits.CONTENT_SIZE) && expectedContentSize != totalContentSize) {
	throw new IOException("Size check mismatch");
      }
      frameInfo.finish();
      return;
    }

    final byte[] tmpBuffer; // Use a temporary buffer, potentially one used for compression
    if (compressed) {
      tmpBuffer = compressedBuffer;
    } else {
      tmpBuffer = rawBuffer;
    }
    if (blockSize > maxBlockSize) {
      throw new IOException(String.format(Locale.ROOT, "Block size %s exceeded max: %s", blockSize, maxBlockSize));
    }

    int offset = 0;
    while (offset < blockSize) {
      final int lastRead = in.read(tmpBuffer, offset, blockSize - offset);
      if (lastRead < 0) {
        throw new IOException(PREMATURE_EOS);
      }
      offset += lastRead;
    }

    // verify block checksum
    if (frameInfo.isEnabled(LZ4FrameOutputStream.FLG.Bits.BLOCK_CHECKSUM)) {
      final int hashCheck = readInt(in);
      if (hashCheck != checksum.hash(tmpBuffer, 0, blockSize, 0)) {
        throw new IOException(BLOCK_HASH_MISMATCH);
      }
    }

    final int currentBufferSize;
    if (compressed) {
      try {
        currentBufferSize = decompressor.decompress(tmpBuffer, 0, blockSize, rawBuffer, 0, rawBuffer.length);
      } catch (LZ4Exception e) {
        throw new IOException(e);
      }
    } else {
      currentBufferSize = blockSize;
    }
    if (frameInfo.isEnabled(LZ4FrameOutputStream.FLG.Bits.CONTENT_CHECKSUM)) {
      frameInfo.updateStreamHash(rawBuffer, 0, currentBufferSize);
    }
    totalContentSize += currentBufferSize;
    buffer.limit(currentBufferSize);
    buffer.rewind();
  }
697252
@Override
	protected void writeAllocationBlock( int blockIndex ) throws DataStoreException
    {
    	byte[] allocationBlock = serializeAllocationBlock(blockIndex);
        journal.writeMetaDataBlock(AT_HEADER_SIZE+blockIndex*AT_BLOCK_SIZE, allocationBlock);
    }
869545
@Override
  public void validate(byte[] blockBuffer, int rowOffset, int rowHead, int blobTail)
  {
    int offset = rowOffset + offset();
    
    int blobLen = BitsUtil.readInt16(blockBuffer, offset + 2);
    int blobOffset = BitsUtil.readInt16(blockBuffer, offset);
    
    if (blobLen == 0) {
      return;
    }
    
    if (blobOffset < 0 || blobTail < blobOffset) {
      throw new IllegalStateException(L.l("{0}: corrupted blob offset {1} with blobTail={2}",
                                          this, blobOffset, blobTail));
    }
    
    if ((blobLen & LARGE_BLOB_MASK) != 0) {
      blobLen &= ~LARGE_BLOB_MASK;
      
      if (blobLen != 4) {
        throw new IllegalStateException(L.l("{0}: corrupted blob len {1} for large blob.",
                                            this, blobOffset));
      }
    }
    
    
    if (blobLen < 0 || blobTail < blobLen + blobOffset) {
      throw new IllegalStateException(L.l("{0}: corrupted blob len {1} with blobOffset={2} blobTail={3}",
                                          this, blobLen, blobOffset, blobTail));
    }
  }
1140105
public void resetCheckpoint() {
        synchronized (lock) {
            if (c4ReplStatus != null && c4ReplStatus
                .getActivityLevel() != C4ReplicatorStatus.ActivityLevel.STOPPED) {
                throw new IllegalStateException(
                    "Replicator is not stopped. Resetting checkpoint is only allowed when the replicator is in the "
                        + "stopped state.");
            }
            shouldResetCheckpoint = true;
        }
    }
417582
public void addBlocksToDelete(List<Long> blocks) {
    for (long id : blocks) {
      if (mRemovingBlocks.contains(id)) {
        LOG.debug("{} is being removed. Current queue size is {}.", id, mBlocksToRemove.size());
        continue;
      }
      try {
        mBlocksToRemove.put(id);
        mRemovingBlocks.add(id);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        LOG.warn("AsyncBlockRemover got interrupted while it was putting block {}.", id);
      }
    }
  }
156762
public void checkpointStart()
  {
    if (_isWhileCheckpoint) {
      throw new IllegalStateException();
    }
    
    _isWhileCheckpoint = true;
    
    long sequence = ++_sequence;
    
    setSequence(sequence);
    
    byte []headerBuffer = _headerBuffer;
    BitsUtil.writeInt16(headerBuffer, 0, CHECKPOINT_START);
    writeImpl(headerBuffer, 0, 2);
    
    _lastCheckpointStart = _index - _startAddress;
  }
147763
protected void processMisReplicatedBlocks() {
    writeLock();
    try {
      if (this.initializedReplQueues) {
        return;
      }
      String logPrefix = "Processing mis-replicated blocks: ";
      long nrInvalid = 0;
      
      // clear queues
      neededReplications.clear();
      overReplicatedBlocks.clear();
      raidEncodingTasks.clear();
      
      int totalBlocks = blocksMap.size();
      
      // shutdown initial block report executor
      setupInitialBlockReportExecutor(true);
      
      // simply return if there are no blocks
      if (totalBlocks == 0) {
        // indicate that we are populating replication queues
        setInitializedReplicationQueues(true);
        LOG.info(logPrefix + "Blocks map empty. Nothing to do.");
        return;
      }
      
      AtomicLong count = new AtomicLong(0);
      
      // shutdown initial block report thread executor
      setupInitialBlockReportExecutor(true);
      
      FLOG.info(logPrefix + "Starting, total number of blocks: " + totalBlocks);
      long start = now();
      
      // have one thread process at least 1M blocks
      // no more than configured number of threads
      // at least one thread if the number of blocks < 1M
      int numShards = Math.min(parallelProcessingThreads,
          ((totalBlocks + parallelRQblocksPerShard - 1) / parallelRQblocksPerShard));
      
      // get shard iterators
      List<Iterator<BlockInfo>> iterators = blocksMap
          .getBlocksIterarors(numShards);

      // sanity, as the number can be lower in corner cases
      numShards = iterators.size();
      
      FLOG.info(logPrefix + "Using " + numShards + " threads");
      
      List<MisReplicatedBlocksWorker> misReplicationWorkers 
        = new ArrayList<MisReplicatedBlocksWorker>();
      List<Thread> misReplicationThreads = new ArrayList<Thread>();
      
      // workers will synchronize on this object to insert into 
      // replication queues
      Object lock = new Object();
      
      // initialize mis-replication worker threads
      for (int i = 0; i < numShards; i++) {
        MisReplicatedBlocksWorker w = new MisReplicatedBlocksWorker(lock, i, count,
            iterators.get(i), totalBlocks);
        Thread t = new Thread(w);
        t.start();
        misReplicationWorkers.add(w);
        misReplicationThreads.add(t);
      }
      
      // join all threads
      for (Thread t : misReplicationThreads) {
        try {
          t.join();
        } catch (InterruptedException e) { 
          Thread.currentThread().interrupt();
        }
      }
      
      // get number of invalidated blocks
      for (MisReplicatedBlocksWorker w : misReplicationWorkers) {
        nrInvalid += w.nrInvalid;
      }
      
      // update safeblock count (finalized blocks)
      this.blocksSafe = blocksMap.size() - getMissingBlocksCount();
      // update safeblock count (under construction blocks)
      for (MisReplicatedBlocksWorker w : misReplicationWorkers) {
        this.blocksSafe -= w.missingUnderConstructionBlocks;
      }
      
      // indicate that we are populating replication queues
      setInitializedReplicationQueues(true);

      long stop = now();
      
      FLOG.info(logPrefix + "Total number of blocks = " + blocksMap.size());
      FLOG.info(logPrefix + "Number of invalid blocks = " + nrInvalid);
      FLOG.info(logPrefix + "Number of under-replicated blocks = " +
          neededReplications.size());
      FLOG.info(logPrefix + "Number of  over-replicated blocks = " +
          overReplicatedBlocks.size());
      FLOG.info(logPrefix + "Number of safe blocks = " + this.blocksSafe);
      FLOG.info(logPrefix + "Finished in " + (stop - start) + " ms");
    } finally {
      writeUnlock();
    }
  }
1245306
private void blockIfNecessary() {
        if (diskPermits == null || diskLimit == Long.MAX_VALUE)
            return;
        try {
            diskPermits.acquire();
        } catch (InterruptedException e) {
            // don't want to re-interrupt so it won't cause SDK stream to be
            // closed in case the thread is reused for a different request
            throw new AbortedException(e);
        }
    }
910149
private boolean setupPipelineForAppend(LocatedBlock lastBlock) throws IOException {
    if (nodes == null || nodes.length == 0) {
      String msg = "Could not get block locations. " +
          "Source file \"" + src
          + "\" - Aborting...";
      DFSClient.LOG.warn(msg);
      setLastException(new IOException(msg));
      closed = true;
      if (streamer != null) streamer.close();
      return false;
    }
    
    boolean success = createBlockOutputStream(nodes, dfsClient.clientName, false, true);
    long oldGenerationStamp = 
        ((LocatedBlockWithOldGS)lastBlock).getOldGenerationStamp();
    
    if (success) {
      // bump up the generation stamp in NN.
      Block newBlock = lastBlock.getBlock();
      Block oldBlock = new Block(newBlock.getBlockId(), newBlock.getNumBytes(), 
          oldGenerationStamp);
      dfsClient.namenode.updatePipeline(dfsClient.clientName, 
          oldBlock, newBlock, nodes);
    } else {
      DFSClient.LOG.warn("Fall back to block recovery process when trying" +
          " to setup the append pipeline for file " + src);
      // set the old generation stamp 
      block.setGenerationStamp(oldGenerationStamp);
      // fall back the block recovery
      while(processDatanodeError(true, true)) {
        try {
          Thread.sleep(1000);
        } catch (InterruptedException  e) {
          lastException = new IOException(e);
          break;
        }
      }
    }
    return success;
  }
1219616
@Override
	protected void writeAllocationBlock( int blockIndex ) throws DataStoreException
    {
    	byte[] allocationBlock = serializeAllocationBlock(blockIndex);
        try
        {
	        allocationTableRandomAccessFile.seek(AT_HEADER_SIZE+blockIndex*AT_BLOCK_SIZE);
	        allocationTableRandomAccessFile.write(allocationBlock);
        }
    	catch (IOException e)
    	{
    		throw new DataStoreException("Cannot write to allocation table file : "+allocationTableFile.getAbsolutePath(),e);
    	}
    }
769259
private void block() {
        final long steps = this.limits.simpSteps;
        assert this.level == 0;
        assert !this.config.plain;
        if (!this.config.block) { return; }
        if (this.config.blkwait >= this.stats.simplifications) { return; }
        assert this.simplifier == Simplifier.TOPSIMP;
        this.simplifier = Simplifier.BLOCK;
        updateCands();
        final long limit;
        if (this.stats.simplifications <= this.config.blkrtc) { limit = Long.MAX_VALUE; } else { limit = this.stats.steps + 10 * steps / sizePenalty(); }
        while (this.empty == null && !this.candsBlock.empty() && this.stats.steps++ < limit) {
            final int cand = this.candsBlock.top();
            final long priority = this.candsBlock.priority(cand);
            this.candsBlock.pop(cand);
            if (priority == 0 || !var(cand).free()) { continue; }
            blockLit(cand);
            blockLit(-cand);
        }
        assert this.schedule;
        this.schedule = false;
        assert this.simplifier == Simplifier.BLOCK;
        this.simplifier = Simplifier.TOPSIMP;
    }
605501
public void abandonBlock(Block b, String src, String holder
      ) throws IOException {
    abandonBlockInternal(b, src, holder);
  }
689776
boolean removeFromCorruptReplicasMap(Block blk, DatanodeDescriptor datanode) {
    Collection<DatanodeDescriptor> datanodes = corruptReplicasMap.get(blk);
    if (datanodes==null)
      return false;
    if (datanodes.remove(datanode)) { // remove the replicas
      if (datanodes.isEmpty()) {
        // remove the block if there is no more corrupted replicas
        corruptReplicasMap.remove(blk);
      }
      return true;
    }
    return false;
  }
292538
def blockstack_backup_restore(working_dir, block_number):
    
    db = BlockstackDB.get_readwrite_instance(working_dir, restore=True, restore_block_height=block_number)
    try:
        db.db_restore(block_number=block_number)
    except Exception as e:
        raise e
    finally:
        db.close()

    return True
1167579
public boolean abandonBlock(Block b, String src, String holder
  ) throws IOException {
    writeLock();
    try {
      //
      // Remove the block from the pending creates list
      //
      if (NameNode.stateChangeLog.isDebugEnabled()) {
        NameNode.stateChangeLog.debug("BLOCK* NameSystem.abandonBlock: "
          + b + "of file " + src);
      }
      if (isInSafeMode()) {
        throw new SafeModeException("Cannot abandon block " + b +
          " for fle" + src, safeMode);
      }
      INodeFileUnderConstruction file = checkLease(src, holder);
      dir.removeBlock(src, file, b);
      if (NameNode.stateChangeLog.isDebugEnabled()) {
        NameNode.stateChangeLog.debug("BLOCK* NameSystem.abandonBlock: "
          + b
          + " is removed from pendingCreates");
      }
      return true;
    } finally {
      writeUnlock();
    }
  }
1099619
public boolean isBlock() throws SftpStatusException, SshException {
		// This is long hand because gcj chokes when it is not? Investigate why
		if ((getAttributes().getPermissions().longValue() & SftpFileAttributes.S_IFBLK) == SftpFileAttributes.S_IFBLK) {
			return true;
		}
		return false;
	}