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