code.vegaprotocol.io/vega@v0.79.0/core/datasource/external/ethcall/call_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package ethcall_test
    17  
    18  import (
    19  	"context"
    20  	"math/big"
    21  	"testing"
    22  
    23  	dscommon "code.vegaprotocol.io/vega/core/datasource/common"
    24  	"code.vegaprotocol.io/vega/core/datasource/external/ethcall"
    25  	ethcallcommon "code.vegaprotocol.io/vega/core/datasource/external/ethcall/common"
    26  	v1 "code.vegaprotocol.io/vega/protos/vega/data/v1"
    27  
    28  	"github.com/ethereum/go-ethereum/common"
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func TestContractCall(t *testing.T) {
    34  	ctx := context.Background()
    35  	tc, err := NewToyChain()
    36  	require.NoError(t, err)
    37  
    38  	args := []any{
    39  		int64(42),
    40  		big.NewInt(42),
    41  		"hello",
    42  		true,
    43  		common.HexToAddress("0xb794f5ea0ba39494ce839613fffba74279579268"),
    44  	}
    45  
    46  	argsJson, err := ethcall.AnyArgsToJson(args)
    47  	require.NoError(t, err)
    48  
    49  	spec := ethcallcommon.Spec{
    50  		ArgsJson:    argsJson,
    51  		Address:     tc.contractAddr.Hex(),
    52  		AbiJson:     tc.abiBytes,
    53  		Method:      "testy1",
    54  		Normalisers: map[string]string{"badger": `$[0]`, "static": "66"},
    55  	}
    56  
    57  	call, err := ethcall.NewCall(spec)
    58  	require.NoError(t, err)
    59  
    60  	res, err := call.Call(ctx, tc.client, 1)
    61  	require.NoError(t, err)
    62  	assert.NotEmpty(t, res.Bytes)
    63  
    64  	assert.Equal(t, []any{int64(42), big.NewInt(42), "hello", true, common.HexToAddress("0xb794f5ea0ba39494ce839613fffba74279579268")}, res.Values)
    65  	assert.Equal(t, map[string]string{"badger": "42", "static": "66"}, res.Normalised)
    66  }
    67  
    68  func TestContractCallWithStaticBool(t *testing.T) {
    69  	ctx := context.Background()
    70  	tc, err := NewToyChain()
    71  	require.NoError(t, err)
    72  
    73  	args := []any{
    74  		int64(42),
    75  		big.NewInt(42),
    76  		"hello",
    77  		true,
    78  		common.HexToAddress("0xb794f5ea0ba39494ce839613fffba74279579268"),
    79  	}
    80  
    81  	argsJson, err := ethcall.AnyArgsToJson(args)
    82  	require.NoError(t, err)
    83  
    84  	spec := ethcallcommon.Spec{
    85  		ArgsJson:    argsJson,
    86  		Address:     tc.contractAddr.Hex(),
    87  		AbiJson:     tc.abiBytes,
    88  		Method:      "testy1",
    89  		Normalisers: map[string]string{"badger": `$[0]`, "static": "true"},
    90  	}
    91  
    92  	call, err := ethcall.NewCall(spec)
    93  	require.NoError(t, err)
    94  
    95  	res, err := call.Call(ctx, tc.client, 1)
    96  	require.NoError(t, err)
    97  	assert.NotEmpty(t, res.Bytes)
    98  
    99  	assert.Equal(t, []any{int64(42), big.NewInt(42), "hello", true, common.HexToAddress("0xb794f5ea0ba39494ce839613fffba74279579268")}, res.Values)
   100  	assert.Equal(t, map[string]string{"badger": "42", "static": "true"}, res.Normalised)
   101  }
   102  
   103  func TestContractCall2(t *testing.T) {
   104  	ctx := context.Background()
   105  	tc, err := NewToyChain()
   106  	require.NoError(t, err)
   107  
   108  	args := []any{
   109  		[]*big.Int{big.NewInt(10), big.NewInt(20)},
   110  		struct {
   111  			Name string `json:"name"`
   112  			Age  uint16 `json:"age"`
   113  		}{Name: "test", Age: 42},
   114  	}
   115  
   116  	argsJson, err := ethcall.AnyArgsToJson(args)
   117  	require.NoError(t, err)
   118  
   119  	spec := ethcallcommon.Spec{
   120  		ArgsJson: argsJson,
   121  		Address:  tc.contractAddr.Hex(),
   122  		AbiJson:  tc.abiBytes,
   123  		Method:   "testy2",
   124  		Normalisers: map[string]string{
   125  			"inside_bigint_list": `$[0][1]`,
   126  			"inside_struct":      `$[1].name`,
   127  			"static":             "66",
   128  		},
   129  	}
   130  
   131  	call, err := ethcall.NewCall(spec)
   132  	require.NoError(t, err)
   133  
   134  	res, err := call.Call(ctx, tc.client, 1)
   135  	require.NoError(t, err)
   136  	assert.NotEmpty(t, res.Bytes)
   137  
   138  	assert.Equal(t, args, res.Values)
   139  
   140  	assert.Equal(t, map[string]string{"static": "66", "inside_struct": "test", "inside_bigint_list": "20"}, res.Normalised)
   141  }
   142  
   143  func TestContractFilters(t *testing.T) {
   144  	ctx := context.Background()
   145  	tc, err := NewToyChain()
   146  	require.NoError(t, err)
   147  
   148  	args := []any{
   149  		int64(42),
   150  		big.NewInt(42),
   151  		"hello",
   152  		true,
   153  		common.HexToAddress("0xb794f5ea0ba39494ce839613fffba74279579268"),
   154  	}
   155  
   156  	argsJson, err := ethcall.AnyArgsToJson(args)
   157  	require.NoError(t, err)
   158  
   159  	spec := ethcallcommon.Spec{
   160  		ArgsJson:    argsJson,
   161  		Address:     tc.contractAddr.Hex(),
   162  		AbiJson:     tc.abiBytes,
   163  		Method:      "testy1",
   164  		Normalisers: map[string]string{"badger": `$[0]`, "static": "66"},
   165  		Filters: []*dscommon.SpecFilter{
   166  			{
   167  				Key: &dscommon.SpecPropertyKey{
   168  					Name: "badger",
   169  					Type: v1.PropertyKey_TYPE_INTEGER,
   170  				},
   171  				Conditions: []*dscommon.SpecCondition{
   172  					{
   173  						Operator: v1.Condition_OPERATOR_GREATER_THAN_OR_EQUAL,
   174  						Value:    "50",
   175  					},
   176  				},
   177  			},
   178  		},
   179  	}
   180  
   181  	call, err := ethcall.NewCall(spec)
   182  	require.NoError(t, err)
   183  
   184  	res, err := call.Call(ctx, tc.client, 1)
   185  	require.NoError(t, err)
   186  	assert.NotEmpty(t, res.Bytes)
   187  	assert.False(t, res.PassesFilters)
   188  	assert.Equal(t, []any{int64(42), big.NewInt(42), "hello", true, common.HexToAddress("0xb794f5ea0ba39494ce839613fffba74279579268")}, res.Values)
   189  	assert.Equal(t, map[string]string{"badger": "42", "static": "66"}, res.Normalised)
   190  }