4 "github.com/bytom/errors"
5 "github.com/bytom/protocol/bc"
6 "github.com/bytom/protocol/bc/legacy"
7 "github.com/bytom/protocol/validation"
10 // ErrBadTx is returned for transactions failing validation
11 var ErrBadTx = errors.New("invalid transaction")
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 *legacy.Tx) error {
18 if err := c.checkIssuanceWindow(newTx); err != nil {
21 if ok := c.txPool.HaveTransaction(&newTx.ID); ok {
22 return c.txPool.GetErrCache(&newTx.ID)
25 oldBlock, err := c.GetBlockByHash(c.state.hash)
29 block := legacy.MapBlock(oldBlock)
30 fee, err := validation.ValidateTx(newTx, block)
33 c.txPool.AddErrCache(&newTx.ID, err)
37 c.txPool.AddTransaction(tx, block.BlockHeader.Height, fee)
38 return errors.Sub(ErrBadTx, err)
41 func (c *Chain) checkIssuanceWindow(tx *bc.Tx) error {
42 if c.MaxIssuanceWindow == 0 {
45 for _, entryID := range tx.InputIDs {
46 if _, err := tx.Issuance(entryID); err == nil {
47 if tx.MinTimeMs+bc.DurationMillis(c.MaxIssuanceWindow) < tx.MaxTimeMs {
48 return errors.WithDetailf(ErrBadTx, "issuance input's time window is larger than the network maximum (%s)", c.MaxIssuanceWindow)