mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-28 01:36:42 +00:00

* Add new ErrMissingTxOut error * Add tests for ruleError wrapping * Update consensus to use new ErrMissingTxOut type where appropriate * Add new ErrInvalidTransactionsInNewBlock error * Add wrapping tests for ErrInvalidTransactionsInNewBlock * Fix Review suggestions * Fix broken serialization(add pointer redirection)
62 lines
2.0 KiB
Go
62 lines
2.0 KiB
Go
package transactionvalidator
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
|
)
|
|
|
|
const (
|
|
// MassPerTxByte is the number of grams that any byte
|
|
// adds to a transaction.
|
|
MassPerTxByte = 1
|
|
|
|
// MassPerScriptPubKeyByte is the number of grams that any
|
|
// scriptPubKey byte adds to a transaction.
|
|
MassPerScriptPubKeyByte = 10
|
|
|
|
// MassPerSigOp is the number of grams that any
|
|
// signature operation adds to a transaction.
|
|
MassPerSigOp = 10000
|
|
)
|
|
|
|
func (v *transactionValidator) transactionMassStandalonePart(tx *externalapi.DomainTransaction) uint64 {
|
|
size := estimatedsize.TransactionEstimatedSerializedSize(tx)
|
|
|
|
totalScriptPubKeySize := uint64(0)
|
|
for _, output := range tx.Outputs {
|
|
totalScriptPubKeySize += uint64(len(output.ScriptPublicKey))
|
|
}
|
|
|
|
return size*MassPerTxByte + totalScriptPubKeySize*MassPerScriptPubKeyByte
|
|
}
|
|
|
|
func (v *transactionValidator) transactionMass(tx *externalapi.DomainTransaction) (uint64, error) {
|
|
if transactionhelper.IsCoinBase(tx) {
|
|
return 0, nil
|
|
}
|
|
|
|
standaloneMass := v.transactionMassStandalonePart(tx)
|
|
sigOpsCount := uint64(0)
|
|
var missingOutpoints []externalapi.DomainOutpoint
|
|
for _, input := range tx.Inputs {
|
|
utxoEntry := input.UTXOEntry
|
|
if utxoEntry == nil {
|
|
missingOutpoints = append(missingOutpoints, input.PreviousOutpoint)
|
|
continue
|
|
}
|
|
// Count the precise number of signature operations in the
|
|
// referenced public key script.
|
|
sigScript := input.SignatureScript
|
|
isP2SH := txscript.IsPayToScriptHash(utxoEntry.ScriptPublicKey)
|
|
sigOpsCount += uint64(txscript.GetPreciseSigOpCount(sigScript, utxoEntry.ScriptPublicKey, isP2SH))
|
|
}
|
|
if len(missingOutpoints) > 0 {
|
|
return 0, ruleerrors.NewErrMissingTxOut(missingOutpoints)
|
|
}
|
|
|
|
return standaloneMass + sigOpsCount*MassPerSigOp, nil
|
|
}
|