github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/tx.go (about)

     1  package protocol
     2  
     3  import (
     4  	log "github.com/sirupsen/logrus"
     5  
     6  	"github.com/bytom/bytom/consensus/bcrp"
     7  	"github.com/bytom/bytom/errors"
     8  	"github.com/bytom/bytom/protocol/bc"
     9  	"github.com/bytom/bytom/protocol/bc/types"
    10  	"github.com/bytom/bytom/protocol/state"
    11  	"github.com/bytom/bytom/protocol/validation"
    12  )
    13  
    14  // ErrBadTx is returned for transactions failing validation
    15  var ErrBadTx = errors.New("invalid transaction")
    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 ok := c.txPool.HaveTransaction(&tx.ID); ok {
    27  		return false, c.txPool.GetErrCache(&tx.ID)
    28  	}
    29  
    30  	if c.txPool.IsDust(tx) {
    31  		c.txPool.AddErrCache(&tx.ID, ErrDustTx)
    32  		return false, ErrDustTx
    33  	}
    34  
    35  	bh := c.BestBlockHeader()
    36  	gasStatus, err := validation.ValidateTx(tx.Tx, types.MapBlock(&types.Block{BlockHeader: *bh}), c.ProgramConverter)
    37  	if err != nil {
    38  		log.WithFields(log.Fields{"module": logModule, "tx_id": tx.Tx.ID.String(), "error": err}).Info("transaction status fail")
    39  		c.txPool.AddErrCache(&tx.ID, err)
    40  		return false, err
    41  	}
    42  
    43  	return c.txPool.ProcessTransaction(tx, bh.Height, gasStatus.BTMValue)
    44  }
    45  
    46  //ProgramConverter convert program. Only for BCRP now
    47  func (c *Chain) ProgramConverter(prog []byte) ([]byte, error) {
    48  	hash, err := bcrp.ParseContractHash(prog)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	return c.store.GetContract(hash)
    54  }