🐛 Change sync to be more consistent

This commit is contained in:
Victor Bodinaud
2024-11-30 12:18:19 +01:00
parent 22d8b22ea1
commit 358bdda5a6
3 changed files with 90 additions and 27 deletions

View File

@@ -20,9 +20,9 @@ class Blockchain {
let block = Block()
block.previousHash = "0000genesis0000"
block.index = 0
block.timestamp = 1701388800 // 1er Décembre 2023 00:00:00 GMT
block.timestamp = 1701388800
block.difficulty = 4
block.nonce = 12345 // Nonce précalculé qui donne un hash valide
block.nonce = 12345
block.hash = "000088c1731bed4996680d2c50ea3d9b573c1507d2d61866c0deff33a7f8cf5e"
return block
}()
@@ -86,7 +86,7 @@ class Blockchain {
return nil
}
private func calculateNewDifficulty() -> Int {
func calculateNewDifficulty() -> Int {
guard chain.count >= 2 else { return minDifficulty }
let lastBlock = chain.last!
@@ -123,18 +123,18 @@ class Blockchain {
return true
}
func validateChain(_ newChain: [Block]) -> Bool {
func validateChain(_ chain: [Block]) -> Bool {
// Vérifier que la chaîne commence par notre bloc genesis codé en dur
guard let firstBlock = newChain.first,
guard let firstBlock = chain.first,
firstBlock.hash == Blockchain.genesisBlock.hash else {
print("Genesis block mismatch")
return false
}
// Vérifier les blocs suivants
for i in 1..<newChain.count {
let block = newChain[i]
let previousBlock = newChain[i-1]
for i in 1..<chain.count {
let block = chain[i]
let previousBlock = chain[i-1]
if block.previousHash != previousBlock.hash {
print("Invalid chain at block \(i): incorrect previous hash")

View File

@@ -10,15 +10,19 @@ import Network
class Node {
private var peers: [NWConnection] = []
private let port: NWEndpoint.Port = 8333 // Port standard
private let port: NWEndpoint.Port = 8333
private var listener: NWListener?
private let blockchain: Blockchain
// Le node possède et gère la blockchain
private let blockchain = Blockchain()
private let memPool: MemPool
private let accountManager = AccountManager()
// Queue pour gérer les connexions de manière asynchrone
private let queue = DispatchQueue(label: "com.blockchain.node")
init(blockchain: Blockchain) {
self.blockchain = blockchain
init() {
self.memPool = MemPool(accountManager: accountManager)
setupListener()
}
@@ -61,6 +65,71 @@ class Node {
}
}
func mineBlock(minerAddress: String) -> Block? {
guard let lastBlock = blockchain.chain.last else { return nil }
// Récupérer les transactions du mempool
var transactions = memPool.getTransactionsForBlock()
// Créer la récompense de minage
let miningReward = Transaction(
sender: "SYSTEM",
receiver: minerAddress,
amount: 50,
type: "MINING_REWARD"
)
transactions.append(miningReward)
// Créer et miner le bloc
let newBlock = Block(
transactions: transactions,
previousHash: lastBlock.hash,
index: blockchain.chain.count,
difficulty: blockchain.calculateNewDifficulty()
)
newBlock.miner = minerAddress
newBlock.timestamp = Int(Date().timeIntervalSince1970)
let miningTime = newBlock.mineBlock()
// Valider et traiter les transactions
if accountManager.processBlock(newBlock) {
blockchain.chain.append(newBlock)
broadcastBlock(newBlock)
print("""
Block \(newBlock.index) created:
Hash: \(newBlock.hash)
Previous hash: \(newBlock.previousHash)
Transactions: \(newBlock.transactions.count)
Mining time: \(String(format: "%.2f", miningTime)) seconds
""")
return newBlock
}
return nil
}
func submitTransaction(_ transaction: Transaction) -> Bool {
if memPool.addTransaction(transaction) {
broadcastTransaction(transaction)
return true
}
return false
}
func getBalance(_ address: String) -> Int {
return accountManager.getBalance(address)
}
func getPendingTransactions() -> [Transaction] {
return memPool.getAllPendingTransactions()
}
func isChainValid() -> Bool {
return blockchain.validateChain(blockchain.chain)
}
// Connexion à un pair
func connectToPeer(host: String) {
let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(host), port: port)

View File

@@ -8,10 +8,9 @@
import Foundation
let blockchain = Blockchain()
let node = Node(blockchain: blockchain)
let node = Node()
var command: String?
var currentMinerAddress = "MINER1" // Adresse par défaut du mineur
var currentMinerAddress = "MINER1"
var wallets: [String: Wallet] = [:]
print("""
@@ -27,8 +26,6 @@ Blockchain CLI - Commandes disponibles:
- exit : Quitter
""")
blockchain.createGenesisBlock()
repeat {
print("\nEntrer une commande:")
command = readLine()?.lowercased()
@@ -44,9 +41,9 @@ repeat {
node.listPeers()
case "mine":
if let block = blockchain.createBlock(minerAddress: currentMinerAddress) {
if let block = node.mineBlock(minerAddress: currentMinerAddress) {
print("Bloc miné avec succès. Récompense envoyée à \(currentMinerAddress)")
print("Nouveau solde: \(blockchain.getBalance(address: currentMinerAddress))")
print("Nouveau solde: \(node.getBalance(currentMinerAddress))")
} else {
print("Échec du minage")
}
@@ -54,7 +51,7 @@ repeat {
case "balance":
print("Entrer l'adresse:")
if let address = readLine() {
let balance = blockchain.getBalance(address: address)
let balance = node.getBalance(address)
print("Solde de \(address): \(balance)")
}
@@ -66,7 +63,7 @@ repeat {
}
case "pending":
let transactions = blockchain.memPool.getAllPendingTransactions()
let transactions = node.getPendingTransactions()
print("Transactions en attente: \(transactions.count)")
for (index, tx) in transactions.enumerated() {
print("""
@@ -78,7 +75,7 @@ repeat {
}
case "validity":
let isValid = blockchain.chainValidity()
let isValid = node.isChainValid()
print("Chaîne valide: \(isValid)")
case "exit":
@@ -91,12 +88,10 @@ repeat {
print("Nouveau wallet créé!")
print("Adresse: \(wallet.address)")
// Modifions la commande send
case "send":
print("Votre adresse (wallet):")
guard let senderAddress = readLine(),
let wallet = wallets[senderAddress]
else {
let wallet = wallets[senderAddress] else {
print("Wallet non trouvé")
break
}
@@ -119,8 +114,7 @@ repeat {
transaction.senderPublicKey = wallet.getPublicKeyData()
transaction.signature = wallet.signTransaction(transaction)
if blockchain.submitTransaction(transaction) {
node.broadcastTransaction(transaction)
if node.submitTransaction(transaction) {
print("Transaction propagée au réseau!")
} else {
print("Erreur lors de l'envoi de la transaction")