rpc, cli: encode script in base64 for Invoke*

This commit is contained in:
Anna Shaleva 2020-10-14 16:46:06 +03:00
parent d58c50fb77
commit c50f3db6ad
6 changed files with 38 additions and 33 deletions

View file

@ -500,11 +500,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
fmt.Fprintln(ctx.App.Writer, errText+". Sending transaction...")
}
if out := ctx.String("out"); out != "" {
script, err := hex.DecodeString(resp.Script)
if err != nil {
return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %w", err), 1)
}
tx, err := c.CreateTxFromScript(script, acc, resp.GasConsumed, int64(gas), cosigners...)
tx, err := c.CreateTxFromScript(resp.Script, acc, resp.GasConsumed, int64(gas), cosigners...)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create tx: %w", err), 1)
}
@ -518,11 +514,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
if len(resp.Script) == 0 {
return cli.NewExitError(errors.New("no script returned from the RPC node"), 1)
}
script, err := hex.DecodeString(resp.Script)
if err != nil {
return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %w", err), 1)
}
txHash, err := c.SignAndPushInvocationTx(script, acc, resp.GasConsumed, gas, cosigners)
txHash, err := c.SignAndPushInvocationTx(resp.Script, acc, resp.GasConsumed, gas, cosigners)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1)
}

View file

