blockchain: properly set invocation counter for verification ctx

Fix problem noted in #2270.
This commit is contained in:
Roman Khimov 2022-01-13 01:34:46 +03:00
parent 9f9bd7261c
commit fc45d3b132
4 changed files with 12 additions and 19 deletions

View file

@ -22,7 +22,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result/subscriptions"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm"
uatomic "go.uber.org/atomic"
)
@ -104,8 +103,8 @@ func (chain *FakeChain) IsTxStillRelevant(t *transaction.Transaction, txpool *me
panic("TODO")
}
// InitVerificationVM initializes VM for witness check.
func (chain *FakeChain) InitVerificationVM(v *vm.VM, getContract func(util.Uint160) (*state.Contract, error), hash util.Uint160, witness *transaction.Witness) error {
// InitVerificationContext initializes context for witness check.
func (chain *FakeChain) InitVerificationContext(ic *interop.Context, hash util.Uint160, witness *transaction.Witness) error {
panic("TODO")
}

View file

@ -2160,8 +2160,8 @@ var (
ErrInvalidVerificationContract = errors.New("verification contract is missing `verify` method")
)
// InitVerificationVM initializes VM for witness check.
func (bc *Blockchain) InitVerificationVM(v *vm.VM, getContract func(util.Uint160) (*state.Contract, error), hash util.Uint160, witness *transaction.Witness) error {
// InitVerificationContext initializes context for witness check.
func (bc *Blockchain) InitVerificationContext(ic *interop.Context, hash util.Uint160, witness *transaction.Witness) error {
if len(witness.VerificationScript) != 0 {
if witness.ScriptHash() != hash {
return ErrWitnessHashMismatch
@ -2173,9 +2173,9 @@ func (bc *Blockchain) InitVerificationVM(v *vm.VM, getContract func(util.Uint160
if err != nil {
return fmt.Errorf("%w: %v", ErrInvalidVerification, err)
}
v.LoadScriptWithHash(witness.VerificationScript, hash, callflag.ReadOnly)
ic.VM.LoadScriptWithHash(witness.VerificationScript, hash, callflag.ReadOnly)
} else {
cs, err := getContract(hash)
cs, err := ic.GetContract(hash)
if err != nil {
return ErrUnknownVerificationContract
}
@ -2189,7 +2189,8 @@ func (bc *Blockchain) InitVerificationVM(v *vm.VM, getContract func(util.Uint160
if md != nil {
initOffset = md.Offset
}
v.LoadNEFMethod(&cs.NEF, util.Uint160{}, hash, callflag.ReadOnly,
ic.Invocations[cs.Hash]++
ic.VM.LoadNEFMethod(&cs.NEF, util.Uint160{}, hash, callflag.ReadOnly,
true, verifyOffset, initOffset)
}
if len(witness.InvocationScript) != 0 {
@ -2197,7 +2198,7 @@ func (bc *Blockchain) InitVerificationVM(v *vm.VM, getContract func(util.Uint160
if err != nil {
return fmt.Errorf("%w: %v", ErrInvalidInvocation, err)
}
v.LoadScript(witness.InvocationScript)
ic.VM.LoadScript(witness.InvocationScript)
}
return nil
}
@ -2221,7 +2222,7 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
vm.SetPriceGetter(interopCtx.GetPrice)
vm.LoadToken = contract.LoadToken(interopCtx)
vm.GasLimit = gas
if err := bc.InitVerificationVM(vm, interopCtx.GetContract, hash, witness); err != nil {
if err := bc.InitVerificationContext(interopCtx, hash, witness); err != nil {
return 0, err
}
err := interopCtx.Exec()

View file

@ -15,7 +15,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result/subscriptions"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm"
)
// Blockchainer is an interface that abstract the implementation
@ -26,7 +25,7 @@ type Blockchainer interface {
Blockqueuer // Blockqueuer interface
CalculateClaimable(h util.Uint160, endHeight uint32) (*big.Int, error)
Close()
InitVerificationVM(v *vm.VM, getContract func(util.Uint160) (*state.Contract, error), hash util.Uint160, witness *transaction.Witness) error
InitVerificationContext(ic *interop.Context, hash util.Uint160, witness *transaction.Witness) error
IsTxStillRelevant(t *transaction.Transaction, txpool *mempool.Pool, isPartialTx bool) bool
HeaderHeight() uint32
GetBlock(hash util.Uint256) (*block.Block, error)

View file

@ -1703,13 +1703,7 @@ func (s *Server) runScriptInVM(t trigger.Type, script []byte, contractScriptHash
ic.VM.GasLimit = gasPolicy
}
err := s.chain.InitVerificationVM(ic.VM, func(h util.Uint160) (*state.Contract, error) {
res := s.chain.GetContractState(h)
if res == nil {
return nil, fmt.Errorf("unknown contract: %s", h.StringBE())
}
return res, nil
}, contractScriptHash, &transaction.Witness{InvocationScript: script, VerificationScript: []byte{}})
err := s.chain.InitVerificationContext(ic, contractScriptHash, &transaction.Witness{InvocationScript: script, VerificationScript: []byte{}})
if err != nil {
return nil, response.NewInternalServerError("can't prepare verification VM", err)
}