🐛 Change sync to be more consistent
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user