Merge pull request #1604 from nspcc-dev/fix/deploy
cli/smartcontract: return error if deploy script failed to run
This commit is contained in:
commit
189d0d801a
5 changed files with 45 additions and 6 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"`
|
||||||
|
|
|
@ -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"}
|
||||||
|
|
Loading…
Reference in a new issue