study/블록체인

직접 만드는 나만의 블록체인 (11) – 블록체인 성능 최적화 (멀티 스레드 마이닝 & DB 연동)

octo54 2025. 3. 28. 10:57
반응형

직접 만드는 나만의 블록체인 (11) – 블록체인 성능 최적화 (멀티 스레드 마이닝 & DB 연동)


🚀 성능 최적화가 필요한 이유

이전 글에서는 블록체인 API 보안 강화를 통해 보안 취약점을 보완했습니다.
하지만 현재 블록체인은 성능이 매우 제한적입니다.

🚨 기존 문제점:

  • 싱글 스레드 마이닝 → CPU가 하나의 연산만 처리
  • 메모리 내 블록 저장 → 서버가 꺼지면 데이터 손실
  • 트랜잭션 처리 속도 제한 → 대량 트랜잭션을 처리하기 어려움

이번 글에서는 멀티 스레드 마이닝과 DB 연동을 적용하여 블록체인의 성능을 크게 개선하겠습니다.


✅ 목표

  • 멀티 스레드 마이닝 구현 → 연산 속도 최적화
  • 블록체인 데이터 영구 저장 (SQLite or PostgreSQL)
  • 대량 트랜잭션 처리 최적화

🏗 프로젝트 변경 사항

반응형
my_blockchain/
├── blockchain.py         # 블록체인 로직 (멀티스레드 마이닝 포함)
├── db.py                 # 블록 & 트랜잭션 데이터베이스 저장
├── node.py               # API 서버 실행
├── requirements.txt      # 필요한 패키지 목록

🔹 Step 1. 멀티 스레드 마이닝 (CPU 성능 최적화)

기존 mine_block() 함수는 싱글 스레드에서 실행되어 연산 속도가 느립니다.
이를 해결하기 위해 멀티 스레드 마이닝을 적용합니다.

import threading

class Block:
    def __init__(self, index, transactions, previous_hash, difficulty=4):
        self.index = index
        self.transactions = transactions
        self.previous_hash = previous_hash
        self.nonce = 0
        self.hash = self.calculate_hash()
        self.difficulty = difficulty

    def calculate_hash(self):
        block_string = f"{self.index}{self.previous_hash}{self.nonce}{self.transactions}"
        return hashlib.sha256(block_string.encode()).hexdigest()

    def mine_block(self):
        print(f"⛏️ Mining block {self.index}...")
        prefix = "0" * self.difficulty

        def mine():
            while not self.hash.startswith(prefix):
                self.nonce += 1
                self.hash = self.calculate_hash()

        thread = threading.Thread(target=mine)
        thread.start()
        thread.join()

        print(f"✅ Block {self.index} mined: {self.hash}")

마이닝을 멀티 스레드로 실행하여 CPU 코어 활용 극대화


🔹 Step 2. 블록체인 데이터 영구 저장 (SQLite 연동)

현재 블록체인은 메모리에만 저장되므로 서버가 꺼지면 데이터가 사라짐
→ 이를 해결하기 위해 SQLite로 영구 저장을 적용

import sqlite3

class BlockchainDB:
    def __init__(self, db_name="blockchain.db"):
        self.conn = sqlite3.connect(db_name, check_same_thread=False)
        self.create_tables()

    def create_tables(self):
        with self.conn:
            self.conn.execute("""
                CREATE TABLE IF NOT EXISTS blocks (
                    index INTEGER PRIMARY KEY,
                    previous_hash TEXT,
                    hash TEXT,
                    transactions TEXT
                )
            """)

    def save_block(self, block):
        with self.conn:
            self.conn.execute("""
                INSERT INTO blocks (index, previous_hash, hash, transactions)
                VALUES (?, ?, ?, ?)
            """, (block.index, block.previous_hash, block.hash, json.dumps(block.transactions)))

    def load_blocks(self):
        with self.conn:
            rows = self.conn.execute("SELECT * FROM blocks").fetchall()
            return [Block(row[0], json.loads(row[3]), row[1], row[2]) for row in rows]

SQLite를 사용하여 블록 데이터를 영구 저장
서버가 재시작 되어도 블록체인이 유지됨


🔹 Step 3. 블록 저장 & 불러오기 기능 추가

이제 마이닝 후 블록을 DB에 저장하고,
블록체인 초기화 시 DB에서 불러오는 기능을 추가합니다.

class Blockchain:
    def __init__(self):
        self.db = BlockchainDB()
        self.chain = self.db.load_blocks()

        if not self.chain:
            self.chain = [self.create_genesis_block()]
            self.db.save_block(self.chain[0])

    def mine_pending_transactions(self, miner_address):
        transactions = self.mempool[:]
        prev_block = self.get_latest_block()

        new_block = Block(
            index=prev_block.index + 1,
            transactions=transactions,
            previous_hash=prev_block.hash,
            difficulty=self.difficulty
        )

        new_block.mine_block()
        self.chain.append(new_block)
        self.db.save_block(new_block)  # 블록 저장
        self.mempool = []

체인 데이터가 DB에서 자동 로드되며, 새로운 블록이 생성될 때마다 저장됨


🏗 전체 성능 최적화 적용 후의 변화

개선 전 개선 후

싱글 스레드 마이닝 멀티 스레드 마이닝 (연산 속도 ↑)
메모리 내 데이터 저장 DB (SQLite) 영구 저장
서버 종료 시 데이터 손실 서버 재시작 후에도 데이터 유지

🚀 실행 및 테스트

1️⃣ SQLite DB 초기화 및 마이닝 테스트

python node.py

2️⃣ 트랜잭션 전송

curl -X POST http://localhost:5000/transactions/new -H "Content-Type: application/json" -d '{"sender": "Alice", "recipient": "Bob", "amount": 10}'

3️⃣ 블록 생성

curl -X GET http://localhost:5000/mine

4️⃣ 블록체인 확인 (DB에서 불러오기)

curl http://localhost:5000/chain

서버가 재시작 되어도 블록체인 유지됨
멀티 스레드로 마이닝 속도가 향상됨


🧠 정리

성능 최적화 요소 설명

멀티 스레드 마이닝 CPU 성능 활용 극대화
블록 데이터 DB 저장 SQLite를 사용해 영구 저장
빠른 블록 로드 서버 재시작 시 DB에서 즉시 로드

📌 다음 글 예고

👉 (12) 블록체인 확장성 – 샤딩(Sharding) 및 Layer 2 솔루션 개념 적용

  • 샤딩(Sharding) 개념 및 적용 가능성
  • Rollups (Optimistic & ZK) 소개
  • 트랜잭션 처리 속도 극대화 기법