OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / protocol / tx.go
1 package protocol
2
3 import (
4         log "github.com/sirupsen/logrus"
5         "github.com/vapor/errors"
6         "github.com/vapor/protocol/bc"
7         "github.com/vapor/protocol/bc/types"
8         "github.com/vapor/protocol/state"
9         "github.com/vapor/protocol/validation"
10 )
11
12 // ErrBadTx is returned for transactions failing validation
13 var ErrBadTx = errors.New("invalid transaction")
14
15 // GetTransactionStatus return the transaction status of give block
16 func (c *Chain) GetTransactionStatus(hash *bc.Hash) (*bc.TransactionStatus, error) {
17         return c.store.GetTransactionStatus(hash)
18 }
19
20 // GetTransactionsUtxo return all the utxos that related to the txs' inputs
21 func (c *Chain) GetTransactionsUtxo(view *state.UtxoViewpoint, txs []*bc.Tx) error {
22         return c.store.GetTransactionsUtxo(view, txs)
23 }
24
25 // ValidateTx validates the given transaction. A cache holds
26 // per-transaction validation results and is consulted before
27 // performing full validation.
28 func (c *Chain) ValidateTx(tx *types.Tx) (bool, error) {
29         if ok := c.txPool.HaveTransaction(&tx.ID); ok {
30                 return false, c.txPool.GetErrCache(&tx.ID)
31         }
32
33         if ok := c.txPool.IsWithdrawSpent(tx); ok {
34                 log.WithFields(log.Fields{"module": "ValidateTx", "error": "Cliam transactions already exist in the trading pool"}).Error("chain error")
35                 return false, errors.New("Cliam transactions already exist in the trading pool")
36         }
37
38         bh := c.BestBlockHeader()
39         block := types.MapBlock(&types.Block{BlockHeader: *bh})
40         gasStatus, err := validation.ValidateTx(tx.Tx, block)
41         if gasStatus.GasValid == false {
42                 c.txPool.AddErrCache(&tx.ID, err)
43                 return false, err
44         }
45
46         if err != nil {
47                 log.WithFields(log.Fields{"tx_id": tx.Tx.ID.String(), "error": err}).Info("transaction status fail")
48         }
49
50         return c.txPool.ProcessTransaction(tx, err != nil, block.BlockHeader.Height, gasStatus.BTMValue)
51 }