@ -381,7 +381,7 @@ func (c *Client) GetVersion() (*result.Version, error) {
// InvokeScript returns the result of the given script after running it true the VM.
// NOTE: This is a test invoke and will not affect the blockchain.
func (c *Client) InvokeScript(script []byte, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(hex.EncodeToString(script))
var p = request.NewRawParams(script)
return c.invokeSomething("invokescript", p, signers)
}

View file

@ -347,7 +347,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
invoke: func(c *Client) (interface{}, error) {
return c.GetFeePerByte()
},
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"10c00c0d676574466565506572427974650c149a61a46eec97b89306d7ce81f15b462091d0093241627d5b52","stack":[{"type":"Integer","value":"1000"}],"tx":null}}`,
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"EMAMDWdldEZlZVBlckJ5dGUMFJphpG7sl7iTBtfOgfFbRiCR0AkyQWJ9W1I=","stack":[{"type":"Integer","value":"1000"}],"tx":null}}`,
result: func(c *Client) interface{} {
return int64(1000)
},
@ -359,7 +359,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
invoke: func(c *Client) (interface{}, error) {
return c.GetMaxTransactionsPerBlock()
},
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"10c00c1a6765744d61785472616e73616374696f6e73506572426c6f636b0c149a61a46eec97b89306d7ce81f15b462091d0093241627d5b52","stack":[{"type":"Integer","value":"512"}],"tx":null}}`,
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"EMAMGmdldE1heFRyYW5zYWN0aW9uc1BlckJsb2NrDBSaYaRu7Je4kwbXzoHxW0YgkdAJMkFifVtS","stack":[{"type":"Integer","value":"512"}],"tx":null}}`,
result: func(c *Client) interface{} {
return int64(512)
},
@ -371,7 +371,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
invoke: func(c *Client) (interface{}, error) {
return c.GetMaxBlockSize()
},
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"10c00c0f6765744d6178426c6f636b53697a650c149a61a46eec97b89306d7ce81f15b462091d0093241627d5b52","stack":[{"type":"Integer","value":"262144"}],"tx":null}}`,
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"EMAMD2dldE1heEJsb2NrU2l6ZQwUmmGkbuyXuJMG186B8VtGIJHQCTJBYn1bUg==","stack":[{"type":"Integer","value":"262144"}],"tx":null}}`,
result: func(c *Client) interface{} {
return int64(262144)
},
@ -383,7 +383,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
invoke: func(c *Client) (interface{}, error) {
return c.GetBlockedAccounts()
},
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"10c00c12676574426c6f636b65644163636f756e74730c149a61a46eec97b89306d7ce81f15b462091d0093241627d5b52","stack":[{"type":"Array","value":[]}],"tx":null}}`,
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"EMAMEmdldEJsb2NrZWRBY2NvdW50cwwUmmGkbuyXuJMG186B8VtGIJHQCTJBYn1bUg==","stack":[{"type":"Array","value":[]}],"tx":null}}`,
result: func(c *Client) interface{} {
return native.BlockedAccounts{}
},
@ -663,7 +663,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
Account: util.Uint160{1, 2, 3},
}})
},
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"01e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b5238","state":"HALT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"000800000080969800000000000204130000000000b004000001aa8acf859d4fe402b34e673f2156821796a488eb01005701e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b523801420c40d83408774d4bd8b19ae870561d06f2744eb7678f58d1b90cf2f50e98ae83f60b0824e2feeadef6de6418a4cfc43bbc1f916c33ec594cbe662a9d924786e17a14290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78"}}`,
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv","state":"HALT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"000800000080969800000000000204130000000000b004000001aa8acf859d4fe402b34e673f2156821796a488eb01005701e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b523801420c40d83408774d4bd8b19ae870561d06f2744eb7678f58d1b90cf2f50e98ae83f60b0824e2feeadef6de6418a4cfc43bbc1f916c33ec594cbe662a9d924786e17a14290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78"}}`,
result: func(c *Client) interface{} {
return &result.Invoke{}
},
@ -674,9 +674,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
if err != nil {
panic(err)
}
script, err := base64.StdEncoding.DecodeString("FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv")
if err != nil {
panic(err)
}
assert.Equal(t, "HALT", res.State)
assert.Equal(t, int64(31100000), res.GasConsumed)
assert.Equal(t, "01e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b5238", res.Script)
assert.Equal(t, script, res.Script)
assert.Equal(t, []stackitem.Item{stackitem.NewByteArray(bytes)}, res.Stack)
assert.NotNil(t, res.Transaction)
},
@ -701,7 +705,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
Account: util.Uint160{1, 2, 3},
}})
},
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"1426ae7c6c9861ec418468c1f0fdc4a7f2963eb89151c10962616c616e63654f6667be39e7b562f60cbfe2aebca375a2e5ee28737caf","state":"FAULT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"000800000080969800000000000204130000000000b004000001aa8acf859d4fe402b34e673f2156821796a488eb01005701e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b523801420c40d83408774d4bd8b19ae870561d06f2744eb7678f58d1b90cf2f50e98ae83f60b0824e2feeadef6de6418a4cfc43bbc1f916c33ec594cbe662a9d924786e17a14290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78","exception":"gas limit exceeded"}}`,
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv","state":"FAULT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"000800000080969800000000000204130000000000b004000001aa8acf859d4fe402b34e673f2156821796a488eb01005701e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b523801420c40d83408774d4bd8b19ae870561d06f2744eb7678f58d1b90cf2f50e98ae83f60b0824e2feeadef6de6418a4cfc43bbc1f916c33ec594cbe662a9d924786e17a14290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78","exception":"gas limit exceeded"}}`,
result: func(c *Client) interface{} {
return &result.Invoke{}
},
@ -712,9 +716,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
if err != nil {
panic(err)
}
script, err := base64.StdEncoding.DecodeString("FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv")
if err != nil {
panic(err)
}
assert.Equal(t, "FAULT", res.State)
assert.Equal(t, int64(31100000), res.GasConsumed)
assert.Equal(t, "1426ae7c6c9861ec418468c1f0fdc4a7f2963eb89151c10962616c616e63654f6667be39e7b562f60cbfe2aebca375a2e5ee28737caf", res.Script)
assert.Equal(t, script, res.Script)
assert.Equal(t, []stackitem.Item{stackitem.NewByteArray(bytes)}, res.Stack)
assert.NotNil(t, res.Transaction)
},
@ -724,7 +732,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
{
name: "positive",
invoke: func(c *Client) (interface{}, error) {
script, err := hex.DecodeString("00046e616d656724058e5e1b6008847cd662728549088a9ee82191")
script, err := base64.StdEncoding.DecodeString("AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR")
if err != nil {
panic(err)
}
@ -732,16 +740,20 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
Account: util.Uint160{1, 2, 3},
}})
},
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"00046e616d656724058e5e1b6008847cd662728549088a9ee82191","state":"HALT","gasconsumed":"16100000","stack":[{"type":"ByteString","value":"TkVQNSBHQVM="}],"tx":null}}`,
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR","state":"HALT","gasconsumed":"16100000","stack":[{"type":"ByteString","value":"TkVQNSBHQVM="}],"tx":null}}`,
result: func(c *Client) interface{} {
bytes, err := hex.DecodeString("4e45503520474153")
if err != nil {
panic(err)
}
script, err := base64.StdEncoding.DecodeString("AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR")
if err != nil {
panic(err)
}
return &result.Invoke{
State: "HALT",
GasConsumed: 16100000,
Script: "00046e616d656724058e5e1b6008847cd662728549088a9ee82191",
Script: script,
Stack: []stackitem.Item{stackitem.NewByteArray(bytes)},
}
},

View file

