🐛 Change sync to be more consistent
This commit is contained in:
@@ -20,9 +20,9 @@ class Blockchain {
|
|||||||
let block = Block()
|
let block = Block()
|
||||||
block.previousHash = "0000genesis0000"
|
block.previousHash = "0000genesis0000"
|
||||||
block.index = 0
|
block.index = 0
|
||||||
block.timestamp = 1701388800 // 1er Décembre 2023 00:00:00 GMT
|
block.timestamp = 1701388800
|
||||||
block.difficulty = 4
|
block.difficulty = 4
|
||||||
block.nonce = 12345 // Nonce précalculé qui donne un hash valide
|
block.nonce = 12345
|
||||||
block.hash = "000088c1731bed4996680d2c50ea3d9b573c1507d2d61866c0deff33a7f8cf5e"
|
block.hash = "000088c1731bed4996680d2c50ea3d9b573c1507d2d61866c0deff33a7f8cf5e"
|
||||||
return block
|
return block
|
||||||
}()
|
}()
|
||||||
@@ -86,7 +86,7 @@ class Blockchain {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func calculateNewDifficulty() -> Int {
|
func calculateNewDifficulty() -> Int {
|
||||||
guard chain.count >= 2 else { return minDifficulty }
|
guard chain.count >= 2 else { return minDifficulty }
|
||||||
|
|
||||||
let lastBlock = chain.last!
|
let lastBlock = chain.last!
|
||||||
@@ -123,18 +123,18 @@ class Blockchain {
|
|||||||
return true
|
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
|
// 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 {
|
firstBlock.hash == Blockchain.genesisBlock.hash else {
|
||||||
print("Genesis block mismatch")
|
print("Genesis block mismatch")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier les blocs suivants
|
// Vérifier les blocs suivants
|
||||||
for i in 1..<newChain.count {
|
for i in 1..<chain.count {
|
||||||
let block = newChain[i]
|
let block = chain[i]
|
||||||
let previousBlock = newChain[i-1]
|
let previousBlock = chain[i-1]
|
||||||
|
|
||||||
if block.previousHash != previousBlock.hash {
|
if block.previousHash != previousBlock.hash {
|
||||||
print("Invalid chain at block \(i): incorrect previous hash")
|
print("Invalid chain at block \(i): incorrect previous hash")
|
||||||
|
|||||||
@@ -10,15 +10,19 @@ import Network
|
|||||||
|
|
||||||
class Node {
|
class Node {
|
||||||
private var peers: [NWConnection] = []
|
private var peers: [NWConnection] = []
|
||||||
private let port: NWEndpoint.Port = 8333 // Port standard
|
private let port: NWEndpoint.Port = 8333
|
||||||
private var listener: NWListener?
|
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
|
// Queue pour gérer les connexions de manière asynchrone
|
||||||
private let queue = DispatchQueue(label: "com.blockchain.node")
|
private let queue = DispatchQueue(label: "com.blockchain.node")
|
||||||
|
|
||||||
init(blockchain: Blockchain) {
|
init() {
|
||||||
self.blockchain = blockchain
|
self.memPool = MemPool(accountManager: accountManager)
|
||||||
setupListener()
|
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
|
// Connexion à un pair
|
||||||
func connectToPeer(host: String) {
|
func connectToPeer(host: String) {
|
||||||
let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(host), port: port)
|
let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(host), port: port)
|
||||||
|
|||||||
@@ -8,10 +8,9 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
let blockchain = Blockchain()
|
let node = Node()
|
||||||
let node = Node(blockchain: blockchain)
|
|
||||||
var command: String?
|
var command: String?
|
||||||
var currentMinerAddress = "MINER1" // Adresse par défaut du mineur
|
var currentMinerAddress = "MINER1"
|
||||||
var wallets: [String: Wallet] = [:]
|
var wallets: [String: Wallet] = [:]
|
||||||
|
|
||||||
print("""
|
print("""
|
||||||
@@ -27,8 +26,6 @@ Blockchain CLI - Commandes disponibles:
|
|||||||
- exit : Quitter
|
- exit : Quitter
|
||||||
""")
|
""")
|
||||||
|
|
||||||
blockchain.createGenesisBlock()
|
|
||||||
|
|
||||||
repeat {
|
repeat {
|
||||||
print("\nEntrer une commande:")
|
print("\nEntrer une commande:")
|
||||||
command = readLine()?.lowercased()
|
command = readLine()?.lowercased()
|
||||||
@@ -44,9 +41,9 @@ repeat {
|
|||||||
node.listPeers()
|
node.listPeers()
|
||||||
|
|
||||||
case "mine":
|
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("Bloc miné avec succès. Récompense envoyée à \(currentMinerAddress)")
|
||||||
print("Nouveau solde: \(blockchain.getBalance(address: currentMinerAddress))")
|
print("Nouveau solde: \(node.getBalance(currentMinerAddress))")
|
||||||
} else {
|
} else {
|
||||||
print("Échec du minage")
|
print("Échec du minage")
|
||||||
}
|
}
|
||||||
@@ -54,7 +51,7 @@ repeat {
|
|||||||
case "balance":
|
case "balance":
|
||||||
print("Entrer l'adresse:")
|
print("Entrer l'adresse:")
|
||||||
if let address = readLine() {
|
if let address = readLine() {
|
||||||
let balance = blockchain.getBalance(address: address)
|
let balance = node.getBalance(address)
|
||||||
print("Solde de \(address): \(balance)")
|
print("Solde de \(address): \(balance)")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +63,7 @@ repeat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "pending":
|
case "pending":
|
||||||
let transactions = blockchain.memPool.getAllPendingTransactions()
|
let transactions = node.getPendingTransactions()
|
||||||
print("Transactions en attente: \(transactions.count)")
|
print("Transactions en attente: \(transactions.count)")
|
||||||
for (index, tx) in transactions.enumerated() {
|
for (index, tx) in transactions.enumerated() {
|
||||||
print("""
|
print("""
|
||||||
@@ -78,7 +75,7 @@ repeat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "validity":
|
case "validity":
|
||||||
let isValid = blockchain.chainValidity()
|
let isValid = node.isChainValid()
|
||||||
print("Chaîne valide: \(isValid)")
|
print("Chaîne valide: \(isValid)")
|
||||||
|
|
||||||
case "exit":
|
case "exit":
|
||||||
@@ -91,12 +88,10 @@ repeat {
|
|||||||
print("Nouveau wallet créé!")
|
print("Nouveau wallet créé!")
|
||||||
print("Adresse: \(wallet.address)")
|
print("Adresse: \(wallet.address)")
|
||||||
|
|
||||||
// Modifions la commande send
|
|
||||||
case "send":
|
case "send":
|
||||||
print("Votre adresse (wallet):")
|
print("Votre adresse (wallet):")
|
||||||
guard let senderAddress = readLine(),
|
guard let senderAddress = readLine(),
|
||||||
let wallet = wallets[senderAddress]
|
let wallet = wallets[senderAddress] else {
|
||||||
else {
|
|
||||||
print("Wallet non trouvé")
|
print("Wallet non trouvé")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -119,8 +114,7 @@ repeat {
|
|||||||
transaction.senderPublicKey = wallet.getPublicKeyData()
|
transaction.senderPublicKey = wallet.getPublicKeyData()
|
||||||
transaction.signature = wallet.signTransaction(transaction)
|
transaction.signature = wallet.signTransaction(transaction)
|
||||||
|
|
||||||
if blockchain.submitTransaction(transaction) {
|
if node.submitTransaction(transaction) {
|
||||||
node.broadcastTransaction(transaction)
|
|
||||||
print("Transaction propagée au réseau!")
|
print("Transaction propagée au réseau!")
|
||||||
} else {
|
} else {
|
||||||
print("Erreur lors de l'envoi de la transaction")
|
print("Erreur lors de l'envoi de la transaction")
|
||||||
|
|||||||
Reference in New Issue
Block a user