OSDN Git Service

Merge pull request #935 from Bytom/dev
[bytom/bytom.git] / protocol / tx.go
index 75e1c1a..38a5ab9 100644 (file)
@@ -4,44 +4,48 @@ import (
        "github.com/bytom/errors"
        "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/types"
+       "github.com/bytom/protocol/state"
        "github.com/bytom/protocol/validation"
 )
 
 // ErrBadTx is returned for transactions failing validation
 var ErrBadTx = errors.New("invalid transaction")
 
+// GetTransactionStatus return the transaction status of give block
+func (c *Chain) GetTransactionStatus(hash *bc.Hash) (*bc.TransactionStatus, error) {
+       return c.store.GetTransactionStatus(hash)
+}
+
+// GetTransactionsUtxo return all the utxos that related to the txs' inputs
+func (c *Chain) GetTransactionsUtxo(view *state.UtxoViewpoint, txs []*bc.Tx) error {
+       return c.store.GetTransactionsUtxo(view, txs)
+}
+
 // ValidateTx validates the given transaction. A cache holds
 // per-transaction validation results and is consulted before
 // performing full validation.
-func (c *Chain) ValidateTx(tx *types.Tx) error {
-       newTx := tx.Tx
-       block := types.MapBlock(c.BestBlock())
-       if ok := c.txPool.HaveTransaction(&newTx.ID); ok {
-               return c.txPool.GetErrCache(&newTx.ID)
+func (c *Chain) ValidateTx(tx *types.Tx) (bool, error) {
+       if ok := c.txPool.HaveTransaction(&tx.ID); ok {
+               return false, c.txPool.GetErrCache(&tx.ID)
        }
 
-       // validate the UTXO
        view := c.txPool.GetTransactionUTXO(tx.Tx)
-       if err := c.GetTransactionsUtxo(view, []*bc.Tx{newTx}); err != nil {
-               c.txPool.AddErrCache(&newTx.ID, err)
-               return err
+       if err := c.GetTransactionsUtxo(view, []*bc.Tx{tx.Tx}); err != nil {
+               return true, err
        }
-       if err := view.ApplyTransaction(block, newTx, false); err != nil {
-               c.txPool.AddErrCache(&newTx.ID, err)
-               return err
+
+       bh := c.BestBlockHeader()
+       block := types.MapBlock(&types.Block{BlockHeader: *bh})
+       if err := view.ApplyTransaction(block, tx.Tx, false); err != nil {
+               return true, err
        }
 
-       // validate the BVM contract
-       gasOnlyTx := false
-       gasStatus, err := validation.ValidateTx(newTx, block)
-       if err != nil {
-               if gasStatus == nil || !gasStatus.GasVaild {
-                       c.txPool.AddErrCache(&newTx.ID, err)
-                       return err
-               }
-               gasOnlyTx = true
+       gasStatus, err := validation.ValidateTx(tx.Tx, block)
+       if gasStatus.GasValid == false {
+               c.txPool.AddErrCache(&tx.ID, err)
+               return false, err
        }
 
-       _, err = c.txPool.AddTransaction(tx, gasOnlyTx, block.BlockHeader.Height, gasStatus.BTMValue)
-       return err
+       _, err = c.txPool.AddTransaction(tx, err != nil, block.BlockHeader.Height, gasStatus.BTMValue)
+       return false, err
 }