Skip to content

vanillaSky00/merkleport

 
 

Repository files navigation

MerklePort: Blockchain FTP Server-Client

Java Gradle License

A Java-based system that combines a custom FTP server-client architecture with a blockchain backend to record, verify, and query transactions. Clients connect to the server over TCP sockets, submit transaction data, and the server batches them into blocks — each secured with SHA-256 hashing, Merkle tree verification, and adaptive mining difficulty.

Architecture Overview

Clients submit transactions through a custom text-based protocol. The server queues them, and once 4 transactions accumulate, the blockchain mines a new block. The server then broadcasts the block info (transaction IDs, timestamps, height) back to all connected clients and persists records to MySQL.

Table of Contents

Sequence Diagrams

FTP Connection Setup

sequenceDiagram
    autonumber
    participant GUI as GUI (SimpleGUI)
    participant C as FTPClient
    participant CCH as ClientCommandHandler
    participant S as FTPServer
    participant CH as ClientHandler

    Note over GUI,CH: Connection setup

    GUI->>C: new FTPClient(username)
    C->>C: Create Socket(127.0.0.1:9090)
    C->>S: TCP connect
    S->>S: ServerSocket.accept()
    S->>CH: new ClientHandler(socket)
    S->>S: pool.submit(clientHandler)

    Note over C,CH: Handshake

    C->>CCH: commandExecution(type=000, user, user)
    CCH->>S: [000] from Alice to Server : Alice
    CH->>CH: connectConfirm() — parse username
    CH-->>CCH: [333] from Server to Alice : connection succeeded
    CCH->>C: connectSuccess()
    C->>C: Enter polling loop (check upload/query)

    Note over S,CH: Server background threads already running
    S->>S: processTransactionQueue()
    S->>S: processReturnBlock()
    S->>S: processBlockInfo()
    S->>S: detectTransaction()
    S->>S: Chain.queueSizeChecking()
Loading

Transaction Recorded on Blockchain

sequenceDiagram
    autonumber
    participant C as FTPClient
    participant S as FTPServer
    participant CH as ClientHandler
    participant TQ as Transaction Queue
    participant BC as Chain (Blockchain)
    participant BK as BlockImpl
    participant MT as MerkleTree
    participant DH as DifficultyHandler
    participant DB as MySQL (DatabaseOperator)

    Note over C,DB: Client submits a transaction

    C->>S: [111] from Alice to Server : <transaction_text>
    CH->>CH: upload() — store transaction, wait on lock
    S->>S: detectTransaction() finds hasTransaction=true
    CH->>CH: handleTransaction() — mark as handling
    S->>TQ: transactionInLine.add(transaction)
    S->>S: clientsInLine.add("Alice")

    Note over TQ,BC: Queue drains into blockchain (needs 4 txns)

    TQ->>BC: addTransaction(tx1)
    Note right of TQ: ...repeat for tx2, tx3, tx4
    BC->>BC: queueSizeChecking() detects size ≥ 4
    BC->>BC: addBlock() — poll 4 transactions

    Note over BK,DH: Mining a new block

    BC->>BK: new BlockImpl(headBlock, transactions[4])
    BK->>MT: new MerkleTreeImpl(transactions)
    MT->>MT: Hash leaves with SHA-256
    MT->>MT: Pair and hash up the tree
    MT-->>BK: merkleRootHash
    BK->>BK: Generate transactionIDs (SHA-256)
    BK->>BK: Set initial difficulty from previous block

    rect rgb(255, 248, 230)
        Note over BK: Proof-of-Work mining loop
        BK->>BK: nonce++ → SHA-256(prevHash + merkle + nonce + ...)
        BK->>BK: Check leadingZeros > difficulty OR timeout (10 min)
        BK-->>BK: currentBlockHash found
    end

    BK->>DH: adjustDifficulty(blockProcessTime, difficulty)
    DH->>DH: Chain of Responsibility: safe or over?
    DH-->>BK: New difficulty level

    BK-->>BC: New block ready
    BC->>BC: headBlock = newBlock (link to chain)

    Note over S,DB: Server detects new block and broadcasts

    S->>S: processReturnBlock() detects height change
    S->>S: blockProcessingQueue.put(head)
    S->>S: processBlockInfo() takes block

    loop For each of 4 transactions
        S->>S: clientsInLine.take() → username
        S->>DB: insert(txID, user, time, fee, height)
    end

    Note over S,C: Broadcast to ALL connected clients

    S-->>CH: [333] from server to Alice : txID,user,time,fee,height/.../...
    CH->>CH: returnInfo() → finishTransaction()
    CH-->>C: Response with new block data
    C->>C: GUI displays block info
