From f58d424c6d50d7641eb092b9497e8232d23b8b12 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Mon, 22 Nov 2021 12:44:42 +0300 Subject: [PATCH 1/2] rpc/client: fix custom* scope processing in CreateTxFromScript Copying just the scope doesn't work for CustomContracts, CustomGroups and Rules because they all contain additional metadata. Thanks @mialbu for reporting this. --- pkg/rpc/client/rpc.go | 2 +- pkg/rpc/server/client_test.go | 40 +++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index fbf26ca4d..2f43dd8e4 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -714,7 +714,7 @@ func getSigners(sender *wallet.Account, cosigners []SignerAccount) ([]transactio } for _, c := range cosigners { if c.Signer.Account == from { - s.Scopes = c.Signer.Scopes + s = c.Signer continue } signers = append(signers, c.Signer) diff --git a/pkg/rpc/server/client_test.go b/pkg/rpc/server/client_test.go index cd3b3a291..e24647cfe 100644 --- a/pkg/rpc/server/client_test.go +++ b/pkg/rpc/server/client_test.go @@ -710,13 +710,39 @@ func TestCreateNEP17TransferTx(t *testing.T) { gasContractHash, err := c.GetNativeContractHash(nativenames.Gas) require.NoError(t, err) - tx, err := c.CreateNEP17TransferTx(acc, util.Uint160{}, gasContractHash, 1000, 0, nil, nil) - require.NoError(t, err) - require.NoError(t, acc.SignTx(testchain.Network(), tx)) - require.NoError(t, chain.VerifyTx(tx)) - v, _ := chain.GetTestVM(trigger.Application, tx, nil) - v.LoadScriptWithFlags(tx.Script, callflag.All) - require.NoError(t, v.Run()) + t.Run("default scope", func(t *testing.T) { + tx, err := c.CreateNEP17TransferTx(acc, util.Uint160{}, gasContractHash, 1000, 0, nil, nil) + require.NoError(t, err) + require.NoError(t, acc.SignTx(testchain.Network(), tx)) + require.NoError(t, chain.VerifyTx(tx)) + v, _ := chain.GetTestVM(trigger.Application, tx, nil) + v.LoadScriptWithFlags(tx.Script, callflag.All) + require.NoError(t, v.Run()) + }) + t.Run("none scope", func(t *testing.T) { + _, err := c.CreateNEP17TransferTx(acc, util.Uint160{}, gasContractHash, 1000, 0, nil, []client.SignerAccount{{ + Signer: transaction.Signer{ + Account: priv.PublicKey().GetScriptHash(), + Scopes: transaction.None, + }, + }}) + require.Error(t, err) + }) + t.Run("customcontracts scope", func(t *testing.T) { + tx, err := c.CreateNEP17TransferTx(acc, util.Uint160{}, gasContractHash, 1000, 0, nil, []client.SignerAccount{{ + Signer: transaction.Signer{ + Account: priv.PublicKey().GetScriptHash(), + Scopes: transaction.CustomContracts, + AllowedContracts: []util.Uint160{gasContractHash}, + }, + }}) + require.NoError(t, err) + require.NoError(t, acc.SignTx(testchain.Network(), tx)) + require.NoError(t, chain.VerifyTx(tx)) + v, _ := chain.GetTestVM(trigger.Application, tx, nil) + v.LoadScriptWithFlags(tx.Script, callflag.All) + require.NoError(t, v.Run()) + }) } func TestInvokeVerify(t *testing.T) { From e5b5a3b118012efd8656edd54b950753b0d6a4de Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Mon, 22 Nov 2021 12:46:42 +0300 Subject: [PATCH 2/2] cli: add scope check tests for invocations It doesn't trigger the problem fixed in the previous commit because here CreateTxFromScript is used with pre-calculated GAS value from InvokeFunction and thus it's not performing invocation. Still, it's a nice test extension. --- cli/contract_test.go | 12 ++++++++++-- cli/testdata/deploy/main.go | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cli/contract_test.go b/cli/contract_test.go index d43eb8d3e..d8f1865da 100644 --- a/cli/contract_test.go +++ b/cli/contract_test.go @@ -466,9 +466,17 @@ func TestComlileAndInvokeFunction(t *testing.T) { }) t.Run("with cosigner", func(t *testing.T) { - t.Run("cosigner is sender", func(t *testing.T) { + t.Run("cosigner is sender (none)", func(t *testing.T) { e.In.WriteString("one\r") - e.Run(t, append(cmd, hVerify.StringLE(), "verify", "--", validatorAddr+":Global")...) + e.RunWithError(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":None")...) + }) + t.Run("cosigner is sender (customcontract)", func(t *testing.T) { + e.In.WriteString("one\r") + e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":CustomContracts:"+h.StringLE())...) + }) + t.Run("cosigner is sender (global)", func(t *testing.T) { + e.In.WriteString("one\r") + e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":Global")...) }) acc, err := wallet.NewAccount() diff --git a/cli/testdata/deploy/main.go b/cli/testdata/deploy/main.go index 88a3d0f67..cd62988b6 100644 --- a/cli/testdata/deploy/main.go +++ b/cli/testdata/deploy/main.go @@ -40,6 +40,14 @@ func Fail() { panic("as expected") } +// CheckSenderWitness checks sender's witness. +func CheckSenderWitness() { + tx := runtime.GetScriptContainer() + if !runtime.CheckWitness(tx.Sender) { + panic("not witnessed") + } +} + // Update updates contract with the new one. func Update(script, manifest []byte) { ctx := storage.GetReadOnlyContext()