core: return error from verifyResults()

Make it easier to find out what the real problem is.
This commit is contained in:
Roman Khimov 2019-10-11 11:42:36 +03:00
parent 16bc5296cb
commit cffe8d0ee2

View file

@ -788,8 +788,8 @@ func (bc *Blockchain) Verify(t *transaction.Transaction) error {
if ok := bc.verifyOutputs(t); !ok { if ok := bc.verifyOutputs(t); !ok {
return errors.New("invalid transaction's outputs") return errors.New("invalid transaction's outputs")
} }
if ok := bc.verifyResults(t); !ok { if err := bc.verifyResults(t); err != nil {
return errors.New("invalid transaction's results") return err
} }
for _, a := range t.Attributes { for _, a := range t.Attributes {
@ -834,10 +834,10 @@ func (bc *Blockchain) verifyOutputs(t *transaction.Transaction) bool {
return true return true
} }
func (bc *Blockchain) verifyResults(t *transaction.Transaction) bool { func (bc *Blockchain) verifyResults(t *transaction.Transaction) error {
results := bc.GetTransationResults(t) results := bc.GetTransationResults(t)
if results == nil { if results == nil {
return false return errors.New("tx has no results")
} }
var resultsDestroy []*transaction.Result var resultsDestroy []*transaction.Result
var resultsIssue []*transaction.Result var resultsIssue []*transaction.Result
@ -851,38 +851,44 @@ func (bc *Blockchain) verifyResults(t *transaction.Transaction) bool {
} }
} }
if len(resultsDestroy) > 1 { if len(resultsDestroy) > 1 {
return false return errors.New("tx has more than 1 destroy output")
} }
if len(resultsDestroy) == 1 && resultsDestroy[0].AssetID != utilityTokenTX().Hash() { if len(resultsDestroy) == 1 && resultsDestroy[0].AssetID != utilityTokenTX().Hash() {
return false return errors.New("tx destroys non-utility token")
} }
if bc.SystemFee(t).GreaterThan(util.Fixed8(0)) && (len(resultsDestroy) == 0 || resultsDestroy[0].Amount.LessThan(bc.SystemFee(t))) { sysfee := bc.SystemFee(t)
return false if sysfee.GreaterThan(util.Fixed8(0)) {
if len(resultsDestroy) == 0 {
return fmt.Errorf("system requires to pay %s fee, but tx pays nothing", sysfee.String())
}
if resultsDestroy[0].Amount.LessThan(sysfee) {
return fmt.Errorf("system requires to pay %s fee, but tx pays %s only", sysfee.String(), resultsDestroy[0].Amount.String())
}
} }
switch t.Type { switch t.Type {
case transaction.MinerType, transaction.ClaimType: case transaction.MinerType, transaction.ClaimType:
for _, r := range resultsIssue { for _, r := range resultsIssue {
if r.AssetID != utilityTokenTX().Hash() { if r.AssetID != utilityTokenTX().Hash() {
return false return errors.New("miner or claim tx issues non-utility tokens")
} }
} }
break break
case transaction.IssueType: case transaction.IssueType:
for _, r := range resultsIssue { for _, r := range resultsIssue {
if r.AssetID == utilityTokenTX().Hash() { if r.AssetID == utilityTokenTX().Hash() {
return false return errors.New("issue tx issues utility tokens")
} }
} }
break break
default: default:
if len(resultsIssue) > 0 { if len(resultsIssue) > 0 {
return false return errors.New("non issue/miner/claim tx issues tokens")
} }
break break
} }
return true return nil
} }
// GetTransationResults returns the transaction results aggregate by assetID. // GetTransationResults returns the transaction results aggregate by assetID.