import (
"fmt"
"math"
+ "runtime"
"sync"
- "github.com/vapor/config"
- "github.com/vapor/consensus"
- "github.com/vapor/errors"
- "github.com/vapor/math/checked"
- "github.com/vapor/protocol/bc"
- "github.com/vapor/protocol/vm"
-)
-
-const (
- validateWorkerNum = 32
+ "github.com/bytom/vapor/common"
+ "github.com/bytom/vapor/config"
+ "github.com/bytom/vapor/consensus"
+ "github.com/bytom/vapor/errors"
+ "github.com/bytom/vapor/math/checked"
+ "github.com/bytom/vapor/protocol/bc"
+ "github.com/bytom/vapor/protocol/vm"
)
// validate transaction error
ErrGasCalculate = errors.New("gas usage calculate got a math error")
ErrVotePubKey = errors.New("invalid public key of vote")
ErrVoteOutputAmount = errors.New("invalid vote amount")
+ ErrVoteOutputAseet = errors.New("incorrect asset_id while checking vote asset")
)
// GasState record the gas usage status
if len(e.Vote) != 64 {
return ErrVotePubKey
}
+
vs2 := *vs
vs2.sourcePos = 0
if err = checkValidSrc(&vs2, e.Source); err != nil {
return ErrVoteOutputAmount
}
+ if *e.Source.Value.AssetId != *consensus.BTMAssetID {
+ return ErrVoteOutputAseet
+ }
+
case *bc.Retirement:
vs2 := *vs
vs2.sourcePos = 0
}
prog := &bc.Program{
- VmVersion: e.ControlProgram.VmVersion,
- Code: config.FederationWScript(config.CommonConfig),
+ VmVersion: e.AssetDefinition.IssuanceProgram.VmVersion,
+ Code: e.AssetDefinition.IssuanceProgram.Code,
+ }
+
+ if !common.IsOpenFederationIssueAsset(e.RawDefinitionByte) {
+ prog.Code = config.FederationWScript(config.CommonConfig, vs.block.Height)
}
if _, err := vm.Verify(NewTxVMContext(vs, e, prog, e.WitnessArguments), consensus.ActiveNetParams.DefaultGasCredit); err != nil {
return nil
}
+func applySoftFork001(vs *validationState, err error) {
+ if err == nil || vs.block.Height < consensus.ActiveNetParams.SoftForkPoint[consensus.SoftFork001] {
+ return
+ }
+
+ if rootErr := errors.Root(err); rootErr == ErrVotePubKey || rootErr == ErrVoteOutputAmount || rootErr == ErrVoteOutputAseet {
+ vs.gasStatus.GasValid = false
+ }
+}
+
// ValidateTx validates a transaction.
func ValidateTx(tx *bc.Tx, block *bc.Block) (*GasState, error) {
gasStatus := &GasState{GasValid: false}
gasStatus: gasStatus,
cache: make(map[bc.Hash]error),
}
- return vs.gasStatus, checkValid(vs, tx.TxHeader)
+
+ err := checkValid(vs, tx.TxHeader)
+ applySoftFork001(vs, err)
+ return vs.gasStatus, err
}
type validateTxWork struct {
// ValidateTxs validates txs in async mode
func ValidateTxs(txs []*bc.Tx, block *bc.Block) []*ValidateTxResult {
txSize := len(txs)
+ validateWorkerNum := runtime.NumCPU()
//init the goroutine validate worker
var wg sync.WaitGroup
workCh := make(chan *validateTxWork, txSize)