@ -18,7 +18,7 @@ import (
type Invoke struct {
State string
GasConsumed int64
Script string
Script []byte
Stack []stackitem.Item
FaultException string
// Transaction represents transaction bytes. Use GetTransaction method to decode it.
@ -28,7 +28,7 @@ type Invoke struct {
type invokeAux struct {
State string `json:"state"`
GasConsumed int64 `json:"gasconsumed,string"`
Script string `json:"script"`
Script []byte `json:"script"`
Stack json.RawMessage `json:"stack"`
FaultException string `json:"exception,omitempty"`
Transaction string `json:"tx,omitempty"`

View file

@ -977,7 +977,7 @@ func (s *Server) invokescript(reqParams request.Params) (interface{}, *response.
return nil, response.ErrInvalidParams
}
script, err := reqParams[0].GetBytesHex()
script, err := reqParams[0].GetBytesBase64()
if err != nil {
return nil, response.ErrInvalidParams
}
@ -1011,7 +1011,7 @@ func (s *Server) runScriptInVM(script []byte, tx *transaction.Transaction) *resu
result := &result.Invoke{
State: vm.State().String(),
GasConsumed: vm.GasConsumed(),
Script: hex.EncodeToString(script),
Script: script,
Stack: vm.Estack().ToArray(),
FaultException: faultException,
}

View file

@ -60,6 +60,7 @@ const deploymentTxHash = "59f7b22b90e26f883a56b916c1580e3ee4f13caded686353cd7757
const verifyContractHash = "c1213693b22cb0454a436d6e0bd76b8c0a3bfdf7"
const verifyContractAVM = "570300412d51083021700c14aa8acf859d4fe402b34e673f2156821796a488ebdb30716813cedb2869db289740"
const testVerifyContractAVM = "VwcADBQBDAMOBQYMDQIODw0DDgcJAAAAANswcGgRVUH4J+yMIaonBwAAABFADBQNDwMCCQACAQMHAwQFAgEADgYMCdswcWkRVUH4J+yMIaonBwAAABJAE0A="
var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": {
@ -537,7 +538,7 @@ var rpcTestCases = map[string][]rpcTestCase{
check: func(t *testing.T, e *executor, inv interface{}) {
res, ok := inv.(*result.Invoke)
require.True(t, ok)
assert.NotEqual(t, "", res.Script)
assert.NotNil(t, res.Script)
assert.NotEqual(t, "", res.State)
assert.NotEqual(t, 0, res.GasConsumed)
},
@ -566,7 +567,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"invokescript": {
{
name: "positive",
params: `["51c56b0d48656c6c6f2c20776f726c6421680f4e656f2e52756e74696d652e4c6f67616c7566"]`,
params: `["UcVrDUhlbGxvLCB3b3JsZCFoD05lby5SdW50aW1lLkxvZ2FsdWY="]`,
result: func(e *executor) interface{} { return &result.Invoke{} },
check: func(t *testing.T, e *executor, inv interface{}) {
res, ok := inv.(*result.Invoke)
@ -578,8 +579,8 @@ var rpcTestCases = map[string][]rpcTestCase{
},
{
name: "positive, good witness",
// script is hex-encoded `test_verify.avm` representation, hashes are hex-encoded LE bytes of hashes used in the contract with `0x` prefix
params: `["5707000c14010c030e05060c0d020e0f0d030e070900000000db307068115541f827ec8c21aa270700000011400c140d0f03020900020103070304050201000e060c09db307169115541f827ec8c21aa270700000012401340",["0x0000000009070e030d0f0e020d0c06050e030c01","0x090c060e00010205040307030102000902030f0d"]]`,
// script is base64-encoded `test_verify.avm` representation, hashes are hex-encoded LE bytes of hashes used in the contract with `0x` prefix
params: fmt.Sprintf(`["%s",["0x0000000009070e030d0f0e020d0c06050e030c01","0x090c060e00010205040307030102000902030f0d"]]`, testVerifyContractAVM),
result: func(e *executor) interface{} { return &result.Invoke{} },
check: func(t *testing.T, e *executor, inv interface{}) {
res, ok := inv.(*result.Invoke)
@ -591,7 +592,7 @@ var rpcTestCases = map[string][]rpcTestCase{
},
{
name: "positive, bad witness of second hash",
params: `["5707000c14010c030e05060c0d020e0f0d030e070900000000db307068115541f827ec8c21aa270700000011400c140d0f03020900020103070304050201000e060c09db307169115541f827ec8c21aa270700000012401340",["0x0000000009070e030d0f0e020d0c06050e030c01"]]`,
params: fmt.Sprintf(`["%s",["0x0000000009070e030d0f0e020d0c06050e030c01"]]`, testVerifyContractAVM),
result: func(e *executor) interface{} { return &result.Invoke{} },
check: func(t *testing.T, e *executor, inv interface{}) {
res, ok := inv.(*result.Invoke)
@ -603,7 +604,7 @@ var rpcTestCases = map[string][]rpcTestCase{
},
{
name: "positive, no good hashes",
params: `["5707000c14010c030e05060c0d020e0f0d030e070900000000db307068115541f827ec8c21aa270700000011400c140d0f03020900020103070304050201000e060c09db307169115541f827ec8c21aa270700000012401340"]`,
params: fmt.Sprintf(`["%s"]`, testVerifyContractAVM),
result: func(e *executor) interface{} { return &result.Invoke{} },
check: func(t *testing.T, e *executor, inv interface{}) {
res, ok := inv.(*result.Invoke)
@ -615,7 +616,7 @@ var rpcTestCases = map[string][]rpcTestCase{
},
{
name: "positive, bad hashes witness",
params: `["5707000c14010c030e05060c0d020e0f0d030e070900000000db307068115541f827ec8c21aa270700000011400c140d0f03020900020103070304050201000e060c09db307169115541f827ec8c21aa270700000012401340",["0x0000000009070e030d0f0e020d0c06050e030c02"]]`,
params: fmt.Sprintf(`["%s",["0x0000000009070e030d0f0e020d0c06050e030c02"]]`, testVerifyContractAVM),
result: func(e *executor) interface{} { return &result.Invoke{} },
check: func(t *testing.T, e *executor, inv interface{}) {
res, ok := inv.(*result.Invoke)