Browse Source

Add ReplaceChain and NotifyPeers

pull/9/head
garritfra 5 years ago
parent
commit
3251055520
  1. 3
      core/Block.go
  2. 43
      core/Blockchain.go

3
core/Block.go

@ -17,8 +17,8 @@ type Block struct {
// JSONBlock representation
type JSONBlock struct {
Timestamp time.Time `json:"timestamp"`
Hash string `json:"hash"`
PreviousHash string `json:"previous_hash"`
Hash string `json:"hash"`
Data []Transaction `json:"data"`
Proof int `json:"nonce"`
}
@ -33,6 +33,7 @@ func (block *Block) AsJSON() JSONBlock {
return JSONBlock{Timestamp: block.Timestamp, Hash: block.Hash(), PreviousHash: block.PreviousHash, Data: block.Data, Proof: block.Proof}
}
// FromJSON casts a `JSONBlock` to a regular `Block` struct
func (block *JSONBlock) FromJSON() Block {
return Block{Timestamp: block.Timestamp, PreviousHash: block.PreviousHash, Data: block.Data, Proof: block.Proof}
}

43
core/Blockchain.go

@ -29,12 +29,12 @@ func (bc *Blockchain) MineBlock() Block {
bc.Blocks = append(bc.Blocks, block)
bc.PendingTransactions = []Transaction{}
bc.NotifyPeers()
log.Print("Block Added: ", block.Hash())
return block
}
block.Proof++
}
}
// NewBlockchain creates a new Blockchain
@ -91,7 +91,7 @@ func contains(s []string, e string) bool {
}
// IsValid checks, if the chain has any faulty blocks
func (bc *Blockchain) IsValid() bool {
func (bc Blockchain) IsValid() bool {
for i := 1; i < len(bc.Blocks); i++ {
if bc.Blocks[i-1].Hash() != bc.Blocks[i].PreviousHash {
return false
@ -101,6 +101,14 @@ func (bc *Blockchain) IsValid() bool {
return true
}
// NotifyPeers requests an update to all peers
func (bc *Blockchain) NotifyPeers() {
for _, peer := range bc.Peers {
http.Get("http://" + peer + "/update")
}
}
// Update compares the length of the own chain to the blocklength of every known peer, and updates the chain accordingly
func (bc *Blockchain) Update() bool {
var hasBeenReplaced = false
@ -112,15 +120,8 @@ func (bc *Blockchain) Update() bool {
var receivedBlockchain JSONBlockchain
err = decoder.Decode(&receivedBlockchain)
if err == nil {
if receivedBlockchain.Blockcount > bc.AsJSON().Blockcount {
newBlocks := make([]Block, 0)
for _, block := range receivedBlockchain.Blocks {
newBlocks = append(newBlocks, block.FromJSON())
}
bc.Blocks = newBlocks
if receivedBlockchain.Blockcount > bc.AsJSON().Blockcount && receivedBlockchain.FromJSON().IsValid() {
bc.replaceChain(receivedBlockchain.FromJSON())
log.Println("Blockchain has been updated by " + peer)
hasBeenReplaced = true
}
@ -129,6 +130,16 @@ func (bc *Blockchain) Update() bool {
return hasBeenReplaced
}
func (bc *Blockchain) replaceChain(newChain Blockchain) {
newBlocks := make([]Block, 0)
for _, block := range newChain.Blocks {
newBlocks = append(newBlocks, block)
}
bc.Blocks = newBlocks
bc.NotifyPeers()
}
// JSONBlockchain is needed, because the hash of each block is calculated dynamically, and therefore is not stored in the `Block` struct
type JSONBlockchain struct {
Blocks []JSONBlock
@ -148,3 +159,13 @@ func (bc *Blockchain) AsJSON() JSONBlockchain {
return jsonChain
}
// FromJSON casts a `JSONBlockchain` to a regular `Blockchain` struct
func (bc *JSONBlockchain) FromJSON() Blockchain {
chain := Blockchain{PendingTransactions: bc.PendingTransactions, Peers: bc.Peers}
for _, block := range bc.Blocks {
chain.Blocks = append(chain.Blocks, block.FromJSON())
}
return chain
}

Loading…
Cancel
Save