Skip to content

Vergil824/Blockchain-Practice

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

COMP3221 Assignment 2: Blockchain - Summary & Implementation Guide

1. Overall Goal

Implement a single blockchain node program. When multiple instances of this program run, they form a peer-to-peer (P2P) network that collectively maintains a distributed, consistent blockchain ledger by agreeing on blocks of transactions using a crash fault-tolerant consensus protocol.

2. Core Requirements

  • Node Functionality:

    • Act as both a TCP server (listen for incoming peer connections) and a TCP client (initiate connections to other peers).
    • Maintain persistent TCP connections with all known, non-crashed peers in a fully connected topology.
    • Manage a transaction pool (mempool) for pending transactions.
    • Validate incoming transactions based on strict rules (nonce, signature, format).
    • Participate in a synchronous, round-based consensus protocol to agree on the next block to add to the chain.
    • Maintain the local blockchain (append agreed-upon blocks).
    • Handle peer crashes and network issues (timeouts, disconnects) gracefully.
  • Programming Language & Libraries:

    • Use Python in this assignment
    • Submission must include a Run.sh wrapper script as the single entry point.
    • Strict Library Restriction: Only use Python Standard library plus PyNaCl/ed25519 for signatures. Using disallowed libraries results in zero marks.
  • Input/Output:

    • Input: Command-line arguments (<Port-Server> <Node-List-File>), network messages (transactions, consensus values).

    • Output: Standard Output (stdout) for logging accepted transactions and decided blocks in a specific JSON format. Network messages to peers. Boolean (True/False) responses over TCP for received transactions.

    • Strict Formatting: All JSON output to stdout must be pretty-printed with 2-space indentation and keys sorted lexicographically. Use double quotes for keys and strings. Adhere strictly to the examples:

      • {
          "type": "transaction",
          "payload": {
            "sender": "
              a57819938feb51bb3f923496c9dacde3e9f667b214a0fb1653b6bfc0f185363b",
            "message": "Never Gonna Give You Up",
            "nonce": 0,
            "signature": "142e395895e0bf4e4a3aabf2f59c3abc45c9c2b..."
        	}
        }

3. Key Components & Concepts

  • Transaction: A JSON object representing a request.

    • sender: 64-char hex Ed25519 public key.(hex-encoded 32-byte Ed25519 public key )
    • message: Up to 70 alphanumeric chars + spaces (UTF-8).
    • nonce: Integer, sequence number for the sender (starts at 0, increments per confirmed transaction).
    • signature: 128-char hex Ed25519 signature over sender+message+nonce.(The hex-encoded 64-byte Ed25519 signature of the transaction)
  • Block: A JSON object containing a batch of confirmed transactions.

    • index: Integer, block's position in the chain (Genesis is 1).
    • transactions: List of transaction objects included in the block.
    • previous_hash: 64-char hex SHA-256 hash of the previous block. For Genesis, it's 64 zeros.
    • current_hash: 64-char hex SHA-256 hash of this block's content (index, transactions, previous_hash), computed over a specific canonical JSON representation (keys sorted, specific separators - see Appendix D).
  • Transaction Pool (Mempool): Temporary storage for valid transactions waiting to be included in a block.

  • Blockchain: The local list/ledger of confirmed blocks. Starts with the Genesis block.

  • Genesis Block (Block 1):

    • index: 1
    • transactions: []
    • previous_hash: "0000..." (64 zeros)
    • current_hash: Calculated based on the above fields using the specified hashing method.
    • Must be initialized by every node. Not printed to stdout.
  • Networking Protocol:

    • TCP connections.
    • Messages are length-prefixed: 2-byte unsigned big-endian length, followed by the JSON message body.
      • 2 bytes field : indicate specifies the number of bytes in the message body
      • message body: The message body immediately follows the length field and consists of a JSON-encoded object. The maximum message length is 65535 bytes (0xFFFF)
    • Message Body Format: {"type": "...", "payload": ...}
    • Types:
      • "transaction": Payload is a single transaction object.
      • "values": Payload is a list of block proposal objects. Used for consensus exchange.
  • Validation Rules (Transactions):

    1. Nonce: Must be exactly sender's current confirmed nonce count + 1.
      1. If a received transaction’s nonce is not exactly one greater than the sender’s confirmed nonce (or 0 if the sender has none yet), then the transaction is out-of-order or duplicate and must be rejected. There must be no two different transactions with the same sender and same nonce in the pool. (The nonce is monotonically increasing per sender, starting from 0.)
    2. Signature: Must be a valid Ed25519 signature corresponding to the sender public key over the transaction's content (sender+message+nonce).
    3. Format: Fields must match expected types and constraints (lengths, characters).
    • Rejected transactions: Return False over TCP, do not add to pool or any blocks, do not print to stdout.

    • Accepted transactions: Return True over TCP, add to pool, print transaction JSON to stdout

