OSDN Git Service

versoin1.1.9 (#594)
[bytom/vapor.git] / protocol / tx.go
1 package protocol
2
3 import (
4         log "github.com/sirupsen/logrus"
5
6         "github.com/bytom/vapor/protocol/bc"
7         "github.com/bytom/vapor/protocol/bc/types"
8         "github.com/bytom/vapor/protocol/state"
9         "github.com/bytom/vapor/protocol/validation"
10 )
11
12 // GetTransactionStatus return the transaction status of give block
13 func (c *Chain) GetTransactionStatus(hash *bc.Hash) (*bc.TransactionStatus, error) {
14         return c.store.GetTransactionStatus(hash)
15 }
16
17 // GetTransactionsUtxo return all the utxos that related to the txs' inputs
18 func (c *Chain) GetTransactionsUtxo(view *state.UtxoViewpoint, txs []*bc.Tx) error {
19         return c.store.GetTransactionsUtxo(view, txs)
20 }
21
22 // ValidateTx validates the given transaction. A cache holds
23 // per-transaction validation results and is consulted before
24 // performing full validation.
25 func (c *Chain) ValidateTx(tx *types.Tx) (bool, error) {
26         if c.hasSeenTx(tx) {
27                 return false, nil
28         }
29
30         bh := c.BestBlockHeader()
31         isOrphan, err := c.validateTx(tx, bh)
32         if err == nil && !isOrphan {
33                 c.markTransactions(tx)
34         }
35         return isOrphan, err
36 }
37
38 // validateTx validates the given transaction without checking duplication.
39 func (c *Chain) validateTx(tx *types.Tx, bh *types.BlockHeader) (bool, error) {
40         if ok := c.txPool.HaveTransaction(&tx.ID); ok {
41                 return false, c.txPool.GetErrCache(&tx.ID)
42         }
43
44         if c.txPool.IsDust(tx) {
45                 c.txPool.AddErrCache(&tx.ID, ErrDustTx)
46                 return false, ErrDustTx
47         }
48
49         gasStatus, err := validation.ValidateTx(tx.Tx, types.MapBlock(&types.Block{BlockHeader: *bh}))
50         if !gasStatus.GasValid {
51                 c.txPool.AddErrCache(&tx.ID, err)
52                 return false, err
53         }
54
55         txVerifyResult := &bc.TxVerifyResult{StatusFail: err != nil}
56         for _, p := range c.subProtocols {
57                 if err := p.ValidateTx(tx, txVerifyResult, bh.Height); err != nil {
58                         c.txPool.AddErrCache(&tx.ID, err)
59                         return false, err
60                 }
61         }
62
63         if err != nil {
64                 log.WithFields(log.Fields{"module": logModule, "tx_id": tx.Tx.ID.String(), "error": err}).Info("transaction status fail")
65         }
66
67         return c.txPool.ProcessTransaction(tx, err != nil, bh.Height, gasStatus.BTMValue)
68 }