Class Blockchain

java.lang.Object
com.privatechain.core.builder.Blockchain

public final class Blockchain extends Object
The canonical chain manager — orchestrates block appending, chain validation, and event publication.

Blockchain is the single source of truth for the current state of the ledger. It delegates persistence to BlockchainStorage, consensus checks to ConsensusEngine, and state-change notifications to BlockchainEventBus (FR-CORE-04).

Thread safety

All public methods are thread-safe:

Chain integrity

On startup (when the chain is loaded from storage), callers should invoke isChainValid() to detect any corruption. addBlock(Block) performs incremental validation (hash linkage, Merkle root, consensus) on every new block.

Since:
1.0.0
See Also:
  • Constructor Details

    • Blockchain

      public Blockchain(ConsensusEngine consensusEngine, BlockchainStorage storage, BlockchainEventBus eventBus)
      Constructs a Blockchain with the given dependencies.

      Loads any previously persisted blocks from storage and appends them to the in-memory view. If storage is empty (first run), the genesis block is expected to be added explicitly by BlockchainNode during startup.

      Parameters:
      consensusEngine - the engine used to validate and produce blocks (non-null)
      storage - the persistence backend (non-null)
      eventBus - the event bus for publishing state-change events (non-null)
      Throws:
      NullPointerException - if any argument is null
  • Method Details

    • addBlock

      public void addBlock(Block block)
      Appends a new block to the chain after performing all validation checks.

      Validation sequence:

      1. Block hash integrity — block.isHashValid() must return true
      2. Chain linkage — block.getPreviousHash() must equal the latest block's hash
      3. Block index — must equal latestBlock.getIndex() + 1
      4. Consensus validation — ConsensusEngine.validateBlock(Block, Blockchain)

      On success, the block is persisted to BlockchainStorage and a BlockchainEvent.BlockAddedEvent is published asynchronously to all registered listeners.

      Parameters:
      block - the candidate block to append (non-null)
      Throws:
      NullPointerException - if block is null
      BlockValidationException - if any validation step fails
    • getBlock

      public Block getBlock(int index)
      Returns the block at the given index.
      Parameters:
      index - block index (≥ 0)
      Returns:
      the block at index
      Throws:
      NoSuchElementException - if no block exists at that index
    • getBlockByHash

      public Optional<Block> getBlockByHash(String hash)
      Returns the block with the given hash, if present.
      Parameters:
      hash - hex-encoded block hash (non-null)
      Returns:
      an Optional containing the block, or empty if not found
    • getLatestBlock

      public Block getLatestBlock()
      Returns the most recently added block (the chain tip).
      Returns:
      the latest block
      Throws:
      NoSuchElementException - if the chain is empty
    • getChain

      public List<Block> getChain()
      Returns all blocks in ascending index order.

      For large chains, iterating by index range is preferred over loading all blocks into memory at once.

      Returns:
      non-null, possibly empty list of all blocks
    • size

      public int size()
      Returns the number of blocks currently in the chain.
      Returns:
      chain size (≥ 0)
    • isEmpty

      public boolean isEmpty()
      Returns true if the chain contains no blocks.
      Returns:
      true when size() == 0
    • isChainValid

      public boolean isChainValid()
      Verifies the full integrity of the blockchain without network access (FR-CORE-06).

      Checks for each block (starting from index 1):

      1. The stored hash matches a fresh computation (tamper detection)
      2. The previousHash equals the hash of the preceding block

      An empty chain or a single-block chain (genesis only) is always considered valid.

      Returns:
      true if every block passes both checks
    • getConsensusEngine

      public ConsensusEngine getConsensusEngine()
      Returns the consensus engine used by this chain.
      Returns:
      non-null ConsensusEngine
    • getStorage

      public BlockchainStorage getStorage()
      Returns the storage backend used by this chain.

      SpotBugs flags this as EI_EXPOSE_REP because the returned reference is mutable. This is intentional: BlockchainStorage is a public SPI whose methods are called by modules that legitimately need write access. The field is private final, so the reference itself cannot be replaced; callers are responsible for not bypassing the concurrency contract defined in the SPI Javadoc.

      Returns:
      non-null BlockchainStorage