diff --git a/cli/contract_test.go b/cli/contract_test.go index 69ac75e21..994216ae7 100644 --- a/cli/contract_test.go +++ b/cli/contract_test.go @@ -10,6 +10,7 @@ import ( "testing" "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/util" "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) { e := newExecutor(t, true) defer e.Close(t) diff --git a/cli/executor_test.go b/cli/executor_test.go index be56c31ec..417e4f73b 100644 --- a/cli/executor_test.go +++ b/cli/executor_test.go @@ -61,10 +61,13 @@ type executor struct { 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" cfg, err := config.LoadFile(configPath) require.NoError(t, err, "could not load config") + if f != nil { + f(&cfg) + } memoryStore := storage.NewMemoryStore() 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 { + return newExecutorWithConfig(t, needChain, nil) +} + +func newExecutorWithConfig(t *testing.T, needChain bool, f func(*config.Config)) *executor { e := &executor{ CLI: newApp(), 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 input.Terminal = terminal.NewTerminal(rw, "") if needChain { - e.Chain, e.RPC, e.NetSrv = newTestChain(t) + e.Chain, e.RPC, e.NetSrv = newTestChain(t, f) } return e } diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index 4f90d9c7c..270a4014b 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -773,6 +773,9 @@ func contractDeploy(ctx *cli.Context) error { } // It doesn't require any signers. invRes, err := c.InvokeScript(txScript, nil) + if err == nil && invRes.FaultException != "" { + err = errors.New(invRes.FaultException) + } if err != nil { return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %w", err), 1) } diff --git a/pkg/rpc/response/result/invoke.go b/pkg/rpc/response/result/invoke.go index 922dcdcad..bfd4c72ea 100644 --- a/pkg/rpc/response/result/invoke.go +++ b/pkg/rpc/response/result/invoke.go @@ -26,7 +26,7 @@ type Invoke struct { type invokeAux struct { State string `json:"state"` - GasConsumed fixedn.Fixed8 `json:"gasconsumed,string"` + GasConsumed fixedn.Fixed8 `json:"gasconsumed"` Script []byte `json:"script"` Stack json.RawMessage `json:"stack"` FaultException string `json:"exception,omitempty"` diff --git a/pkg/rpc/response/result/invoke_test.go b/pkg/rpc/response/result/invoke_test.go index 611831acb..f1975d42b 100644 --- a/pkg/rpc/response/result/invoke_test.go +++ b/pkg/rpc/response/result/invoke_test.go @@ -6,7 +6,6 @@ import ( "math/big" "testing" - "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/stretchr/testify/require" ) @@ -14,7 +13,7 @@ import ( func TestInvoke_MarshalJSON(t *testing.T) { result := &Invoke{ State: "HALT", - GasConsumed: int64(fixedn.Fixed8FromFloat(123.45)), + GasConsumed: 237626000, Script: []byte{10}, Stack: []stackitem.Item{stackitem.NewBigInteger(big.NewInt(1))}, FaultException: "", @@ -26,7 +25,7 @@ func TestInvoke_MarshalJSON(t *testing.T) { require.NoError(t, err) expected := `{ "state":"HALT", - "gasconsumed":"123.45", + "gasconsumed":"2.37626", "script":"` + base64.StdEncoding.EncodeToString(result.Script) + `", "stack":[ {"type":"Integer","value":"1"}