[NOD-1551] Add SigCache to TransactionValidator + Option to manipulate it in TestConsensus (#1159)

* [NOD-1551] Add SigCache

* [NOD-1551] Add option to edit SigCache in TestConsensus

* [NOD-1551] Fix comments and make SetSigCache pointer-receiver
This commit is contained in:
Svarog 2020-11-29 10:18:00 +02:00 committed by GitHub
parent baa4311a34
commit 048caebda3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 54 additions and 9 deletions

View File

@ -338,11 +338,14 @@ func (f *factory) NewTestConsensusWithDataDir(dagParams *dagconfig.Params, dataD
testConsensusStateManager := consensusstatemanager.NewTestConsensusStateManager(consensusAsImplementation.consensusStateManager)
testTransactionValidator := transactionvalidator.NewTestTransactionValidator(consensusAsImplementation.transactionValidator)
tstConsensus := &testConsensus{
consensus: consensusAsImplementation,
testConsensusStateManager: testConsensusStateManager,
testReachabilityManager: reachabilitymanager.NewTestReachabilityManager(consensusAsImplementation.
reachabilityManager),
testTransactionValidator: testTransactionValidator,
}
tstConsensus.testBlockBuilder = blockbuilder.NewTestBlockBuilder(consensusAsImplementation.blockBuilder, tstConsensus)
teardown = func() {

View File

@ -1,6 +1,8 @@
package model
import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// BlockValidator exposes a set of validation classes, after which
// it's possible to determine whether a block is valid

View File

@ -1,11 +1,21 @@
package model
import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
)
// TransactionValidator exposes a set of validation classes, after which
// it's possible to determine whether a transaction is valid
type TransactionValidator interface {
ValidateTransactionInIsolation(transaction *externalapi.DomainTransaction) error
ValidateTransactionInContextAndPopulateMassAndFee(tx *externalapi.DomainTransaction,
povBlockHash *externalapi.DomainHash, selectedParentMedianTime int64) error
povTransactionHash *externalapi.DomainHash, selectedParentMedianTime int64) error
}
// TestTransactionValidator adds to the main TransactionValidator methods required by tests
type TestTransactionValidator interface {
TransactionValidator
SigCache() *txscript.SigCache
SetSigCache(sigCache *txscript.SigCache)
}

View File

@ -48,5 +48,5 @@ type TestConsensus interface {
PruningManager() model.PruningManager
ReachabilityManager() model.TestReachabilityManager
SyncManager() model.SyncManager
TransactionValidator() model.TransactionValidator
TransactionValidator() model.TestTransactionValidator
}

View File

@ -0,0 +1,23 @@
package transactionvalidator
import (
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
)
type testTransactionValidator struct {
*transactionValidator
}
// NewTestTransactionValidator creates an instance of a TestTransactionValidator
func NewTestTransactionValidator(baseTransactionValidator model.TransactionValidator) model.TestTransactionValidator {
return &testTransactionValidator{transactionValidator: baseTransactionValidator.(*transactionValidator)}
}
func (tbv *testTransactionValidator) SigCache() *txscript.SigCache {
return tbv.sigCache
}
func (tbv *testTransactionValidator) SetSigCache(sigCache *txscript.SigCache) {
tbv.sigCache = sigCache
}

View File

@ -189,7 +189,7 @@ func (v *transactionValidator) validateTransactionScripts(tx *externalapi.Domain
scriptPubKey := utxoEntry.ScriptPublicKey
vm, err := txscript.NewEngine(scriptPubKey, tx,
i, txscript.ScriptNoFlags, nil)
i, txscript.ScriptNoFlags, v.sigCache)
if err != nil {
return errors.Wrapf(ruleerrors.ErrScriptMalformed, "failed to parse input "+
"%d which references output %s - "+

View File

@ -2,8 +2,11 @@ package transactionvalidator
import (
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
)
const sigCacheSize = 10_000
// transactionValidator exposes a set of validation classes, after which
// it's possible to determine whether either a transaction is valid
type transactionValidator struct {
@ -12,6 +15,7 @@ type transactionValidator struct {
pastMedianTimeManager model.PastMedianTimeManager
ghostdagDataStore model.GHOSTDAGDataStore
enableNonNativeSubnetworks bool
sigCache *txscript.SigCache
}
// New instantiates a new TransactionValidator
@ -26,5 +30,6 @@ func New(blockCoinbaseMaturity uint64,
databaseContext: databaseContext,
pastMedianTimeManager: pastMedianTimeManager,
ghostdagDataStore: ghostdagDataStore,
sigCache: txscript.NewSigCache(sigCacheSize),
}
}

View File

@ -12,9 +12,12 @@ type testConsensus struct {
testBlockBuilder model.TestBlockBuilder
testReachabilityManager model.TestReachabilityManager
testConsensusStateManager model.TestConsensusStateManager
testTransactionValidator model.TestTransactionValidator
}
func (tc *testConsensus) BuildBlockWithParents(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (*externalapi.DomainBlock, *model.UTXODiff, error) {
func (tc *testConsensus) BuildBlockWithParents(parentHashes []*externalapi.DomainHash,
coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (
*externalapi.DomainBlock, *model.UTXODiff, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()

View File

@ -116,6 +116,6 @@ func (tc *testConsensus) SyncManager() model.SyncManager {
return tc.syncManager
}
func (tc *testConsensus) TransactionValidator() model.TransactionValidator {
return tc.transactionValidator
func (tc *testConsensus) TransactionValidator() model.TestTransactionValidator {
return tc.testTransactionValidator
}

View File

@ -2249,7 +2249,6 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
secpHash := secp256k1.Hash(*sigHash)
var valid bool
if vm.sigCache != nil {
valid = vm.sigCache.Exists(secpHash, parsedSig, parsedPubKey)
if !valid && parsedPubKey.SchnorrVerify(&secpHash, parsedSig) {
vm.sigCache.Add(secpHash, parsedSig, parsedPubKey)