From 3c5a720e3a8423b49f8d24966cc46c84937fc7f8 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 27 Jul 2022 19:00:36 +0300 Subject: [PATCH] smartcontract: drop Params type and TryParse methods They were first introduced in a058598ecc0e82d4caf9f6225606d9ac61fb672e and then carefully moved in 648e0bb242da9daaeef4f1bbbad69367fc26c836, but it looks like they were never used by any external code. This code can be useful on the server, but the server has its own params package to deal with parameters. Clients usually create Parameters and then get results as stackitem.Items, so they don't use this code either. So there is zero point in keeping it. --- pkg/rpcclient/rpc.go | 2 +- pkg/services/rpcsrv/client_test.go | 20 ++--- pkg/smartcontract/parameter.go | 120 ---------------------------- pkg/smartcontract/parameter_test.go | 84 ------------------- 4 files changed, 11 insertions(+), 215 deletions(-) diff --git a/pkg/rpcclient/rpc.go b/pkg/rpcclient/rpc.go index abfed089f..049f46a46 100644 --- a/pkg/rpcclient/rpc.go +++ b/pkg/rpcclient/rpc.go @@ -1047,7 +1047,7 @@ func (c *Client) AddNetworkFee(tx *transaction.Transaction, extraFee int64, accs var ef int64 for i, cosigner := range tx.Signers { if accs[i].Contract.Deployed { - res, err := c.InvokeContractVerify(cosigner.Account, smartcontract.Params{}, tx.Signers) + res, err := c.InvokeContractVerify(cosigner.Account, []smartcontract.Parameter{}, tx.Signers) if err != nil { return fmt.Errorf("failed to invoke verify: %w", err) } diff --git a/pkg/services/rpcsrv/client_test.go b/pkg/services/rpcsrv/client_test.go index 219963faf..4c12cf9d1 100644 --- a/pkg/services/rpcsrv/client_test.go +++ b/pkg/services/rpcsrv/client_test.go @@ -773,7 +773,7 @@ func TestInvokeVerify(t *testing.T) { require.NoError(t, err) t.Run("positive, with signer", func(t *testing.T) { - res, err := c.InvokeContractVerify(contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) + res, err := c.InvokeContractVerify(contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) require.NoError(t, err) require.Equal(t, "HALT", res.State) require.Equal(t, 1, len(res.Stack)) @@ -782,7 +782,7 @@ func TestInvokeVerify(t *testing.T) { t.Run("positive, historic, by height, with signer", func(t *testing.T) { h := chain.BlockHeight() - 1 - res, err := c.InvokeContractVerifyAtHeight(h, contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) + res, err := c.InvokeContractVerifyAtHeight(h, contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) require.NoError(t, err) require.Equal(t, "HALT", res.State) require.Equal(t, 1, len(res.Stack)) @@ -790,7 +790,7 @@ func TestInvokeVerify(t *testing.T) { }) t.Run("positive, historic, by block, with signer", func(t *testing.T) { - res, err := c.InvokeContractVerifyAtBlock(chain.GetHeaderHash(int(chain.BlockHeight())-1), contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) + res, err := c.InvokeContractVerifyAtBlock(chain.GetHeaderHash(int(chain.BlockHeight())-1), contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) require.NoError(t, err) require.Equal(t, "HALT", res.State) require.Equal(t, 1, len(res.Stack)) @@ -801,7 +801,7 @@ func TestInvokeVerify(t *testing.T) { h := chain.BlockHeight() - 1 sr, err := chain.GetStateModule().GetStateRoot(h) require.NoError(t, err) - res, err := c.InvokeContractVerifyWithState(sr.Root, contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) + res, err := c.InvokeContractVerifyWithState(sr.Root, contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) require.NoError(t, err) require.Equal(t, "HALT", res.State) require.Equal(t, 1, len(res.Stack)) @@ -810,13 +810,13 @@ func TestInvokeVerify(t *testing.T) { t.Run("bad, historic, by hash: contract not found", func(t *testing.T) { var h uint32 = 1 - _, err = c.InvokeContractVerifyAtHeight(h, contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) + _, err = c.InvokeContractVerifyAtHeight(h, contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) require.Error(t, err) require.True(t, strings.Contains(err.Error(), core.ErrUnknownVerificationContract.Error())) // contract wasn't deployed at block #1 yet }) t.Run("bad, historic, by block: contract not found", func(t *testing.T) { - _, err = c.InvokeContractVerifyAtBlock(chain.GetHeaderHash(1), contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) + _, err = c.InvokeContractVerifyAtBlock(chain.GetHeaderHash(1), contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) require.Error(t, err) require.True(t, strings.Contains(err.Error(), core.ErrUnknownVerificationContract.Error())) // contract wasn't deployed at block #1 yet }) @@ -825,13 +825,13 @@ func TestInvokeVerify(t *testing.T) { var h uint32 = 1 sr, err := chain.GetStateModule().GetStateRoot(h) require.NoError(t, err) - _, err = c.InvokeContractVerifyWithState(sr.Root, contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) + _, err = c.InvokeContractVerifyWithState(sr.Root, contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) require.Error(t, err) require.True(t, strings.Contains(err.Error(), core.ErrUnknownVerificationContract.Error())) // contract wasn't deployed at block #1 yet }) t.Run("positive, with signer and witness", func(t *testing.T) { - res, err := c.InvokeContractVerify(contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}, transaction.Witness{InvocationScript: []byte{byte(opcode.PUSH1), byte(opcode.RET)}}) + res, err := c.InvokeContractVerify(contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}, transaction.Witness{InvocationScript: []byte{byte(opcode.PUSH1), byte(opcode.RET)}}) require.NoError(t, err) require.Equal(t, "HALT", res.State) require.Equal(t, 1, len(res.Stack)) @@ -839,12 +839,12 @@ func TestInvokeVerify(t *testing.T) { }) t.Run("error, invalid witness number", func(t *testing.T) { - _, err := c.InvokeContractVerify(contract, smartcontract.Params{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}, transaction.Witness{InvocationScript: []byte{byte(opcode.PUSH1), byte(opcode.RET)}}, transaction.Witness{InvocationScript: []byte{byte(opcode.RET)}}) + _, err := c.InvokeContractVerify(contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}, transaction.Witness{InvocationScript: []byte{byte(opcode.PUSH1), byte(opcode.RET)}}, transaction.Witness{InvocationScript: []byte{byte(opcode.RET)}}) require.Error(t, err) }) t.Run("false", func(t *testing.T) { - res, err := c.InvokeContractVerify(contract, smartcontract.Params{}, []transaction.Signer{{Account: util.Uint160{}}}) + res, err := c.InvokeContractVerify(contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: util.Uint160{}}}) require.NoError(t, err) require.Equal(t, "HALT", res.State) require.Equal(t, 1, len(res.Stack)) diff --git a/pkg/smartcontract/parameter.go b/pkg/smartcontract/parameter.go index 97cb04a2c..3cecd259c 100644 --- a/pkg/smartcontract/parameter.go +++ b/pkg/smartcontract/parameter.go @@ -3,19 +3,16 @@ package smartcontract import ( "bytes" "encoding/base64" - "encoding/binary" "encoding/hex" "encoding/json" "errors" "fmt" "math/big" - "math/bits" "os" "strings" "unicode/utf8" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) @@ -194,123 +191,6 @@ func (p *Parameter) UnmarshalJSON(data []byte) (err error) { return } -// Params is an array of Parameter (TODO: drop it?). -type Params []Parameter - -// TryParseArray converts an array of Parameter into an array of more appropriate things. -func (p Params) TryParseArray(vals ...interface{}) error { - var ( - err error - i int - par Parameter - ) - if len(p) != len(vals) { - return errors.New("receiver array doesn't fit the Params length") - } - for i, par = range p { - if err = par.TryParse(vals[i]); err != nil { - return err - } - } - return nil -} - -// TryParse converts one Parameter into something more appropriate. -func (p Parameter) TryParse(dest interface{}) error { - var ( - err error - ok bool - data []byte - ) - switch p.Type { - case ByteArrayType: - if data, ok = p.Value.([]byte); !ok { - return fmt.Errorf("failed to cast %s to []byte", p.Value) - } - switch dest := dest.(type) { - case *util.Uint160: - if *dest, err = util.Uint160DecodeBytesBE(data); err != nil { - return err - } - return nil - case *[]byte: - *dest = data - return nil - case *util.Uint256: - if *dest, err = util.Uint256DecodeBytesLE(data); err != nil { - return err - } - return nil - case **big.Int: - *dest = bigint.FromBytes(data) - return nil - case *int64, *int32, *int16, *int8, *int, *uint64, *uint32, *uint16, *uint8, *uint: - var size int - switch dest.(type) { - case *int64, *uint64: - size = 64 - case *int32, *uint32: - size = 32 - case *int16, *uint16: - size = 16 - case *int8, *uint8: - size = 8 - case *int, *uint: - size = bits.UintSize - } - - i, err := bytesToUint64(data, size) - if err != nil { - return err - } - - switch dest := dest.(type) { - case *int64: - *dest = int64(i) - case *int32: - *dest = int32(i) - case *int16: - *dest = int16(i) - case *int8: - *dest = int8(i) - case *int: - *dest = int(i) - case *uint64: - *dest = i - case *uint32: - *dest = uint32(i) - case *uint16: - *dest = uint16(i) - case *uint8: - *dest = uint8(i) - case *uint: - *dest = uint(i) - } - case *string: - *dest = string(data) - return nil - default: - return fmt.Errorf("cannot cast param of type %s to type %s", p.Type, dest) - } - default: - return errors.New("cannot define param type") - } - return nil -} - -func bytesToUint64(b []byte, size int) (uint64, error) { - var length = size / 8 - if len(b) > length { - return 0, fmt.Errorf("input doesn't fit into %d bits", size) - } - if len(b) < length { - data := make([]byte, length) - copy(data, b) - return binary.LittleEndian.Uint64(data), nil - } - return binary.LittleEndian.Uint64(b), nil -} - // NewParameterFromString returns a new Parameter initialized from the given // string in neo-go-specific format. It is intended to be used in user-facing // interfaces and has some heuristics in it to simplify parameter passing. The exact diff --git a/pkg/smartcontract/parameter_test.go b/pkg/smartcontract/parameter_test.go index e52cc67a1..51b5931c4 100644 --- a/pkg/smartcontract/parameter_test.go +++ b/pkg/smartcontract/parameter_test.go @@ -6,7 +6,6 @@ import ( "encoding/json" "math" "math/big" - "reflect" "strings" "testing" @@ -341,89 +340,6 @@ func TestParam_UnmarshalJSON(t *testing.T) { } } -var tryParseTestCases = []struct { - input interface{} - expected interface{} -}{ - { - input: []byte{ - 0x0b, 0xcd, 0x29, 0x78, 0x63, 0x4d, 0x96, 0x1c, 0x24, 0xf5, - 0xae, 0xa0, 0x80, 0x22, 0x97, 0xff, 0x12, 0x87, 0x24, 0xd6, - }, - expected: util.Uint160{ - 0x0b, 0xcd, 0x29, 0x78, 0x63, 0x4d, 0x96, 0x1c, 0x24, 0xf5, - 0xae, 0xa0, 0x80, 0x22, 0x97, 0xff, 0x12, 0x87, 0x24, 0xd6, - }, - }, - { - input: []byte{ - 0xf0, 0x37, 0x30, 0x8f, 0xa0, 0xab, 0x18, 0x15, - 0x5b, 0xcc, 0xfc, 0x08, 0x48, 0x54, 0x68, 0xc1, - 0x12, 0x40, 0x9e, 0xa5, 0x06, 0x45, 0x95, 0x69, - 0x9e, 0x98, 0xc5, 0x45, 0xf2, 0x45, 0xf3, 0x2d, - }, - expected: util.Uint256{ - 0x2d, 0xf3, 0x45, 0xf2, 0x45, 0xc5, 0x98, 0x9e, - 0x69, 0x95, 0x45, 0x06, 0xa5, 0x9e, 0x40, 0x12, - 0xc1, 0x68, 0x54, 0x48, 0x08, 0xfc, 0xcc, 0x5b, - 0x15, 0x18, 0xab, 0xa0, 0x8f, 0x30, 0x37, 0xf0, - }, - }, - { - input: []byte{0, 1, 2, 3, 4, 9, 8, 6}, - expected: []byte{0, 1, 2, 3, 4, 9, 8, 6}, - }, - { - input: []byte{0x63, 0x78, 0x29, 0xcd, 0x0b}, - expected: int64(50686687331), - }, - { - input: []byte{0x63, 0x78, 0x29, 0xcd, 0x0b}, - expected: big.NewInt(50686687331), - }, - { - input: []byte("this is a test string"), - expected: "this is a test string", - }, -} - -func TestParam_TryParse(t *testing.T) { - for _, tc := range tryParseTestCases { - t.Run(reflect.TypeOf(tc.expected).String(), func(t *testing.T) { - input := Parameter{ - Type: ByteArrayType, - Value: tc.input, - } - - val := reflect.New(reflect.TypeOf(tc.expected)) - assert.NoError(t, input.TryParse(val.Interface())) - assert.Equal(t, tc.expected, val.Elem().Interface()) - }) - } - - t.Run("[]Uint160", func(t *testing.T) { - exp1 := util.Uint160{1, 2, 3, 4, 5} - exp2 := util.Uint160{9, 8, 7, 6, 5} - - params := Params{ - { - Type: ByteArrayType, - Value: exp1.BytesBE(), - }, - { - Type: ByteArrayType, - Value: exp2.BytesBE(), - }, - } - - var out1, out2 util.Uint160 - - assert.NoError(t, params.TryParseArray(&out1, &out2)) - assert.Equal(t, exp1, out1) - assert.Equal(t, exp2, out2) - }) -} - func TestParamType_String(t *testing.T) { types := []ParamType{ SignatureType,