interop: add CallWithVersion helper

This commit is contained in:
Anna Shaleva 2022-09-16 21:08:05 +03:00
parent df802b6fc6
commit ea08a81726
2 changed files with 52 additions and 0 deletions

View file

@ -13,6 +13,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
@ -519,3 +520,31 @@ func TestCallTConversionErrors(t *testing.T) {
require.Error(t, err)
})
}
func TestCallWithVersion(t *testing.T) {
bc, acc := chain.NewSingle(t)
e := neotest.NewExecutor(t, bc, acc, acc)
src := `package foo
import (
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
util "github.com/nspcc-dev/neo-go/pkg/interop/lib/contract"
)
func CallWithVersion(hash interop.Hash160, version int, method string) interface{} {
return util.CallWithVersion(hash, version, method, contract.All)
}`
ctr := neotest.CompileSource(t, e.CommitteeHash, strings.NewReader(src), &compiler.Options{Name: "Helper"})
e.DeployContract(t, ctr, nil)
c := e.CommitteeInvoker(ctr.Hash)
policyH := state.CreateNativeContractHash(nativenames.Policy)
t.Run("good", func(t *testing.T) {
c.Invoke(t, e.Chain.GetBaseExecFee(), "callWithVersion", policyH.BytesBE(), 0, "getExecFeeFactor")
})
t.Run("unknown contract", func(t *testing.T) {
c.InvokeFail(t, "unknown contract", "callWithVersion", util.Uint160{1, 2, 3}.BytesBE(), 0, "getExecFeeFactor")
})
t.Run("invalid version", func(t *testing.T) {
c.InvokeFail(t, "contract version mismatch", "callWithVersion", policyH.BytesBE(), 1, "getExecFeeFactor")
})
}

View file

@ -0,0 +1,23 @@
package contract
import (
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
"github.com/nspcc-dev/neo-go/pkg/interop/native/management"
)
// CallWithVersion is a utility function that executes the previously deployed
// blockchain contract with the specified version (update counter) and hash
// (20 bytes in BE form) using the provided arguments and call flags. It fails
// if the contract has version mismatch. It returns whatever this contract
// returns. This function uses `System.Contract.Call` syscall.
func CallWithVersion(scriptHash interop.Hash160, version int, method string, f contract.CallFlag, args ...interface{}) interface{} {
cs := management.GetContract(scriptHash)
if cs == nil {
panic("unknown contract")
}
if cs.UpdateCounter != version {
panic("contract version mismatch")
}
return contract.Call(scriptHash, method, f, args...)
}