func TestVerifyBlockHeader(t *testing.T) { ft := FakeTree{} bc := NewBlockchain(&ft, nil) gb := bc.CreateGenesisBlock(genAddress, _genCoins, _genTime) b := coin.Block{Body: coin.BlockBody{}} b.Body.Transactions = append(b.Body.Transactions, makeTransaction(t)) h := coin.BlockHeader{} h.BkSeq = 1 h.Time = gb.Head.Time + 1 h.PrevHash = gb.HashHeader() h.BodyHash = b.HashBody() // Valid header b.Head = h assert.Nil(t, bc.verifyBlockHeader(b)) // Invalid bkSeq i := h i.BkSeq++ b.Head = i assertError(t, bc.verifyBlockHeader(b), "BkSeq invalid") // Invalid time i = h i.Time = gb.Head.Time b.Head = i assertError(t, bc.verifyBlockHeader(b), "Block time must be > head time") b.Head.Time-- assertError(t, bc.verifyBlockHeader(b), "Block time must be > head time") // Invalid prevHash i = h i.PrevHash = cipher.SHA256{} b.Head = i assertError(t, bc.verifyBlockHeader(b), "PrevHash does not match current head") // Invalid bodyHash i = h i.BodyHash = cipher.SHA256{} b.Head = i assertError(t, bc.verifyBlockHeader(b), "Computed body hash does not match") }
// VerifyBlockHeader Returns error if the BlockHeader is not valid func (bc Blockchain) verifyBlockHeader(b coin.Block) error { //check BkSeq head := bc.Head() if b.Head.BkSeq != head.Head.BkSeq+1 { return errors.New("BkSeq invalid") } //check Time, only requirement is that its monotonely increasing if b.Head.Time <= head.Head.Time { return errors.New("Block time must be > head time") } // Check block hash against previous head if b.Head.PrevHash != head.HashHeader() { return errors.New("PrevHash does not match current head") } if b.HashBody() != b.Head.BodyHash { return errors.New("Computed body hash does not match") } return nil }