core: use error wrapping to provide more details

This commit is contained in:
Roman Khimov 2020-08-06 18:34:44 +03:00
parent 5ef08f60ae
commit 205f52c563
4 changed files with 18 additions and 18 deletions

View file

@ -420,7 +420,7 @@ func (bc *Blockchain) AddBlock(block *block.Block) error {
expectedHeight := bc.BlockHeight() + 1 expectedHeight := bc.BlockHeight() + 1
if expectedHeight != block.Index { if expectedHeight != block.Index {
return ErrInvalidBlockIndex return fmt.Errorf("expected %d, got %d: %w", expectedHeight, block.Index, ErrInvalidBlockIndex)
} }
headerLen := bc.headerListLen() headerLen := bc.headerListLen()
@ -1367,23 +1367,22 @@ func (bc *Blockchain) PoolTx(t *transaction.Transaction) error {
defer bc.lock.RUnlock() defer bc.lock.RUnlock()
if bc.HasTransaction(t.Hash()) { if bc.HasTransaction(t.Hash()) {
return ErrAlreadyExists return fmt.Errorf("blockchain: %w", ErrAlreadyExists)
} }
if err := bc.verifyTx(t, nil); err != nil { if err := bc.verifyTx(t, nil); err != nil {
return err return err
} }
// Policying. // Policying.
if ok, err := bc.contracts.Policy.CheckPolicy(bc.newInteropContext(trigger.Application, bc.dao, nil, t), t); err != nil { if err := bc.contracts.Policy.CheckPolicy(bc.newInteropContext(trigger.Application, bc.dao, nil, t), t); err != nil {
return err // Only one %w can be used.
} else if !ok { return fmt.Errorf("%w: %v", ErrPolicy, err)
return ErrPolicy
} }
if err := bc.memPool.Add(t, bc); err != nil { if err := bc.memPool.Add(t, bc); err != nil {
switch err { switch err {
case mempool.ErrOOM: case mempool.ErrOOM:
return ErrOOM return ErrOOM
case mempool.ErrConflict: case mempool.ErrConflict:
return ErrAlreadyExists return fmt.Errorf("mempool: %w", ErrAlreadyExists)
default: default:
return err return err
} }

View file

@ -3,6 +3,7 @@ package native
import ( import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"math/big" "math/big"
"sort" "sort"
"sync" "sync"
@ -510,21 +511,21 @@ func (p *Policy) checkValidators(ic *interop.Context) (bool, error) {
// CheckPolicy checks whether transaction's script hashes for verifying are // CheckPolicy checks whether transaction's script hashes for verifying are
// included into blocked accounts list. // included into blocked accounts list.
func (p *Policy) CheckPolicy(ic *interop.Context, tx *transaction.Transaction) (bool, error) { func (p *Policy) CheckPolicy(ic *interop.Context, tx *transaction.Transaction) error {
ba, err := p.GetBlockedAccountsInternal(ic.DAO) ba, err := p.GetBlockedAccountsInternal(ic.DAO)
if err != nil { if err != nil {
return false, err return fmt.Errorf("unable to get blocked accounts list: %w", err)
} }
scriptHashes, err := ic.Chain.GetScriptHashesForVerifying(tx) scriptHashes, err := ic.Chain.GetScriptHashesForVerifying(tx)
if err != nil { if err != nil {
return false, err return fmt.Errorf("unable to get tx script hashes: %w", err)
} }
for _, acc := range ba { for _, acc := range ba {
for _, hash := range scriptHashes { for _, hash := range scriptHashes {
if acc.Equals(hash) { if acc.Equals(hash) {
return false, nil return fmt.Errorf("account %s is blocked", hash.StringLE())
} }
} }
} }
return true, nil return nil
} }

View file

@ -843,12 +843,12 @@ func (s *Server) relayBlocksLoop() {
// verifyAndPoolTX verifies the TX and adds it to the local mempool. // verifyAndPoolTX verifies the TX and adds it to the local mempool.
func (s *Server) verifyAndPoolTX(t *transaction.Transaction) RelayReason { func (s *Server) verifyAndPoolTX(t *transaction.Transaction) RelayReason {
if err := s.chain.PoolTx(t); err != nil { if err := s.chain.PoolTx(t); err != nil {
switch err { switch {
case core.ErrAlreadyExists: case errors.Is(err, core.ErrAlreadyExists):
return RelayAlreadyExists return RelayAlreadyExists
case core.ErrOOM: case errors.Is(err, core.ErrOOM):
return RelayOutOfMemory return RelayOutOfMemory
case core.ErrPolicy: case errors.Is(err, core.ErrPolicy):
return RelayPolicyFail return RelayPolicyFail
default: default:
return RelayInvalid return RelayInvalid

View file

@ -917,8 +917,8 @@ func (s *Server) submitBlock(reqParams request.Params) (interface{}, *response.E
} }
err = s.chain.AddBlock(b) err = s.chain.AddBlock(b)
if err != nil { if err != nil {
switch err { switch {
case core.ErrInvalidBlockIndex, core.ErrAlreadyExists: case errors.Is(err, core.ErrInvalidBlockIndex) || errors.Is(err, core.ErrAlreadyExists):
return nil, response.ErrAlreadyExists return nil, response.ErrAlreadyExists
default: default:
return nil, response.ErrValidationFailed return nil, response.ErrValidationFailed