block: return error from Verify

Don't hide real problem behind the bool value. Makes it easier to identify
problems when looking at log messages.
This commit is contained in:
Roman Khimov 2019-10-11 11:40:54 +03:00
parent 258f397b9a
commit 16bc5296cb
3 changed files with 14 additions and 10 deletions

View file

@ -1,6 +1,9 @@
package core package core
import ( import (
"errors"
"fmt"
"github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/crypto" "github.com/CityOfZion/neo-go/pkg/crypto"
"github.com/CityOfZion/neo-go/pkg/io" "github.com/CityOfZion/neo-go/pkg/io"
@ -45,26 +48,26 @@ func (b *Block) rebuildMerkleRoot() error {
} }
// Verify the integrity of the block. // Verify the integrity of the block.
func (b *Block) Verify(full bool) bool { func (b *Block) Verify(full bool) error {
// There has to be some transaction inside. // There has to be some transaction inside.
if len(b.Transactions) == 0 { if len(b.Transactions) == 0 {
return false return errors.New("no transactions")
} }
// The first TX has to be a miner transaction. // The first TX has to be a miner transaction.
if b.Transactions[0].Type != transaction.MinerType { if b.Transactions[0].Type != transaction.MinerType {
return false return fmt.Errorf("the first transaction is %s", b.Transactions[0].Type)
} }
// If the first TX is a minerTX then all others cant. // If the first TX is a minerTX then all others cant.
for _, tx := range b.Transactions[1:] { for _, tx := range b.Transactions[1:] {
if tx.Type == transaction.MinerType { if tx.Type == transaction.MinerType {
return false return fmt.Errorf("miner transaction %s is not the first one", tx.Hash().ReverseString())
} }
} }
// TODO: When full is true, do a full verification. // TODO: When full is true, do a full verification.
if full { if full {
log.Warn("full verification of blocks is not yet implemented") log.Warn("full verification of blocks is not yet implemented")
} }
return true return nil
} }
// NewBlockFromTrimmedBytes returns a new block from trimmed data. // NewBlockFromTrimmedBytes returns a new block from trimmed data.

View file

@ -87,19 +87,19 @@ func TestBlockVerify(t *testing.T) {
newMinerTX(), newMinerTX(),
newIssueTX(), newIssueTX(),
) )
assert.True(t, block.Verify(false)) assert.Nil(t, block.Verify(false))
block.Transactions = []*transaction.Transaction{ block.Transactions = []*transaction.Transaction{
{Type: transaction.IssueType}, {Type: transaction.IssueType},
{Type: transaction.MinerType}, {Type: transaction.MinerType},
} }
assert.False(t, block.Verify(false)) assert.NotNil(t, block.Verify(false))
block.Transactions = []*transaction.Transaction{ block.Transactions = []*transaction.Transaction{
{Type: transaction.MinerType}, {Type: transaction.MinerType},
{Type: transaction.MinerType}, {Type: transaction.MinerType},
} }
assert.False(t, block.Verify(false)) assert.NotNil(t, block.Verify(false))
} }
func TestBinBlockDecodeEncode(t *testing.T) { func TestBinBlockDecodeEncode(t *testing.T) {

View file

@ -210,8 +210,9 @@ func (bc *Blockchain) AddBlock(block *Block) error {
return fmt.Errorf("expected block %d, but passed block %d", expectedHeight, block.Index) return fmt.Errorf("expected block %d, but passed block %d", expectedHeight, block.Index)
} }
if bc.verifyBlocks { if bc.verifyBlocks {
if !block.Verify(false) { err := block.Verify(false)
return fmt.Errorf("block %s is invalid", block.Hash()) if err != nil {
return fmt.Errorf("block %s is invalid: %s", block.Hash().ReverseString(), err)
} }
for _, tx := range block.Transactions { for _, tx := range block.Transactions {
err := bc.Verify(tx) err := bc.Verify(tx)