4. Consensus Protocol (Simplified Synchronous Crash Fault-Tolerant)

  • Goal: All correct nodes agree on the same block for each round (chain height).
  • Fault Tolerance: Tolerates up to f = floor(n/2) - 1 crash failures (n = total nodes).
  • Round Structure: Triggered by events (new transaction, peer request), not a global clock.
  • Steps per Round:
    1. Trigger: Start a round if the local transaction pool is non-empty OR if a "values" request is received from a peer. If triggered by a request with an empty pool, prepare an "empty block" proposal (correct index/hash, empty transaction list).
    2. Propose: Create a block proposal containing valid transactions from the pool, the next index, the previous_hash from the current latest block, and the calculated current_hash.
    3. Exchange:
      • For each non-crashed peer: Send your proposal in a "values" message.
      • Wait exactly 2 seconds for a "values" response containing their proposal.
      • If response received: Store the peer's proposal.
      • If timeout: Mark the peer as crashed (persistently for future rounds) and ignore them for this round's decision.
      • Concurrently: Respond immediately to any incoming "values" requests with your own current proposal.
    4. Decide:
      • Gather all proposals received within the timeout (plus your own).
      • Filter proposals: If any proposal contains transactions, discard all empty block proposals.
      • Selection: Among the remaining (non-discarded) proposals, choose the one whose current_hash is lexicographically smallest.
      • (If all proposals were empty, choose the empty one with the lexicographically smallest current_hash).
    5. Commit:
      • Append the decided block to the local blockchain.
      • Print the decided block JSON to stdout.
      • Update node state: Increment nonces for senders whose transactions were included.
      • Clean up pool: Remove committed transactions. Remove any newly invalid transactions (e.g., conflicting nonces).
    6. Next Round: Return to step 1, waiting for a trigger.

5. Design & Implementation Ideas

  • Concurrency: Use threads or asynchronous I/O.
    • Main Thread: Initialization, start other threads/tasks.
    • Server Thread: Listens on the node's port, accepts incoming connections, spawns Peer Handler threads.
    • Peer Handler Thread (per connection): Dedicated to reading messages from one peer. Handles incoming transaction messages (validate, add to pool, respond True/False), handles incoming values requests (responds immediately with current proposal). Detects disconnects (EOF) and marks peer as crashed.
    • Client/Connector Logic: Manages outgoing connections to peers listed in the file. Handles retries on startup if a peer isn't up yet. Used by the consensus thread to send requests.
    • Consensus Thread: The core logic loop. Waits for a trigger (pool not empty / external request signal). Executes the propose-exchange-decide-commit steps. Needs to interact with client logic to send values requests and manage the 2-second timeouts.
  • State Management: Maintain node state carefully:
    • Current blockchain (list of blocks).
    • Transaction pool (use a set or dict for efficiency, perhaps keyed by tx hash or (sender, nonce)).
    • Peer status (addresses, socket objects, is_crashed flag).
    • Confirmed nonce count per sender (dictionary sender_pubkey -> nonce_count).
  • Synchronization: Use locks/mutexes/semaphores to protect shared data structures accessed by multiple threads (e.g., transaction pool, blockchain, nonce counts, peer status list).
  • Modularity: Separate concerns:
    • Networking module (sending/receiving framed JSON messages).
    • Validation module (transaction checks).
    • Blockchain state module (managing the chain, nonce counts).
    • Transaction Pool module.
    • Consensus logic module.
  • Networking Details:
    • Implement the 2-byte length prefixing correctly (unsigned, big-endian).
    • Read the length first, then read exactly that many bytes for the JSON.
    • Use socket timeouts (socket.settimeout() in Python or equivalent) only for the 2-second wait during the consensus exchange phase. Reset timeout to blocking/None afterwards for normal operation (receiving transactions).
    • Handle connection errors, EOF (peer disconnect), etc.
  • Hashing & Signatures:
    • Use the specified hashing script/logic (Appendix D) exactly, especially the json.dumps parameters (sort_keys=True, indent=2, separators=(',', ': ')).
    • Use the specified crypto library (e.g., PyNaCl) for Ed25519 signature verification. Ensure you verify against the correct data (sender+message+nonce).

6. Execution & Submission

  • Execution: ./Run.sh <Port-Server> <Node-List-File>
    • <Port-Server>: Port for this node to listen on.
    • <Node-List-File>: Path to a text file listing host:port of all peers (including potentially itself, though usually not needed for self-connection).
  • Submission:
    • All source code files.
    • Run.sh script.
    • README.md (brief description, instructions).
  • Testing: Test frequently on the Ed platform. Pay extreme attention to exact stdout formatting. Remove all debug prints before final submission unless they match the required output format.

7. Key Pitfalls & Things to Watch Out For

  • Library Restrictions: Double-check you are only using allowed libraries.
  • Stdout Formatting: Any deviation from the specified JSON format (indentation, sorted keys, spacing, quotes) will likely fail tests. Use json.dumps(obj, sort_keys=True, indent=2, separators=(',', ': ')) for hashing and consider similar precise formatting for stdout.
  • Hashing: The current_hash must be calculated exactly as specified in Appendix D. The specific separators argument is crucial and non-default.
  • Consensus Logic: Implement the decision rule (smallest hash, ignoring empty blocks if non-empty exist) correctly. Handle the 2-second timeout precisely. Manage the crashed status correctly.
  • Nonce Management: Nonce validation uses the count from the blockchain, not the pool. Increment nonces only after a block is committed.
  • Concurrency Issues: Ensure thread safety for shared resources (pool, chain, nonces). Deadlocks or race conditions can be hard to debug.
  • Genesis Block: Initialize it correctly but do not print it to stdout.
  • Network Framing: Correctly handle the 2-byte length prefix.
  • Transaction Response: Remember to send a simple True or False (or equivalent boolean serialization) back over the TCP connection after processing a received transaction message. This is separate from the JSON message protocol itself.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages