Ori Newman aeb4b96560
[NOD-1451] Implement Validators (#966)
* [NOD-1451] Implement block validator

* [NOD-1451] Implement block validator

* [NOD-1451] Fix merge errors

* [NOD-1451] Implement block validator

* [NOD-1451] Implement checkTransactionInIsolation

* [NOD-1451] Copy txscript to validator

* [NOD-1451] Change txscript to new design

* [NOD-1451] Add checkTransactionInContext

* [NOD-1451] Add checkBlockSize

* [NOD-1451] Add error handling

* [NOD-1451] Implement checkTransactionInContext

* [NOD-1451] Add checkTransactionMass placeholder

* [NOD-1451] Finish validators

* [NOD-1451] Add comments and stringers

* [NOD-1451] Return model.TransactionValidator interface

* [NOD-1451] Premake rule errors for each "code"

* [NOD-1451] Populate transaction mass

* [NOD-1451] Renmae functions

* [NOD-1451] Always use skipPow=false

* [NOD-1451] Renames

* [NOD-1451] Remove redundant types from WriteElement

* [NOD-1451] Fix error message

* [NOD-1451] Add checkTransactionPayload

* [NOD-1451] Add ValidateProofOfWorkAndDifficulty to block validator interface

* [NOD-1451] Move stringers to model

* [NOD-1451] Fix error message
2020-10-26 17:33:39 +02:00

55 lines
1.8 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/txscript"
"github.com/pkg/errors"
)
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) {
standaloneMass := v.transactionMassStandalonePart(tx)
sigOpsCount := uint64(0)
for _, input := range tx.Inputs {
utxoEntry := input.UTXOEntry
if utxoEntry == nil {
return 0, errors.Wrapf(ruleerrors.ErrMissingTxOut, "output %s "+
"either does not exist or "+
"has already been spent", input.PreviousOutpoint)
}
// 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))
}
return standaloneMass + sigOpsCount*MassPerSigOp, nil
}