• R/O
  • HTTP
  • SSH
  • HTTPS

vapor: Commit

Golang implemented sidechain for Bytom


Commit MetaInfo

Revision904d1051f328f6520da65661b453f40aecb469cb (tree)
Time2019-06-26 20:54:15
Authorpaladz <453256728@qq.c...>
Commiterpaladz

Log Message

speed up valiate tx

Change Summary

Incremental Difference

--- a/protocol/validation/block.go
+++ b/protocol/validation/block.go
@@ -88,17 +88,17 @@ func ValidateBlock(b *bc.Block, parent *types.BlockHeader) error {
8888 coinbaseAmount := consensus.BlockSubsidy(b.BlockHeader.Height)
8989 b.TransactionStatus = bc.NewTransactionStatus()
9090
91- for i, tx := range b.Transactions {
92- gasStatus, err := ValidateTx(tx, b)
93- if !gasStatus.GasValid {
94- return errors.Wrapf(err, "validate of transaction %d of %d", i, len(b.Transactions))
91+ validateResults := ValidateTxs(b.Transactions, b)
92+ for i, validateResult := range validateResults {
93+ if !validateResult.gasStatus.GasValid {
94+ return errors.Wrapf(validateResult.err, "validate of transaction %d of %d", i, len(b.Transactions))
9595 }
9696
97- if err := b.TransactionStatus.SetStatus(i, err != nil); err != nil {
97+ if err := b.TransactionStatus.SetStatus(i, validateResult.err != nil); err != nil {
9898 return err
9999 }
100- coinbaseAmount += gasStatus.BTMValue
101- if blockGasSum += uint64(gasStatus.GasUsed); blockGasSum > consensus.MaxBlockGas {
100+ coinbaseAmount += validateResult.gasStatus.BTMValue
101+ if blockGasSum += uint64(validateResult.gasStatus.GasUsed); blockGasSum > consensus.MaxBlockGas {
102102 return errOverBlockLimit
103103 }
104104 }
--- a/protocol/validation/tx.go
+++ b/protocol/validation/tx.go
@@ -3,6 +3,7 @@ package validation
33 import (
44 "fmt"
55 "math"
6+ "sync"
67
78 "github.com/vapor/config"
89 "github.com/vapor/consensus"
@@ -12,7 +13,10 @@ import (
1213 "github.com/vapor/protocol/vm"
1314 )
1415
15-const ruleAA = 142500
16+const (
17+ validateWorkerNum = 32
18+ ruleAA = 142500
19+)
1620
1721 // validate transaction error
1822 var (
@@ -570,3 +574,59 @@ func ValidateTx(tx *bc.Tx, block *bc.Block) (*GasState, error) {
570574 }
571575 return vs.gasStatus, checkValid(vs, tx.TxHeader)
572576 }
577+
578+type validateTxWork struct {
579+ i int
580+ tx *bc.Tx
581+ block *bc.Block
582+}
583+
584+type validateTxResult struct {
585+ i int
586+ gasStatus *GasState
587+ err error
588+}
589+
590+func validateTxWorker(workCh chan *validateTxWork, resultCh chan *validateTxResult, closeCh chan struct{}, wg *sync.WaitGroup) {
591+ for {
592+ select {
593+ case work := <-workCh:
594+ gasStatus, err := ValidateTx(work.tx, work.block)
595+ resultCh <- &validateTxResult{i: work.i, gasStatus: gasStatus, err: err}
596+ case <-closeCh:
597+ wg.Done()
598+ return
599+ }
600+ }
601+}
602+
603+func ValidateTxs(txs []*bc.Tx, block *bc.Block) []*validateTxResult {
604+ txSize := len(txs)
605+ //init the goroutine validate worker
606+ var wg sync.WaitGroup
607+ workCh := make(chan *validateTxWork, txSize)
608+ resultCh := make(chan *validateTxResult, txSize)
609+ closeCh := make(chan struct{})
610+ for i := 0; i <= validateWorkerNum && i < txSize; i++ {
611+ wg.Add(1)
612+ go validateTxWorker(workCh, resultCh, closeCh, &wg)
613+ }
614+
615+ //sent the works
616+ for i, tx := range txs {
617+ workCh <- &validateTxWork{i: i, tx: tx, block: block}
618+ }
619+
620+ //collect validate results
621+ results := make([]*validateTxResult, txSize)
622+ for i := 0; i < txSize; i++ {
623+ result := <-resultCh
624+ results[result.i] = result
625+ }
626+
627+ close(closeCh)
628+ wg.Wait()
629+ close(workCh)
630+ close(resultCh)
631+ return results
632+}
Show on old repository browser