OSDN Git Service

Repalce tp with mp (#434)
[bytom/bytom.git] / protocol / tx.go
1 package protocol
2
3 import (
4         "github.com/bytom/errors"
5         "github.com/bytom/protocol/bc"
6         "github.com/bytom/protocol/bc/types"
7         "github.com/bytom/protocol/validation"
8 )
9
10 // ErrBadTx is returned for transactions failing validation
11 var ErrBadTx = errors.New("invalid transaction")
12
13 // ValidateTx validates the given transaction. A cache holds
14 // per-transaction validation results and is consulted before
15 // performing full validation.
16 func (c *Chain) ValidateTx(tx *types.Tx) error {
17         newTx := tx.Tx
18         block := types.MapBlock(c.BestBlock())
19         if ok := c.txPool.HaveTransaction(&newTx.ID); ok {
20                 return c.txPool.GetErrCache(&newTx.ID)
21         }
22
23         // validate the UTXO
24         view := c.txPool.GetTransactionUTXO(tx.Tx)
25         if err := c.GetTransactionsUtxo(view, []*bc.Tx{newTx}); err != nil {
26                 c.txPool.AddErrCache(&newTx.ID, err)
27                 return err
28         }
29         if err := view.ApplyTransaction(block, newTx, false); err != nil {
30                 c.txPool.AddErrCache(&newTx.ID, err)
31                 return err
32         }
33
34         // validate the BVM contract
35         gasOnlyTx := false
36         gasStatus, err := validation.ValidateTx(newTx, block)
37         if err != nil {
38                 if !gasStatus.GasVaild {
39                         c.txPool.AddErrCache(&newTx.ID, err)
40                         return err
41                 }
42                 gasOnlyTx = true
43         }
44
45         _, err = c.txPool.AddTransaction(tx, gasOnlyTx, block.BlockHeader.Height, gasStatus.BTMValue)
46         return err
47 }