Merge pull request #1604 from nspcc-dev/fix/deploy

cli/smartcontract: return error if deploy script failed to run
This commit is contained in:
Roman Khimov 2020-12-10 15:38:33 +03:00 committed by GitHub
commit 189d0d801a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 6 deletions

View file

@ -10,6 +10,7 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result" "github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
@ -71,6 +72,35 @@ func TestContractInitAndCompile(t *testing.T) {
}) })
} }
// Checks that error is returned if GAS available for test-invoke exceeds
// GAS needed to be consumed.
func TestDeployBigContract(t *testing.T) {
e := newExecutorWithConfig(t, true, func(c *config.Config) {
c.ApplicationConfiguration.RPC.MaxGasInvoke = fixedn.Fixed8(1)
})
defer e.Close(t)
// For proper nef generation.
config.Version = "0.90.0-test"
tmpDir := path.Join(os.TempDir(), "neogo.test.deployfail")
require.NoError(t, os.Mkdir(tmpDir, os.ModePerm))
defer os.RemoveAll(tmpDir)
nefName := path.Join(tmpDir, "deploy.nef")
manifestName := path.Join(tmpDir, "deploy.manifest.json")
e.Run(t, "neo-go", "contract", "compile",
"--in", "testdata/deploy/main.go", // compile single file
"--config", "testdata/deploy/neo-go.yml",
"--out", nefName, "--manifest", manifestName)
e.In.WriteString("one\r")
e.RunWithError(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--in", nefName, "--manifest", manifestName)
}
func TestComlileAndInvokeFunction(t *testing.T) { func TestComlileAndInvokeFunction(t *testing.T) {
e := newExecutor(t, true) e := newExecutor(t, true)
defer e.Close(t) defer e.Close(t)

View file

@ -61,10 +61,13 @@ type executor struct {
In *bytes.Buffer In *bytes.Buffer
} }
func newTestChain(t *testing.T) (*core.Blockchain, *server.Server, *network.Server) { func newTestChain(t *testing.T, f func(*config.Config)) (*core.Blockchain, *server.Server, *network.Server) {
configPath := "../config/protocol.unit_testnet.single.yml" configPath := "../config/protocol.unit_testnet.single.yml"
cfg, err := config.LoadFile(configPath) cfg, err := config.LoadFile(configPath)
require.NoError(t, err, "could not load config") require.NoError(t, err, "could not load config")
if f != nil {
f(&cfg)
}
memoryStore := storage.NewMemoryStore() memoryStore := storage.NewMemoryStore()
logger := zaptest.NewLogger(t) logger := zaptest.NewLogger(t)
@ -85,6 +88,10 @@ func newTestChain(t *testing.T) (*core.Blockchain, *server.Server, *network.Serv
} }
func newExecutor(t *testing.T, needChain bool) *executor { func newExecutor(t *testing.T, needChain bool) *executor {
return newExecutorWithConfig(t, needChain, nil)
}
func newExecutorWithConfig(t *testing.T, needChain bool, f func(*config.Config)) *executor {
e := &executor{ e := &executor{
CLI: newApp(), CLI: newApp(),
Out: bytes.NewBuffer(nil), Out: bytes.NewBuffer(nil),
@ -97,7 +104,7 @@ func newExecutor(t *testing.T, needChain bool) *executor {
require.Nil(t, input.Terminal) // check that tests clean up properly require.Nil(t, input.Terminal) // check that tests clean up properly
input.Terminal = terminal.NewTerminal(rw, "") input.Terminal = terminal.NewTerminal(rw, "")
if needChain { if needChain {
e.Chain, e.RPC, e.NetSrv = newTestChain(t) e.Chain, e.RPC, e.NetSrv = newTestChain(t, f)
} }
return e return e
} }

View file

@ -773,6 +773,9 @@ func contractDeploy(ctx *cli.Context) error {
} }
// It doesn't require any signers. // It doesn't require any signers.
invRes, err := c.InvokeScript(txScript, nil) invRes, err := c.InvokeScript(txScript, nil)
if err == nil && invRes.FaultException != "" {
err = errors.New(invRes.FaultException)
}
if err != nil { if err != nil {
return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %w", err), 1) return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %w", err), 1)
} }

View file

@ -26,7 +26,7 @@ type Invoke struct {
type invokeAux struct { type invokeAux struct {
State string `json:"state"` State string `json:"state"`
GasConsumed fixedn.Fixed8 `json:"gasconsumed,string"` GasConsumed fixedn.Fixed8 `json:"gasconsumed"`
Script []byte `json:"script"` Script []byte `json:"script"`
Stack json.RawMessage `json:"stack"` Stack json.RawMessage `json:"stack"`
FaultException string `json:"exception,omitempty"` FaultException string `json:"exception,omitempty"`

View file

@ -6,7 +6,6 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -14,7 +13,7 @@ import (
func TestInvoke_MarshalJSON(t *testing.T) { func TestInvoke_MarshalJSON(t *testing.T) {
result := &Invoke{ result := &Invoke{
State: "HALT", State: "HALT",
GasConsumed: int64(fixedn.Fixed8FromFloat(123.45)), GasConsumed: 237626000,
Script: []byte{10}, Script: []byte{10},
Stack: []stackitem.Item{stackitem.NewBigInteger(big.NewInt(1))}, Stack: []stackitem.Item{stackitem.NewBigInteger(big.NewInt(1))},
FaultException: "", FaultException: "",
@ -26,7 +25,7 @@ func TestInvoke_MarshalJSON(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
expected := `{ expected := `{
"state":"HALT", "state":"HALT",
"gasconsumed":"123.45", "gasconsumed":"2.37626",
"script":"` + base64.StdEncoding.EncodeToString(result.Script) + `", "script":"` + base64.StdEncoding.EncodeToString(result.Script) + `",
"stack":[ "stack":[
{"type":"Integer","value":"1"} {"type":"Integer","value":"1"}