pbft

package
v0.0.0-...-f00b9cc Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2024 License: MIT Imports: 4 Imported by: 0

README

Practical Byzantine Fault Tolerance (PBFT)

Practical Byzantine Fault Tolerance (PBFT) is a consensus algorithm designed to work in distributed systems with potential Byzantine faults, which refer to arbitrary or malicious failures. PBFT is used to reach consensus even when some nodes in the network act maliciously or provide incorrect information. PBFT is particularly well-suited for scenarios where nodes may be compromised, such as in blockchain networks.

How PBFT Works

  1. Network Participants:
    • Primary Node: Also known as the leader, initiates proposals.
    • Replica Nodes: Other nodes that verify and agree on the correctness of the proposals.
  2. Phases of PBFT:
    • Pre-Prepare Phase: The primary node proposes a request by broadcasting it to all replica nodes.
    • Prepare Phase: Each replica verifies the request and broadcasts a prepare message to the network.
    • Commit Phase: Each node broadcasts a commit message after receiving enough prepare messages. If a replica receives enough commit messages, it commits the request to the blockchain.
  3. Consensus:
    • To reach consensus, at least 2f + 1 nodes (where f is the number of faulty nodes tolerated) must agree on the same value.
    • PBFT is effective in systems with a small number of malicious nodes.

Features of PBFT

  • Byzantine Fault Tolerance: PBFT can tolerate malicious or faulty nodes, making it ideal for use in environments where some nodes may not behave correctly.
  • Low Latency: Compared to Proof of Work (PoW), PBFT has lower latency since it does not require extensive computational resources to solve complex puzzles.
  • Deterministic Finality: Once consensus is reached, the value is immediately final and cannot be reverted.

Structure of This Implementation

In this folder, we provide a Go implementation of the PBFT consensus algorithm. The implementation demonstrates how nodes work together to reach consensus even in the presence of Byzantine faults.

Files
  • pbft.go: Contains the Go implementation of the Practical Byzantine Fault Tolerance consensus algorithm.
Key Elements of the Code
  • Blockchain: Represents the chain of blocks agreed upon by the nodes.
  • Node: Represents individual nodes that participate in consensus. Nodes can be primary or replica nodes.
  • Phases: The implementation simulates the Pre-Prepare, Prepare, and Commit phases to reach consensus.
Code Example
package main

import (
    "fmt"
    "consensus-algorithms-edu/algorithms/pbft"
)

func main() {
    blockchain := pbft.NewPBFTNetwork(5)

    blockchain.RunPBFT("First transaction data")
    blockchain.RunPBFT("Second transaction data")
    blockchain.RunPBFT("Third transaction data")

    for _, block := range blockchain.Blocks {
        fmt.Printf("Index: %d\nTimestamp: %s\nData: %s\nPrevious Hash: %s\nHash: %s\n\n", 
            block.Index, block.Timestamp, block.Data, block.PrevHash, block.Hash)
    }
}
How to Run the Example
  1. Initialize the Network: Use NewPBFTNetwork() to create a distributed network of nodes.
  2. Propose Values: Use RunPBFT() to propose a new value that all nodes must reach consensus on.
  3. Phases of PBFT: The algorithm will go through Pre-Prepare, Prepare, and Commit phases to reach consensus.
Advantages of PBFT
  • Byzantine Fault Tolerance: PBFT can tolerate up to f Byzantine faults in a network with 3f + 1 nodes, making it robust against malicious actors.
  • Efficiency: Unlike PoW, PBFT does not require computational resources for mining, leading to faster consensus.
  • Finality: Once consensus is achieved, the value is final, and there is no risk of chain reorganization.
Limitations
  • Scalability: PBFT works well in systems with a relatively small number of nodes. As the number of nodes increases, the communication overhead also increases.
  • Complex Communication: The consensus requires multiple rounds of communication between nodes, which can be complex and lead to delays if there are too many nodes.
License

This implementation is licensed under the MIT License.