Loading

Core Components

Blockchain Layer

The blockchain is managed by the Chain class (singleton pattern), backed by a linked list of BlockImpl nodes:

  • Genesis Block — Automatically created on chain initialization with random seed data.
  • Block Creation — When 4 transactions are queued, a new BlockImpl is constructed, linking to the previous block via its SHA-256 hash.
  • Block Structure — Each block stores:
    • previousBlockHash / currentBlockHash
    • merkleRootHash — root of the block's Merkle tree
    • transactions[] / transactionIDs[] — raw data and their unique SHA-256 identifiers
    • height, nonce, timestamp, difficulty
  • Transaction Query — Given a block height and transaction ID (TXID), the chain traverses to the target block and verifies the transaction exists via the Merkle tree before returning the data.

Merkle Tree

Each block constructs a MerkleTreeImpl from its transactions:

  1. Leaf nodes — SHA-256 hash of each transaction.
  2. Internal nodes — SHA-256 hash of concatenated child pairs. If the count is odd, the last node is duplicated.
  3. Root — The final hash becomes the block's merkleRootHash.

The tree supports a search(inputData) method that re-derives the root from the leaf level, checking if the query data's hash path leads to the stored Merkle root — providing O(log n) data integrity verification.

Mining & Difficulty Adjustment

Block mining follows a proof-of-work scheme based on leading-zero requirements in the block hash:

  • The miner increments a nonce until the resulting SHA-256 hash has more leading zeros than the current difficulty target.
  • A 10-minute timeout prevents infinite mining on high difficulty — if exceeded, the block is accepted regardless.
  • Adaptive difficulty is handled by DifficultyHandler using a Chain of Responsibility pattern:
    • timeIntervalSafe — Maps block creation time (0–600 seconds) to difficulty levels 0–5.
    • timeIntervalOver — If mining exceeds the max threshold, a random lower difficulty is assigned to prevent stalling.
Block Time (s) Difficulty (leading zeros)
0 0
≤ 120 1
≤ 240 2
≤ 360 3
≤ 480 4
≤ 600 5
> 600 Random (0–4)

FTP Server-Client Layer

FTPServer (port 9090):

  • Accepts multiple client connections via a thread pool (ExecutorService).
  • Each client is managed by a dedicated ClientHandler thread.
  • Maintains three concurrent queues: transactionInLine, clientsInLine, and blockProcessingQueue.
  • Background threads handle: transaction detection → queue processing → chain submission → new block detection → broadcast to all clients.
  • Persists transaction metadata (ID, user, timestamp, handling fee, block height) to MySQL via DatabaseOperator + HikariCP connection pooling.

FTPClient:

  • Connects to the server, authenticates with a username, then polls for upload/query requests from the GUI.
  • Uses ClientCommandHandler for synchronized send-then-receive communication.
  • Displays results (new block info or query results) through the GUI layer.

Command Protocol

All communication uses a structured text format:

[TYPE] from SENDER to RECEIVER : PAYLOAD
Code Type Description
000 CONNECT Client connection handshake
111 UPLOAD Transaction submission
222 QUERY Transaction lookup by TXID
333 SUCCESS Server acknowledgment
444 ERROR Error response

Upload responses contain multiple transaction records separated by /, with individual fields separated by ,.

How It Works

See the Sequence Diagrams above for detailed step-by-step flows. In summary:

  1. Client connects → sends [000] from Alice to Server : Alice → server responds with [333] success.
  2. Client uploads a transaction → sends [111] from Alice to Server : <transaction_text>.
  3. Server queues the transaction. Once 4 transactions accumulate, the blockchain mines a new block.
  4. MiningBlockImpl constructs a Merkle tree, then searches for a nonce producing a SHA-256 hash meeting the current difficulty. Difficulty adjusts based on how long mining took.
  5. Broadcast — Server sends the new block info (transaction IDs, users, timestamps, heights) to all connected clients.
  6. Persistence — Transaction metadata is inserted into MySQL for future queries.
  7. Client queries → sends [222] from Alice to Server : <TXID> → server looks up the record in the database and returns the details.

Getting Started

Prerequisites

  • Java 17+
  • Gradle 7.5+Install guide
  • MySQL — A running MySQL instance (for transaction persistence)

Build

gradle clean build

Run

Start the server first, then launch one or more clients:

# Terminal 1 — Start the server
gradle runServer

# Terminal 2+ — Start clients
gradle runClient

The server listens on 127.0.0.1:9090 by default.

Features

  • Blockchain with Proof-of-Work — SHA-256 mining with nonce search and leading-zero difficulty.
  • Merkle Tree Verification — Every block builds a Merkle tree for tamper-evident transaction integrity.
  • Adaptive Difficulty — Automatically adjusts mining difficulty based on block creation time using a Chain of Responsibility pattern.
  • Multi-Client Support — Thread-pooled server handles concurrent client connections and transactions.
  • Real-Time Broadcast — All connected clients are notified when a new block is mined.
  • Transaction Query — Look up any transaction by its ID; verified against the Merkle tree before returning.
  • Custom FTP Protocol — Structured text-based protocol for upload, query, and response handling.
  • Database Persistence — Transaction records stored in MySQL via HikariCP connection pooling.
  • GUI Interface — Simple GUI for submitting transactions and viewing results.

Project Structure Overview

src/main/java/project/block_chain/
├── BlockChain/
│   ├── Block.java              # Block interface
│   ├── BlockImpl.java          # Block implementation (genesis, mining, hashing)
│   ├── BlockChain.java         # Blockchain interface
│   ├── Chain.java              # Singleton blockchain manager
│   ├── MerkleTree.java         # Merkle tree interface
│   ├── MerkleTreeImpl.java     # Merkle tree build & search
│   ├── DifficultyHandler.java  # Adaptive difficulty (Chain of Responsibility)
│   ├── SHA256.java             # SHA-256 hashing utilities
│   ├── BackupService.java      # Backup interface
│   ├── BlockchainBackupHandler.java  # Serialization-based block backup
│   └── SHA256SignatureHandler.java   # RSA digital signature for backups
├── FTP/
│   ├── FTPServer.java          # Multi-threaded server with queue management
│   ├── FTPClient.java          # Client with GUI integration
│   ├── ClientHandler.java      # Per-client server-side handler
│   ├── ClientCommandHandler.java  # Client-side command send/receive
│   ├── CommandFormat.java      # Protocol message formatting & parsing
│   ├── CommandMap.java         # Command type code mapping
│   └── DatabaseOperator.java   # MySQL operations (insert/query)
├── GUI/
│   ├── GUI.java                # GUI interface
│   └── SimpleGUI.java          # Simple GUI implementation
└── Main/
    ├── ServerMain.java         # Server entry point
    └── ClientMain.java         # Client entry point

Tech Stack

Component Technology
Language Java 17
Build Gradle 7.5.1 / Maven
Database MySQL 8.0 (mysql-connector-java)
Connection Pool HikariCP 5.0.1
Serialization Jackson XML 2.13
Logging SLF4J 1.7 + Logback 1.2
Cryptography SHA-256 (java.security), RSA (backup signing)

Work In Progress

  • Blockchain Backup & Restore — Block serialization with RSA digital signature verification. Backup files are signed with a private key; restoration verifies integrity using the corresponding public key. (Partially implemented)
  • Database Layer Completion — Full CRUD operations and advanced query support.
  • Timeout-Based Block Creation — Optional mode to create blocks even when fewer than 4 transactions are queued, after a configurable timeout.
  • Blockchain Rebuild — Restore a full chain from backup files given a public key and previous chain length.

Contributing

Feel free to dive in! Open an issue or submit a PR.

Maintainers

kji vanillaSky
kji vanillaSky

References

  • Satoshi Nakamoto, Bitcoin: A Peer-to-Peer Electronic Cash System, 2008.

About

A Java server-client (customed-FTP) system that records and verifies transactions with blockchain batching, Merkle trees, and MySQL persistence.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Java 100.0%