diff --git a/core/Blockchain.go b/core/Blockchain.go index deeb576..761a875 100644 --- a/core/Blockchain.go +++ b/core/Blockchain.go @@ -21,12 +21,12 @@ func (bc *Blockchain) MineBlock() Block { // Mine Block log.Print("Mining Block...") for { - if strings.HasPrefix(block.Hash(), "00000") { + if strings.HasPrefix(block.Hash(), "0000") { bc.Blocks = append(bc.Blocks, block) bc.PendingTransactions = []Transaction{} - log.Print("Block Added: ", block.Hash) + log.Print("Block Added: ", block.Hash()) return block } block.Proof++ @@ -62,6 +62,17 @@ func (bc *Blockchain) GetLastHash() string { return bc.Blocks[len(bc.Blocks)-1].Hash() } +// IsValid checks, if the chain has any faulty blocks +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 + } + } + + return true +} + // 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 diff --git a/core/block_test.go b/core/block_test.go index 2e6443a..9a8bc95 100644 --- a/core/block_test.go +++ b/core/block_test.go @@ -1,18 +1 @@ package core - -import ( - "testing" -) - -func TestBlock_AddTransaction(t *testing.T) { - block := Block{} - transaction := Transaction{Sender: "foo", Receiver: "bar", Message: "Test", Amount: 100} - block.AddTransaction(transaction) - - want := transaction - got := block.Data[0] - - if want != got { - t.Errorf("Want: %v, but got %v", want, got) - } -} diff --git a/core/blockchain_test.go b/core/blockchain_test.go index b3f22c1..4dde69f 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -4,8 +4,8 @@ import ( "testing" ) -func Test_generateGenesisBlock(t *testing.T) { - genesisBlock := generateGenesisBlock() +func Test_hasGenesisBlock(t *testing.T) { + genesisBlock := NewBlockchain().Blocks[0] if len(genesisBlock.PreviousHash) > 1 { t.Errorf("Previous hash of Genesis Block is not empty!") @@ -23,10 +23,34 @@ func TestNewBlockchain(t *testing.T) { func TestBlockchain_GetLastHash(t *testing.T) { blockchain := NewBlockchain() - blockchain.MineBlock(Block{}) - want := blockchain.Blocks[1].Hash + blockchain.MineBlock() + want := blockchain.Blocks[1].Hash() got := blockchain.GetLastHash() if got != want { t.Errorf("Want: %v, but got %v", want, got) } } + +func TestBlockchain_IsValid(t *testing.T) { + blockchain := NewBlockchain() + blockchain.MineBlock() + + want := true + got := blockchain.IsValid() + if got != want { + t.Errorf("Want: %v, but got %v", want, got) + } +} + +func TestBlockchain_IsNotValid(t *testing.T) { + blockchain := NewBlockchain() + blockchain.MineBlock() + blockchain.MineBlock() + blockchain.Blocks[1].Proof++ + + want := false + got := blockchain.IsValid() + if got != want { + t.Errorf("Want: %v, but got %v", want, got) + } +} diff --git a/server/webserver.go b/server/webserver.go index 6903cc3..42b4d41 100644 --- a/server/webserver.go +++ b/server/webserver.go @@ -32,6 +32,7 @@ func registerRouteHandlers() { http.HandleFunc("/mine_block", handleMineBlock) http.HandleFunc("/pending_transactions", handleListPendingTransactions) http.HandleFunc("/add_transaction", handleAddTransaction) + http.HandleFunc("/is_valid", handleIsValid) } func handleError(err error, w http.ResponseWriter, r *http.Request) { @@ -64,3 +65,8 @@ func handleMineBlock(w http.ResponseWriter, r *http.Request) { func handleListPendingTransactions(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(blockchain.PendingTransactions) } + +func handleIsValid(w http.ResponseWriter, r *http.Request) { + valid := blockchain.IsValid() + json.NewEncoder(w).Encode(valid) +}