Documentation

Overview

Package pbft implements a basic version of the Practical Byzantine Fault Tolerance (PBFT) consensus algorithm. PBFT is designed to allow a group of nodes to reach consensus in a distributed system, even in the presence of Byzantine faults—nodes that may behave arbitrarily or maliciously. This module simulates a blockchain network using PBFT to demonstrate how nodes work together to validate and commit new blocks, ensuring consistency and resilience against malicious actors. The algorithm requires agreement from at least 2/3 of the nodes for a block to be committed.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Block

type Block struct {
	Index     int    // The position of the block in the blockchain.
	Timestamp string // The time when the block was created.
	Data      string // The data contained in the block (e.g., transactions).
	PrevHash  string // The hash of the previous block, establishing continuity of the chain.
	Hash      string // The cryptographic hash of the current block's contents.
}

Block represents an individual block in the blockchain. Each block contains essential information, including metadata, the cryptographic hash, and the data it stores.

func NewBlock

func NewBlock(data string, prevHash string, index int) Block

NewBlock creates a new block given the data, index, and previous block hash. It calculates the hash for the new block to ensure data integrity.

func (*Block) CalculateHash

func (b *Block) CalculateHash() string

CalculateHash generates the SHA-256 hash of the block's contents. This ensures that each block is uniquely represented and immutable.

type Blockchain

type Blockchain struct {
	Blocks []Block // A slice of all blocks in the blockchain.
	Nodes  []Node  // A slice representing all nodes participating in PBFT consensus.
}

Blockchain represents the distributed ledger, which is maintained by nodes. It contains an ordered list of blocks, each of which is linked to its predecessor by cryptographic hash.

func NewBlockchain

func NewBlockchain() *Blockchain

NewBlockchain initializes a new blockchain with a genesis block, which serves as the root of the chain.

func NewPBFTNetwork

func NewPBFTNetwork(size int) *Blockchain

NewPBFTNetwork initializes a PBFT network with a specified number of nodes. The first node is assigned as the primary node, and all nodes are linked to the blockchain.

func (*Blockchain) AddBlock

func (bc *Blockchain) AddBlock(block Block)

AddBlock appends a new block to the blockchain.

func (*Blockchain) BroadcastBlock

func (bc *Blockchain) BroadcastBlock(block Block) bool

BroadcastBlock broadcasts a proposed block to all nodes in the network for verification. A block is considered valid if at least 2/3 of nodes approve it.

func (*Blockchain) RunPBFT

func (bc *Blockchain) RunPBFT(data string)

RunPBFT initiates the Practical Byzantine Fault Tolerance consensus process. The primary node proposes a new block, and if it receives approval from 2/3 of nodes, all nodes commit the block.

type Node

type Node struct {
	ID         int         // A unique identifier for the node.
	IsPrimary  bool        // A flag indicating if this node is the primary node (leader).
	State      string      // The state of the node (optional, for future implementation).
	Blockchain *Blockchain // Reference to the blockchain managed by the node.
}

Node represents an individual node participating in the PBFT protocol. Each node can propose, verify, and commit blocks, and maintains its own state and reference to the blockchain.

func NewNode

func NewNode(id int, isPrimary bool, blockchain *Blockchain) *Node

NewNode creates a new node with the given ID, assigns it as primary or follower, and links it to the blockchain.

func (*Node) CommitBlock

func (n *Node) CommitBlock(block Block)

CommitBlock adds a block to the blockchain, once it has been verified and approved by the network.

func (*Node) ProposeBlock

func (n *Node) ProposeBlock(data string) Block

ProposeBlock allows the primary node to create a new block proposal. It retrieves the latest block and proposes a new block with the given data.

func (*Node) VerifyBlock

func (n *Node) VerifyBlock(block Block) bool

VerifyBlock allows a node to verify the validity of a proposed block. The node checks if the block's previous hash matches the last block in the chain and if the block hash is valid.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL