OSDN Git Service

Merge pull request #6 from Bytom/demo
[bytom/bytom.git] / protocol / tx.go
1 package protocol
2
3 import (
4         "github.com/bytom/errors"
5         "github.com/bytom/protocol/bc"
6         "github.com/bytom/protocol/bc/legacy"
7         "github.com/bytom/protocol/validation"
8 )
9
10 // ErrBadTx is returned for transactions failing validation
11 var ErrBadTx = errors.New("invalid transaction")
12
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 {
17         newTx := tx.Tx
18         err := c.checkIssuanceWindow(newTx)
19         if err != nil {
20                 return err
21         }
22         if ok := c.txPool.HaveTransaction(&newTx.ID); !ok {
23                 oldBlock, err := c.GetBlock(c.Height())
24                 if err != nil {
25                         return err
26                 }
27                 block := legacy.MapBlock(oldBlock)
28                 fee, err := validation.ValidateTx(newTx, block)
29
30                 if err == nil {
31                         c.txPool.AddTransaction(tx, block.BlockHeader.Height, fee)
32                 } else {
33                         c.txPool.AddErrCache(&newTx.ID, err)
34                 }
35         } else {
36                 return c.txPool.GetErrCache(&newTx.ID)
37         }
38         return errors.Sub(ErrBadTx, err)
39 }
40
41 func (c *Chain) checkIssuanceWindow(tx *bc.Tx) error {
42         if c.MaxIssuanceWindow == 0 {
43                 return nil
44         }
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)
49                         }
50                 }
51         }
52         return nil
53 }