Class BlockSerializer

java.lang.Object
com.privatechain.storage.BlockSerializer

public final class BlockSerializer extends Object
Shared Jackson-based JSON serializer / deserializer for Block objects.

Used internally by all persistent storage implementations (LevelDBStorage, RocksDBStorage, FileSystemStorage) to convert blocks to / from their JSON wire format. Centralizing serialization here ensures that all implementations use an identical format, making cross-implementation round-trips lossless.

Jackson configuration

  • JavaTimeModule — serializes Instant as ISO-8601 strings, not numeric timestamp arrays, when WRITE_DATES_AS_TIMESTAMPS is disabled.
  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES is disabled so that convenience getters on Block (e.g. getMerkleRoot(), which delegates to header.merkleRoot()) do not cause deserialization failures. Jackson serializes every public getter as a JSON field; those derived fields have no corresponding constructor parameter in Block's @JsonCreator and would otherwise trigger "Unrecognized field" errors. Disabling this feature is safe because verifyHash(Block) provides an independent integrity check after every deserialization (NFR-SEC-03).
  • Getter-based serialization is suppressed (PropertyAccessor.GETTER and IS_GETTER set to NONE) so only @JsonProperty-annotated constructor parameters are written to JSON. This prevents derived convenience getters such as getMerkleRoot() from producing redundant top-level fields, keeping stored JSON canonical and eliminating the round-trip mismatch at the source rather than merely tolerating it on the read path.
  • Polymorphic Transaction subtypes are handled by Jackson's @JsonTypeInfo annotation on the abstract Transaction base class (design §7.5, FR-SER-01).
Since:
1.0.0
  • Method Details

    • toBytes

      public static byte[] toBytes(Block block)
      Serializes a Block to its canonical UTF-8 JSON byte representation.

      Compact JSON (no pretty-printing) minimizes storage footprint, particularly in LevelDB and RocksDB where values are raw byte arrays.

      Parameters:
      block - the block to serialize (non-null)
      Returns:
      UTF-8 JSON byte array (non-null)
      Throws:
      BlockValidationException - if Jackson serialization fails
      NullPointerException - if block is null
    • toJson

      public static String toJson(Block block)
      Serializes a Block to a UTF-8 JSON string.

      Convenience wrapper around toBytes(Block) for storage backends that work with String values (e.g., FileSystemStorage).

      Parameters:
      block - the block to serialize (non-null)
      Returns:
      JSON string (non-null)
      Throws:
      BlockValidationException - if Jackson serialization fails
      NullPointerException - if block is null
    • fromBytes

      public static Block fromBytes(byte[] bytes)
      Deserializes a Block from a raw UTF-8 JSON byte array.

      After deserialization, the block's hash is recomputed and compared against the stored hash field to detect storage corruption (NFR-SEC-03). A mismatch causes a BlockValidationException.

      Parameters:
      bytes - raw UTF-8 JSON bytes (non-null, non-empty)
      Returns:
      the deserialized and hash-verified Block
      Throws:
      BlockValidationException - if deserialization fails or hash is corrupt
      NullPointerException - if bytes is null
    • fromJson

      public static Block fromJson(String json)
      Deserializes a Block from a UTF-8 JSON string.

      Convenience wrapper around fromBytes(byte[]) for storage backends that read String values (e.g., FileSystemStorage).

      Parameters:
      json - UTF-8 JSON string (non-null, non-blank)
      Returns:
      the deserialized and hash-verified Block
      Throws:
      BlockValidationException - if deserialization fails or hash is corrupt
      NullPointerException - if json is null