From a0b73150c6ae2fe4b108d9e2b434904f4a66e5b3 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 8 Dec 2023 11:10:00 +0300 Subject: [PATCH] Revert "[#53] proxy: Allow using proxy by trusted accounts" This reverts commit bc3186575ff47b75a811a78ddef3b10869f2d4e2. --- proxy/proxy_contract.go | 40 ++++--------------- rpcclient/proxy/client.go | 48 +---------------------- tests/proxy_test.go | 82 +++------------------------------------ 3 files changed, 15 insertions(+), 155 deletions(-) diff --git a/proxy/proxy_contract.go b/proxy/proxy_contract.go index be59473..7157062 100644 --- a/proxy/proxy_contract.go +++ b/proxy/proxy_contract.go @@ -5,13 +5,10 @@ import ( "github.com/nspcc-dev/neo-go/pkg/interop" "github.com/nspcc-dev/neo-go/pkg/interop/native/gas" "github.com/nspcc-dev/neo-go/pkg/interop/native/management" + "github.com/nspcc-dev/neo-go/pkg/interop/native/neo" "github.com/nspcc-dev/neo-go/pkg/interop/runtime" - "github.com/nspcc-dev/neo-go/pkg/interop/storage" - "github.com/nspcc-dev/neo-go/pkg/interop/util" ) -const accountKeyPrefix = 'a' - // OnNEP17Payment is a callback for NEP-17 compatible native GAS contract. func OnNEP17Payment(from interop.Hash160, amount int, data any) { caller := runtime.GetCallingScriptHash() @@ -43,40 +40,19 @@ func Update(script []byte, manifest []byte, data any) { // Verify method returns true if transaction contains valid multisignature of // Alphabet nodes of the Inner Ring. -func Verify(addr interop.Hash160) bool { - common.CheckWitness(addr) +func Verify() bool { + alphabet := neo.GetCommittee() + sig := common.Multiaddress(alphabet, false) - ctx := storage.GetReadOnlyContext() - if storage.Get(ctx, append([]byte{accountKeyPrefix}, addr...)) != nil { - return true + if !runtime.CheckWitness(sig) { + sig = common.Multiaddress(alphabet, true) + return runtime.CheckWitness(sig) } - if util.Equals(addr, common.CommitteeAddress()) { - return true - } - - if util.Equals(addr, common.AlphabetAddress()) { - return true - } - - return false + return true } // Version returns the version of the contract. func Version() int { return common.Version } - -func AddAccount(addr interop.Hash160) { - common.CheckWitness(common.CommitteeAddress()) - - ctx := storage.GetContext() - storage.Put(ctx, append([]byte{accountKeyPrefix}, addr...), []byte{1}) -} - -func RemoveAccount(addr interop.Hash160) { - common.CheckWitness(common.CommitteeAddress()) - - ctx := storage.GetContext() - storage.Delete(ctx, append([]byte{accountKeyPrefix}, addr...)) -} diff --git a/rpcclient/proxy/client.go b/rpcclient/proxy/client.go index 7481ff9..10acfda 100644 --- a/rpcclient/proxy/client.go +++ b/rpcclient/proxy/client.go @@ -52,8 +52,8 @@ func New(actor Actor, hash util.Uint160) *Contract { } // Verify invokes `verify` method of contract. -func (c *ContractReader) Verify(addr util.Uint160) (bool, error) { - return unwrap.Bool(c.invoker.Call(c.hash, "verify", addr)) +func (c *ContractReader) Verify() (bool, error) { + return unwrap.Bool(c.invoker.Call(c.hash, "verify")) } // Version invokes `version` method of contract. @@ -61,50 +61,6 @@ func (c *ContractReader) Version() (*big.Int, error) { return unwrap.BigInt(c.invoker.Call(c.hash, "version")) } -// AddAccount creates a transaction invoking `addAccount` method of the contract. -// This transaction is signed and immediately sent to the network. -// The values returned are its hash, ValidUntilBlock value and error if any. -func (c *Contract) AddAccount(addr util.Uint160) (util.Uint256, uint32, error) { - return c.actor.SendCall(c.hash, "addAccount", addr) -} - -// AddAccountTransaction creates a transaction invoking `addAccount` method of the contract. -// This transaction is signed, but not sent to the network, instead it's -// returned to the caller. -func (c *Contract) AddAccountTransaction(addr util.Uint160) (*transaction.Transaction, error) { - return c.actor.MakeCall(c.hash, "addAccount", addr) -} - -// AddAccountUnsigned creates a transaction invoking `addAccount` method of the contract. -// This transaction is not signed, it's simply returned to the caller. -// Any fields of it that do not affect fees can be changed (ValidUntilBlock, -// Nonce), fee values (NetworkFee, SystemFee) can be increased as well. -func (c *Contract) AddAccountUnsigned(addr util.Uint160) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(c.hash, "addAccount", nil, addr) -} - -// RemoveAccount creates a transaction invoking `removeAccount` method of the contract. -// This transaction is signed and immediately sent to the network. -// The values returned are its hash, ValidUntilBlock value and error if any. -func (c *Contract) RemoveAccount(addr util.Uint160) (util.Uint256, uint32, error) { - return c.actor.SendCall(c.hash, "removeAccount", addr) -} - -// RemoveAccountTransaction creates a transaction invoking `removeAccount` method of the contract. -// This transaction is signed, but not sent to the network, instead it's -// returned to the caller. -func (c *Contract) RemoveAccountTransaction(addr util.Uint160) (*transaction.Transaction, error) { - return c.actor.MakeCall(c.hash, "removeAccount", addr) -} - -// RemoveAccountUnsigned creates a transaction invoking `removeAccount` method of the contract. -// This transaction is not signed, it's simply returned to the caller. -// Any fields of it that do not affect fees can be changed (ValidUntilBlock, -// Nonce), fee values (NetworkFee, SystemFee) can be increased as well. -func (c *Contract) RemoveAccountUnsigned(addr util.Uint160) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(c.hash, "removeAccount", nil, addr) -} - // Update creates a transaction invoking `update` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. diff --git a/tests/proxy_test.go b/tests/proxy_test.go index 5b89443..845fb16 100644 --- a/tests/proxy_test.go +++ b/tests/proxy_test.go @@ -1,21 +1,12 @@ package tests import ( - "errors" "path" "testing" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" - "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" - "github.com/nspcc-dev/neo-go/pkg/core/transaction" - "github.com/nspcc-dev/neo-go/pkg/crypto/hash" - "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/neotest" "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neo-go/pkg/vm/emit" - "github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" - "github.com/stretchr/testify/require" ) const proxyPath = "../proxy" @@ -45,76 +36,13 @@ func newProxyInvoker(t *testing.T) *neotest.ContractInvoker { func TestVerify(t *testing.T) { e := newProxyInvoker(t) - acc := e.NewAccount(t) - gas := e.NewInvoker(e.NativeHash(t, nativenames.Gas), e.Validator) - gas.Invoke(t, true, "transfer", e.Validator.ScriptHash(), e.Hash, 100_0000_0000, nil) + const method = "verify" - t.Run("proxy + committee", func(t *testing.T) { - s := &proxySigner{contract: e.Hash, account: e.CommitteeHash} - tx := e.PrepareInvocation(t, []byte{byte(opcode.RET)}, []neotest.Signer{s, e.Committee}) - require.NoError(t, e.Chain.VerifyTx(tx)) - }) - t.Run("proxy + custom account", func(t *testing.T) { - s := &proxySigner{contract: e.Hash, account: acc.ScriptHash()} - t.Run("bad, only proxy", func(t *testing.T) { - tx := e.PrepareInvocation(t, []byte{byte(opcode.RET)}, []neotest.Signer{s, acc}) - require.Error(t, e.Chain.VerifyTx(tx)) - }) + e.Invoke(t, stackitem.NewBool(true), method) - e.Invoke(t, stackitem.Null{}, "addAccount", s.account) + notAlphabet := e.NewAccount(t) + cNotAlphabet := e.WithSigners(notAlphabet) - tx := e.PrepareInvocation(t, []byte{byte(opcode.RET)}, []neotest.Signer{s, acc}) - require.NoError(t, e.Chain.VerifyTx(tx)) - }) -} - -type proxySigner struct { - contract util.Uint160 - account util.Uint160 -} - -var _ neotest.ContractSigner = (*proxySigner)(nil) - -func (s *proxySigner) Script() []byte { - return nil -} -func (s *proxySigner) ScriptHash() util.Uint160 { - return s.contract -} -func (s *proxySigner) SignHashable(uint32, hash.Hashable) []byte { - panic("not implemented") -} -func (s *proxySigner) SignTx(_ netmode.Magic, tx *transaction.Transaction) error { - pos := -1 - for i := range tx.Signers { - if tx.Signers[i].Account.Equals(s.contract) { - pos = i - break - } - } - if pos < 0 { - return errors.New("transaction is not signed by this account") - } - if len(tx.Scripts) < pos { - return errors.New("transaction is not yet signed by the previous signer") - } - - invoc, err := s.InvocationScript(tx) - if err != nil { - return err - } - - w := transaction.Witness{InvocationScript: invoc} - if len(tx.Scripts) == pos { - tx.Scripts = append(tx.Scripts, w) - } else { - tx.Scripts[pos].InvocationScript = invoc - } - return nil -} -func (s *proxySigner) InvocationScript(tx *transaction.Transaction) ([]byte, error) { - w := io.NewBufBinWriter() - emit.Any(w.BinWriter, s.account) - return w.Bytes(), nil + cNotAlphabet.Invoke(t, stackitem.NewBool(false), method) }