code.vegaprotocol.io/vega@v0.79.0/core/assets/assets_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 assets_test
    17  
    18  import (
    19  	"context"
    20  	"encoding/hex"
    21  	"math/big"
    22  	"testing"
    23  	"time"
    24  
    25  	"code.vegaprotocol.io/vega/core/assets"
    26  	erc20mocks "code.vegaprotocol.io/vega/core/assets/erc20/mocks"
    27  	"code.vegaprotocol.io/vega/core/assets/mocks"
    28  	bmocks "code.vegaprotocol.io/vega/core/broker/mocks"
    29  	nwethmocks "code.vegaprotocol.io/vega/core/nodewallets/eth/mocks"
    30  	"code.vegaprotocol.io/vega/core/types"
    31  	"code.vegaprotocol.io/vega/libs/num"
    32  	vgrand "code.vegaprotocol.io/vega/libs/rand"
    33  	"code.vegaprotocol.io/vega/logging"
    34  
    35  	"github.com/golang/mock/gomock"
    36  	"github.com/stretchr/testify/require"
    37  )
    38  
    39  type testService struct {
    40  	*assets.Service
    41  	broker              *bmocks.MockInterface
    42  	primaryBridgeView   *mocks.MockERC20BridgeView
    43  	secondaryBridgeView *mocks.MockERC20BridgeView
    44  	notary              *mocks.MockNotary
    45  	ctrl                *gomock.Controller
    46  	primaryEthClient    *erc20mocks.MockETHClient
    47  	ethWallet           *nwethmocks.MockEthereumWallet
    48  	secondaryEthClient  *erc20mocks.MockETHClient
    49  }
    50  
    51  func TestAssets(t *testing.T) {
    52  	t.Run("Staging asset update for unknown asset fails", testStagingAssetUpdateForUnknownAssetFails)
    53  	t.Run("Offers signature on tick success", testOffersSignaturesOnTickSuccess)
    54  	t.Run("Checking an assets address when chain id is unknown", testValidateUnknownChainID)
    55  }
    56  
    57  func testOffersSignaturesOnTickSuccess(t *testing.T) {
    58  	service := getTestService(t)
    59  
    60  	assetID := hex.EncodeToString([]byte("asset_id"))
    61  
    62  	assetDetails := &types.AssetDetails{
    63  		Name:     vgrand.RandomStr(5),
    64  		Symbol:   vgrand.RandomStr(3),
    65  		Decimals: 10,
    66  		Quantum:  num.DecimalFromInt64(42),
    67  		Source: &types.AssetDetailsErc20{
    68  			ERC20: &types.ERC20{
    69  				ContractAddress:   vgrand.RandomStr(5),
    70  				LifetimeLimit:     num.NewUint(42),
    71  				WithdrawThreshold: num.NewUint(84),
    72  				ChainID:           "1",
    73  			},
    74  		},
    75  	}
    76  
    77  	ctx := context.Background()
    78  
    79  	service.broker.EXPECT().Send(gomock.Any()).Times(1)
    80  	_, err := service.NewAsset(ctx, assetID, assetDetails)
    81  	require.NoError(t, err)
    82  
    83  	service.broker.EXPECT().Send(gomock.Any()).Times(1)
    84  	require.NoError(t, service.Enable(ctx, assetID))
    85  
    86  	nodeSignature := []byte("node_signature")
    87  	service.notary.EXPECT().
    88  		OfferSignatures(gomock.Any(), gomock.Any()).DoAndReturn(
    89  		func(kind types.NodeSignatureKind, f func(id string) []byte) {
    90  			require.Equal(t, kind, types.NodeSignatureKindAssetNew)
    91  			require.Equal(t, nodeSignature, f(assetID))
    92  		},
    93  	)
    94  	service.primaryEthClient.EXPECT().CollateralBridgeAddress().Times(1)
    95  	service.ethWallet.EXPECT().Algo().Times(1)
    96  	service.ethWallet.EXPECT().Sign(gomock.Any()).Return(nodeSignature, nil).Times(1)
    97  	service.OnTick(ctx, time.Now())
    98  }
    99  
   100  func testStagingAssetUpdateForUnknownAssetFails(t *testing.T) {
   101  	service := getTestService(t)
   102  
   103  	// given
   104  	asset := &types.Asset{
   105  		ID: vgrand.RandomStr(5),
   106  		Details: &types.AssetDetails{
   107  			Name:     vgrand.RandomStr(5),
   108  			Symbol:   vgrand.RandomStr(3),
   109  			Decimals: 10,
   110  			Quantum:  num.DecimalFromInt64(42),
   111  			Source: &types.AssetDetailsErc20{
   112  				ERC20: &types.ERC20{
   113  					ContractAddress:   vgrand.RandomStr(5),
   114  					LifetimeLimit:     num.NewUint(42),
   115  					WithdrawThreshold: num.NewUint(84),
   116  					ChainID:           "1",
   117  				},
   118  			},
   119  		},
   120  	}
   121  
   122  	// when
   123  	err := service.StageAssetUpdate(asset)
   124  
   125  	// then
   126  	require.ErrorIs(t, err, assets.ErrAssetDoesNotExist)
   127  }
   128  
   129  func testValidateUnknownChainID(t *testing.T) {
   130  	service := getTestService(t)
   131  
   132  	require.NoError(t, service.ValidateEthereumAddress(vgrand.RandomStr(5), "1"))
   133  	require.NoError(t, service.ValidateEthereumAddress(vgrand.RandomStr(5), "2"))
   134  	require.ErrorIs(t, service.ValidateEthereumAddress(vgrand.RandomStr(5), "666"), assets.ErrUnknownChainID)
   135  }
   136  
   137  func getTestService(t *testing.T) *testService {
   138  	t.Helper()
   139  	conf := assets.NewDefaultConfig()
   140  	logger := logging.NewTestLogger()
   141  	ctrl := gomock.NewController(t)
   142  	primaryEthClient := erc20mocks.NewMockETHClient(ctrl)
   143  	primaryEthClient.EXPECT().ChainID(gomock.Any()).AnyTimes().Return(big.NewInt(1), nil)
   144  	primaryEthClient.EXPECT().IsEthereum().AnyTimes().Return(true)
   145  	secondaryEthClient := erc20mocks.NewMockETHClient(ctrl)
   146  	secondaryEthClient.EXPECT().ChainID(gomock.Any()).AnyTimes().Return(big.NewInt(2), nil)
   147  	secondaryEthClient.EXPECT().IsEthereum().AnyTimes().Return(false)
   148  	broker := bmocks.NewMockInterface(ctrl)
   149  	primaryBridgeView := mocks.NewMockERC20BridgeView(ctrl)
   150  	secondaryBridgeView := mocks.NewMockERC20BridgeView(ctrl)
   151  	notary := mocks.NewMockNotary(ctrl)
   152  	ethWallet := nwethmocks.NewMockEthereumWallet(ctrl)
   153  
   154  	service, _ := assets.New(context.Background(), logger, conf, ethWallet, primaryEthClient, secondaryEthClient, broker, primaryBridgeView, secondaryBridgeView, notary, true)
   155  	return &testService{
   156  		Service:             service,
   157  		broker:              broker,
   158  		ctrl:                ctrl,
   159  		primaryBridgeView:   primaryBridgeView,
   160  		secondaryBridgeView: secondaryBridgeView,
   161  		notary:              notary,
   162  		primaryEthClient:    primaryEthClient,
   163  		secondaryEthClient:  secondaryEthClient,
   164  		ethWallet:           ethWallet,
   165  	}
   166  }