From 703a7785b3d9bf881637362e857bad8eba57599b Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 3 Sep 2024 17:11:29 +0300 Subject: [PATCH 1/3] - made the migration tool automatically fetch the tokens list --- clients/multiversx/mxClientDataGetter.go | 9 ++ clients/multiversx/mxClientDataGetter_test.go | 29 +++++ cmd/migration/config/config.toml | 16 --- cmd/migration/main.go | 9 +- config/config.go | 12 +- config/tomlConfigs_test.go | 16 --- executors/ethereum/errors.go | 9 +- executors/ethereum/interface.go | 7 ++ executors/ethereum/migrationBatchCreator.go | 56 +++++++--- .../ethereum/migrationBatchCreator_test.go | 103 ++++++++++++------ testsCommon/bridge/dataGetterStub.go | 10 ++ 11 files changed, 169 insertions(+), 107 deletions(-) diff --git a/clients/multiversx/mxClientDataGetter.go b/clients/multiversx/mxClientDataGetter.go index aae649f0..324f03ea 100644 --- a/clients/multiversx/mxClientDataGetter.go +++ b/clients/multiversx/mxClientDataGetter.go @@ -41,6 +41,7 @@ const ( getTotalBalances = "getTotalBalances" getMintBalances = "getMintBalances" getBurnBalances = "getBurnBalances" + getAllKnownTokens = "getAllKnownTokens" ) // ArgsMXClientDataGetter is the arguments DTO used in the NewMXClientDataGetter constructor @@ -526,6 +527,14 @@ func getStatusFromBuff(buff []byte) (byte, error) { return buff[len(buff)-1], nil } +// GetAllKnownTokens returns all registered tokens +func (dataGetter *mxClientDataGetter) GetAllKnownTokens(ctx context.Context) ([][]byte, error) { + builder := dataGetter.createSafeDefaultVmQueryBuilder() + builder.Function(getAllKnownTokens) + + return dataGetter.executeQueryFromBuilder(ctx, builder) +} + // IsInterfaceNil returns true if there is no value under the interface func (dataGetter *mxClientDataGetter) IsInterfaceNil() bool { return dataGetter == nil diff --git a/clients/multiversx/mxClientDataGetter_test.go b/clients/multiversx/mxClientDataGetter_test.go index d6a9a527..d21ea26b 100644 --- a/clients/multiversx/mxClientDataGetter_test.go +++ b/clients/multiversx/mxClientDataGetter_test.go @@ -1258,6 +1258,35 @@ func TestMXClientDataGetter_GetAllStakedRelayers(t *testing.T) { assert.Equal(t, providedRelayers, result) } +func TestMXClientDataGetter_GetAllKnownTokens(t *testing.T) { + t.Parallel() + + args := createMockArgsMXClientDataGetter() + providedTokens := [][]byte{[]byte("tkn1"), []byte("tkn2")} + args.Proxy = &interactors.ProxyStub{ + ExecuteVMQueryCalled: func(ctx context.Context, vmRequest *data.VmValueRequest) (*data.VmValuesResponseData, error) { + assert.Equal(t, getBech32Address(args.SafeContractAddress), vmRequest.Address) + assert.Equal(t, "", vmRequest.CallValue) + assert.Equal(t, getAllKnownTokens, vmRequest.FuncName) + + assert.Nil(t, vmRequest.Args) + + return &data.VmValuesResponseData{ + Data: &vm.VMOutputApi{ + ReturnCode: okCodeAfterExecution, + ReturnData: providedTokens, + }, + }, nil + }, + } + + dg, _ := NewMXClientDataGetter(args) + + result, err := dg.GetAllKnownTokens(context.Background()) + assert.Nil(t, err) + assert.Equal(t, providedTokens, result) +} + func TestMultiversXClientDataGetter_GetShardCurrentNonce(t *testing.T) { t.Parallel() diff --git a/cmd/migration/config/config.toml b/cmd/migration/config/config.toml index e6a8e24f..c5c36513 100644 --- a/cmd/migration/config/config.toml +++ b/cmd/migration/config/config.toml @@ -32,19 +32,3 @@ [Logs] LogFileLifeSpanInSec = 86400 # 24h LogFileLifeSpanInMB = 1024 # 1GB - -[WhitelistedTokens] - List = [ - "ETHUSDC-220753", - "ETHUTK-8cdf7a", - "ETHUSDT-9c73c6", - "ETHBUSD-450923", - "ETHHMT-18538a", - "ETHCGG-ee4e0c", - "ETHINFRA-60a3bf", - "ETHWBTC-74e282", - "ETHWETH-e1c126", - "ETHWSDAI-572803", - "ETHWDAI-bd65f9", - "ETHUMB-291202", - ] diff --git a/cmd/migration/main.go b/cmd/migration/main.go index 93bcd293..cf7c19a2 100644 --- a/cmd/migration/main.go +++ b/cmd/migration/main.go @@ -16,7 +16,6 @@ import ( ethereumClient "github.com/multiversx/mx-bridge-eth-go/clients/ethereum" "github.com/multiversx/mx-bridge-eth-go/clients/ethereum/contract" "github.com/multiversx/mx-bridge-eth-go/clients/multiversx" - "github.com/multiversx/mx-bridge-eth-go/clients/multiversx/mappers" "github.com/multiversx/mx-bridge-eth-go/cmd/migration/disabled" "github.com/multiversx/mx-bridge-eth-go/config" "github.com/multiversx/mx-bridge-eth-go/executors/ethereum" @@ -119,11 +118,6 @@ func generateAndSign(ctx *cli.Context, cfg config.MigrationToolConfig) error { return err } - tokensWrapper, err := mappers.NewMultiversXToErc20Mapper(mxDataGetter) - if err != nil { - return err - } - ethClient, err := ethclient.Dial(cfg.Eth.NetworkAddress) if err != nil { return err @@ -145,8 +139,7 @@ func generateAndSign(ctx *cli.Context, cfg config.MigrationToolConfig) error { } argsCreator := ethereum.ArgsMigrationBatchCreator{ - TokensList: cfg.WhitelistedTokens.List, - TokensMapper: tokensWrapper, + MvxDataGetter: mxDataGetter, Erc20ContractsHolder: erc20ContractsHolder, SafeContractAddress: safeEthAddress, SafeContractWrapper: safeInstance, diff --git a/config/config.go b/config/config.go index 916126db..76e85dcb 100644 --- a/config/config.go +++ b/config/config.go @@ -206,15 +206,9 @@ type ScCallsModuleConfig struct { Logs LogsConfig } -// WhitelistedTokensConfig will hold the whitelisted tokens config -type WhitelistedTokensConfig struct { - List []string -} - // MigrationToolConfig is the migration tool config struct type MigrationToolConfig struct { - Eth EthereumConfig - MultiversX MultiversXConfig - Logs LogsConfig - WhitelistedTokens WhitelistedTokensConfig + Eth EthereumConfig + MultiversX MultiversXConfig + Logs LogsConfig } diff --git a/config/tomlConfigs_test.go b/config/tomlConfigs_test.go index 4e0b3498..03d1ce67 100644 --- a/config/tomlConfigs_test.go +++ b/config/tomlConfigs_test.go @@ -494,22 +494,6 @@ func TestMigrationToolConfig(t *testing.T) { LogFileLifeSpanInSec: 86400, LogFileLifeSpanInMB: 1024, }, - WhitelistedTokens: WhitelistedTokensConfig{ - List: []string{ - "ETHUSDC-220753", - "ETHUTK-8cdf7a", - "ETHUSDT-9c73c6", - "ETHBUSD-450923", - "ETHHMT-18538a", - "ETHCGG-ee4e0c", - "ETHINFRA-60a3bf", - "ETHWBTC-74e282", - "ETHWETH-e1c126", - "ETHWSDAI-572803", - "ETHWDAI-bd65f9", - "ETHUMB-291202", - }, - }, } testString := ` diff --git a/executors/ethereum/errors.go b/executors/ethereum/errors.go index 25687f62..c0c19f9c 100644 --- a/executors/ethereum/errors.go +++ b/executors/ethereum/errors.go @@ -3,8 +3,9 @@ package ethereum import "errors" var ( - errEmptyTokensList = errors.New("empty tokens list") - errNilTokensMapper = errors.New("nil MultiversX to Ethereum tokens mapper") - errNilErc20ContractsHolder = errors.New("nil ERC20 contracts holder") - errNilSafeContractWrapper = errors.New("nil safe contract wrapper") + errEmptyTokensList = errors.New("empty tokens list") + errNilMvxDataGetter = errors.New("nil MultiversX data getter") + errNilErc20ContractsHolder = errors.New("nil ERC20 contracts holder") + errNilSafeContractWrapper = errors.New("nil safe contract wrapper") + errWrongERC20AddressResponse = errors.New("wrong ERC20 address response") ) diff --git a/executors/ethereum/interface.go b/executors/ethereum/interface.go index 5ddaf025..5c3bc0f4 100644 --- a/executors/ethereum/interface.go +++ b/executors/ethereum/interface.go @@ -25,3 +25,10 @@ type SafeContractWrapper interface { DepositsCount(opts *bind.CallOpts) (uint64, error) BatchesCount(opts *bind.CallOpts) (uint64, error) } + +// MvxDataGetter defines the operations for the data getter operating on MultiversX chain +type MvxDataGetter interface { + GetAllKnownTokens(ctx context.Context) ([][]byte, error) + GetERC20AddressForTokenId(ctx context.Context, tokenId []byte) ([][]byte, error) + IsInterfaceNil() bool +} diff --git a/executors/ethereum/migrationBatchCreator.go b/executors/ethereum/migrationBatchCreator.go index 3571d383..a7c4621c 100644 --- a/executors/ethereum/migrationBatchCreator.go +++ b/executors/ethereum/migrationBatchCreator.go @@ -16,16 +16,14 @@ var zero = big.NewInt(0) // ArgsMigrationBatchCreator is the argument for the NewMigrationBatchCreator constructor type ArgsMigrationBatchCreator struct { - TokensList []string - TokensMapper TokensMapper + MvxDataGetter MvxDataGetter Erc20ContractsHolder Erc20ContractsHolder SafeContractAddress common.Address SafeContractWrapper SafeContractWrapper } type migrationBatchCreator struct { - tokensList []string - tokensMapper TokensMapper + mvxDataGetter MvxDataGetter erc20ContractsHolder Erc20ContractsHolder safeContractAddress common.Address safeContractWrapper SafeContractWrapper @@ -33,11 +31,8 @@ type migrationBatchCreator struct { // NewMigrationBatchCreator creates a new instance of type migrationBatchCreator that is able to generate the migration batch output file func NewMigrationBatchCreator(args ArgsMigrationBatchCreator) (*migrationBatchCreator, error) { - if len(args.TokensList) == 0 { - return nil, errEmptyTokensList - } - if check.IfNil(args.TokensMapper) { - return nil, errNilTokensMapper + if check.IfNil(args.MvxDataGetter) { + return nil, errNilMvxDataGetter } if check.IfNil(args.Erc20ContractsHolder) { return nil, errNilErc20ContractsHolder @@ -47,8 +42,7 @@ func NewMigrationBatchCreator(args ArgsMigrationBatchCreator) (*migrationBatchCr } return &migrationBatchCreator{ - tokensList: args.TokensList, - tokensMapper: args.TokensMapper, + mvxDataGetter: args.MvxDataGetter, erc20ContractsHolder: args.Erc20ContractsHolder, safeContractAddress: args.SafeContractAddress, safeContractWrapper: args.SafeContractWrapper, @@ -67,7 +61,12 @@ func (creator *migrationBatchCreator) CreateBatchInfo(ctx context.Context, newSa return nil, err } - deposits, err := creator.fetchERC20ContractsAddresses(ctx, depositsCount) + tokensList, err := creator.getTokensList(ctx) + if err != nil { + return nil, err + } + + deposits, err := creator.fetchERC20ContractsAddresses(ctx, tokensList, depositsCount) if err != nil { return nil, err } @@ -80,19 +79,40 @@ func (creator *migrationBatchCreator) CreateBatchInfo(ctx context.Context, newSa return creator.assembleBatchInfo(batchesCount, deposits, newSafeAddress) } -func (creator *migrationBatchCreator) fetchERC20ContractsAddresses(ctx context.Context, lastDepositNonce uint64) ([]*DepositInfo, error) { - deposits := make([]*DepositInfo, 0, len(creator.tokensList)) - for idx, token := range creator.tokensList { - addressBytes, err := creator.tokensMapper.ConvertToken(ctx, []byte(token)) +func (creator *migrationBatchCreator) getTokensList(ctx context.Context) ([]string, error) { + tokens, err := creator.mvxDataGetter.GetAllKnownTokens(ctx) + if err != nil { + return nil, err + } + if len(tokens) == 0 { + return nil, fmt.Errorf("%w when calling the getAllKnownTokens function on the safe contract", errEmptyTokensList) + } + + stringTokens := make([]string, 0, len(tokens)) + for _, token := range tokens { + stringTokens = append(stringTokens, string(token)) + } + + return stringTokens, nil +} + +func (creator *migrationBatchCreator) fetchERC20ContractsAddresses(ctx context.Context, tokensList []string, lastDepositNonce uint64) ([]*DepositInfo, error) { + deposits := make([]*DepositInfo, 0, len(tokensList)) + for idx, token := range tokensList { + response, err := creator.mvxDataGetter.GetERC20AddressForTokenId(ctx, []byte(token)) if err != nil { return nil, err } + if len(response) != 1 { + return nil, fmt.Errorf("%w when querying the safe contract for token %s", + errWrongERC20AddressResponse, token) + } deposit := &DepositInfo{ DepositNonce: lastDepositNonce + uint64(1+idx), Token: token, - ContractAddress: common.BytesToAddress(addressBytes).String(), - contractAddress: common.BytesToAddress(addressBytes), + ContractAddress: common.BytesToAddress(response[0]).String(), + contractAddress: common.BytesToAddress(response[0]), Amount: "", } diff --git a/executors/ethereum/migrationBatchCreator_test.go b/executors/ethereum/migrationBatchCreator_test.go index 4dd7fd64..801e2465 100644 --- a/executors/ethereum/migrationBatchCreator_test.go +++ b/executors/ethereum/migrationBatchCreator_test.go @@ -23,8 +23,17 @@ var balanceOfTkn2 = big.NewInt(38) func createMockArgsForMigrationBatchCreator() ArgsMigrationBatchCreator { return ArgsMigrationBatchCreator{ - TokensList: []string{"tkn1", "tkn2"}, - TokensMapper: &bridge.TokensMapperStub{}, + MvxDataGetter: &bridge.DataGetterStub{ + GetAllKnownTokensCalled: func(ctx context.Context) ([][]byte, error) { + return [][]byte{ + []byte("tkn1"), + []byte("tkn2"), + }, nil + }, + GetERC20AddressForTokenIdCalled: func(ctx context.Context, tokenId []byte) ([][]byte, error) { + return [][]byte{[]byte("erc 20 address")}, nil + }, + }, Erc20ContractsHolder: &bridge.ERC20ContractsHolderStub{}, SafeContractAddress: safeContractAddress, SafeContractWrapper: &bridge.SafeContractWrapperStub{}, @@ -34,32 +43,15 @@ func createMockArgsForMigrationBatchCreator() ArgsMigrationBatchCreator { func TestNewMigrationBatchCreator(t *testing.T) { t.Parallel() - t.Run("nil or empty tokens list should error", func(t *testing.T) { - t.Parallel() - - args := createMockArgsForMigrationBatchCreator() - args.TokensList = nil - - creator, err := NewMigrationBatchCreator(args) - assert.Nil(t, creator) - assert.Equal(t, errEmptyTokensList, err) - - args = createMockArgsForMigrationBatchCreator() - args.TokensList = make([]string, 0) - - creator, err = NewMigrationBatchCreator(args) - assert.Nil(t, creator) - assert.Equal(t, errEmptyTokensList, err) - }) - t.Run("nil tokens mapper should error", func(t *testing.T) { + t.Run("nil mvx data getter should error", func(t *testing.T) { t.Parallel() args := createMockArgsForMigrationBatchCreator() - args.TokensMapper = nil + args.MvxDataGetter = nil creator, err := NewMigrationBatchCreator(args) assert.Nil(t, creator) - assert.Equal(t, errNilTokensMapper, err) + assert.Equal(t, errNilMvxDataGetter, err) }) t.Run("nil erc20 contracts holder should error", func(t *testing.T) { t.Parallel() @@ -127,12 +119,12 @@ func TestMigrationBatchCreator_CreateBatchInfo(t *testing.T) { assert.Equal(t, expectedErr, err) assert.Nil(t, batch) }) - t.Run("ConvertToken errors should error", func(t *testing.T) { + t.Run("get all known tokens errors should error", func(t *testing.T) { t.Parallel() args := createMockArgsForMigrationBatchCreator() - args.TokensMapper = &bridge.TokensMapperStub{ - ConvertTokenCalled: func(ctx context.Context, sourceBytes []byte) ([]byte, error) { + args.MvxDataGetter = &bridge.DataGetterStub{ + GetAllKnownTokensCalled: func(ctx context.Context) ([][]byte, error) { return nil, expectedErr }, } @@ -142,6 +134,47 @@ func TestMigrationBatchCreator_CreateBatchInfo(t *testing.T) { assert.Equal(t, expectedErr, err) assert.Nil(t, batch) }) + t.Run("get all known tokens returns 0 tokens should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsForMigrationBatchCreator() + args.MvxDataGetter = &bridge.DataGetterStub{ + GetAllKnownTokensCalled: func(ctx context.Context) ([][]byte, error) { + return make([][]byte, 0), nil + }, + } + + creator, _ := NewMigrationBatchCreator(args) + batch, err := creator.CreateBatchInfo(context.Background(), newSafeContractAddress) + assert.ErrorIs(t, err, errEmptyTokensList) + assert.Nil(t, batch) + }) + t.Run("GetERC20AddressForTokenId errors should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsForMigrationBatchCreator() + args.MvxDataGetter.(*bridge.DataGetterStub).GetERC20AddressForTokenIdCalled = func(ctx context.Context, sourceBytes []byte) ([][]byte, error) { + return nil, expectedErr + } + + creator, _ := NewMigrationBatchCreator(args) + batch, err := creator.CreateBatchInfo(context.Background(), newSafeContractAddress) + assert.Equal(t, expectedErr, err) + assert.Nil(t, batch) + }) + t.Run("GetERC20AddressForTokenId returns empty list should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsForMigrationBatchCreator() + args.MvxDataGetter.(*bridge.DataGetterStub).GetERC20AddressForTokenIdCalled = func(ctx context.Context, sourceBytes []byte) ([][]byte, error) { + return make([][]byte, 0), nil + } + + creator, _ := NewMigrationBatchCreator(args) + batch, err := creator.CreateBatchInfo(context.Background(), newSafeContractAddress) + assert.ErrorIs(t, err, errWrongERC20AddressResponse) + assert.Nil(t, batch) + }) t.Run("BalanceOf errors should error", func(t *testing.T) { t.Parallel() @@ -164,17 +197,15 @@ func TestMigrationBatchCreator_CreateBatchInfo(t *testing.T) { depositCount := depositCountStart batchesCount := uint64(2244) args := createMockArgsForMigrationBatchCreator() - args.TokensMapper = &bridge.TokensMapperStub{ - ConvertTokenCalled: func(ctx context.Context, sourceBytes []byte) ([]byte, error) { - if string(sourceBytes) == "tkn1" { - return tkn1Erc20Address, nil - } - if string(sourceBytes) == "tkn2" { - return tkn2Erc20Address, nil - } - - return nil, fmt.Errorf("unexpected source bytes") - }, + args.MvxDataGetter.(*bridge.DataGetterStub).GetERC20AddressForTokenIdCalled = func(ctx context.Context, sourceBytes []byte) ([][]byte, error) { + if string(sourceBytes) == "tkn1" { + return [][]byte{tkn1Erc20Address}, nil + } + if string(sourceBytes) == "tkn2" { + return [][]byte{tkn2Erc20Address}, nil + } + + return nil, fmt.Errorf("unexpected source bytes") } args.Erc20ContractsHolder = &bridge.ERC20ContractsHolderStub{ BalanceOfCalled: func(ctx context.Context, erc20Address common.Address, address common.Address) (*big.Int, error) { diff --git a/testsCommon/bridge/dataGetterStub.go b/testsCommon/bridge/dataGetterStub.go index 5badf503..f3209009 100644 --- a/testsCommon/bridge/dataGetterStub.go +++ b/testsCommon/bridge/dataGetterStub.go @@ -9,6 +9,7 @@ type DataGetterStub struct { GetTokenIdForErc20AddressCalled func(ctx context.Context, erc20Address []byte) ([][]byte, error) GetERC20AddressForTokenIdCalled func(ctx context.Context, tokenId []byte) ([][]byte, error) GetAllStakedRelayersCalled func(ctx context.Context) ([][]byte, error) + GetAllKnownTokensCalled func(ctx context.Context) ([][]byte, error) } // GetTokenIdForErc20Address - @@ -36,6 +37,15 @@ func (stub *DataGetterStub) GetAllStakedRelayers(ctx context.Context) ([][]byte, return make([][]byte, 0), nil } +// GetAllKnownTokens - +func (stub *DataGetterStub) GetAllKnownTokens(ctx context.Context) ([][]byte, error) { + if stub.GetAllKnownTokensCalled != nil { + return stub.GetAllKnownTokensCalled(ctx) + } + + return make([][]byte, 0), nil +} + // IsInterfaceNil - func (stub *DataGetterStub) IsInterfaceNil() bool { return stub == nil From 5d860dc80b92b3df141c19add9e842ffee12dece Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 3 Sep 2024 17:55:01 +0300 Subject: [PATCH 2/3] - fixes --- cmd/migration/config/config.toml | 3 +- cmd/migration/config/migration.json | 33 ++++++++++--------- cmd/migration/flags.go | 2 +- cmd/migration/main.go | 21 ++++++++---- config/tomlConfigs_test.go | 4 ++- executors/ethereum/errors.go | 1 + executors/ethereum/migrationBatchCreator.go | 18 ++++++++++ .../ethereum/migrationBatchCreator_test.go | 12 +++++++ 8 files changed, 69 insertions(+), 25 deletions(-) diff --git a/cmd/migration/config/config.toml b/cmd/migration/config/config.toml index c5c36513..e2e13976 100644 --- a/cmd/migration/config/config.toml +++ b/cmd/migration/config/config.toml @@ -20,12 +20,13 @@ [MultiversX] NetworkAddress = "https://devnet-gateway.multiversx.com" # the network address MultisigContractAddress = "erd1qqqqqqqqqqqqqpgqtvnswnzxxz8susupesys0hvg7q2z5nawrcjq06qdus" + SafeContractAddress = "erd1qqqqqqqqqqqqqpgqhxkc48lt5uv2hejj4wtjqvugfm4wgv6gyfkqw0uuxl" [MultiversX.Proxy] CacherExpirationSeconds = 600 # the caching time in seconds # valid options for ProxyRestAPIEntityType are "observer" and "proxy". Any other value will trigger an error. # "observer" is useful when querying an observer, directly and "proxy" is useful when querying a squad's proxy (gateway) - RestAPIEntityType = "observer" + RestAPIEntityType = "proxy" FinalityCheck = true MaxNoncesDelta = 7 # the number of maximum blocks allowed to be "in front" of what the metachain has notarized diff --git a/cmd/migration/config/migration.json b/cmd/migration/config/migration.json index 3f03dc36..25d106fd 100644 --- a/cmd/migration/config/migration.json +++ b/cmd/migration/config/migration.json @@ -1,76 +1,77 @@ { "OldSafeContractAddress": "0x92A26975433A61CF1134802586aa669bAB8B69f3", - "NewSafeContractAddress": "0x37aaaf95887624a363effB7762D489E3C05c2a02", - "BatchID": 3547, + "NewSafeContractAddress": "0xA6504Cc508889bbDBd4B748aFf6EA6b5D0d2684c", + "BatchID": 3548, + "MessageHash": "0x9fad9673d99127cf3bfbcb25fdb271c90009e1199e5ae3bd98f516a6d2b46357", "DepositsInfo": [ { - "DepositNonce": 4651, + "DepositNonce": 4652, "Token": "ETHUSDC-220753", "ContractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - "Amount": "7245293620507" + "Amount": "7091634513581" }, { - "DepositNonce": 4652, + "DepositNonce": 4653, "Token": "ETHUTK-8cdf7a", "ContractAddress": "0xdc9Ac3C20D1ed0B540dF9b1feDC10039Df13F99c", "Amount": "224564169411881824066539333" }, { - "DepositNonce": 4653, + "DepositNonce": 4654, "Token": "ETHUSDT-9c73c6", "ContractAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7", - "Amount": "305146464594" + "Amount": "318715112062" }, { - "DepositNonce": 4654, + "DepositNonce": 4655, "Token": "ETHBUSD-450923", "ContractAddress": "0x4Fabb145d64652a948d72533023f6E7A623C7C53", "Amount": "22294352736330153151984" }, { - "DepositNonce": 4655, + "DepositNonce": 4656, "Token": "ETHHMT-18538a", "ContractAddress": "0xd1ba9BAC957322D6e8c07a160a3A8dA11A0d2867", "Amount": "435000000000000000000" }, { - "DepositNonce": 4656, + "DepositNonce": 4657, "Token": "ETHCGG-ee4e0c", "ContractAddress": "0x1fE24F25b1Cf609B9c4e7E12D802e3640dFA5e43", "Amount": "1500138370967581082219795" }, { - "DepositNonce": 4657, + "DepositNonce": 4658, "Token": "ETHINFRA-60a3bf", "ContractAddress": "0x013062189dc3dcc99e9Cee714c513033b8d99e3c", "Amount": "141172595980399500424091" }, { - "DepositNonce": 4658, + "DepositNonce": 4659, "Token": "ETHWBTC-74e282", "ContractAddress": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "Amount": "3898848955" }, { - "DepositNonce": 4659, + "DepositNonce": 4660, "Token": "ETHWETH-e1c126", "ContractAddress": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "Amount": "725921417141355037005" }, { - "DepositNonce": 4660, + "DepositNonce": 4661, "Token": "ETHWSDAI-572803", "ContractAddress": "0x83F20F44975D03b1b09e64809B757c47f942BEeA", "Amount": "5431516086574385345409" }, { - "DepositNonce": 4661, + "DepositNonce": 4662, "Token": "ETHWDAI-bd65f9", "ContractAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "Amount": "127608014625114134146189" }, { - "DepositNonce": 4662, + "DepositNonce": 4663, "Token": "ETHUMB-291202", "ContractAddress": "0x6fC13EACE26590B80cCCAB1ba5d51890577D83B2", "Amount": "4669367702477323508554075" diff --git a/cmd/migration/flags.go b/cmd/migration/flags.go index 37b07063..e2fce5fa 100644 --- a/cmd/migration/flags.go +++ b/cmd/migration/flags.go @@ -15,7 +15,7 @@ var ( ", if set to *:INFO the logs for all packages will have the INFO level. However, if set to *:INFO,api:DEBUG" + " the logs for all packages will have the INFO level, excepting the api package which will receive a DEBUG" + " log level.", - Value: "*:" + logger.LogDebug.String(), + Value: "*:" + logger.LogInfo.String(), } configurationFile = cli.StringFlag{ Name: "config", diff --git a/cmd/migration/main.go b/cmd/migration/main.go index cf7c19a2..7b4c5cf8 100644 --- a/cmd/migration/main.go +++ b/cmd/migration/main.go @@ -57,6 +57,8 @@ func main() { log.Error(err.Error()) os.Exit(1) } + + log.Info("process finished successfully") } func execute(ctx *cli.Context) error { @@ -106,9 +108,14 @@ func generateAndSign(ctx *cli.Context, cfg config.MigrationToolConfig) error { return err } + safeAddress, err := data.NewAddressFromBech32String(cfg.MultiversX.SafeContractAddress) + if err != nil { + return err + } + argsMXClientDataGetter := multiversx.ArgsMXClientDataGetter{ MultisigContractAddress: multisigAddress, - SafeContractAddress: dummyAddress, + SafeContractAddress: safeAddress, RelayerAddress: dummyAddress, Proxy: proxy, Log: log, @@ -143,6 +150,7 @@ func generateAndSign(ctx *cli.Context, cfg config.MigrationToolConfig) error { Erc20ContractsHolder: erc20ContractsHolder, SafeContractAddress: safeEthAddress, SafeContractWrapper: safeInstance, + Logger: log, } creator, err := ethereum.NewMigrationBatchCreator(argsCreator) @@ -171,16 +179,15 @@ func generateAndSign(ctx *cli.Context, cfg config.MigrationToolConfig) error { return err } + log.Info("signing batch", "message hash", batchInfo.MessageHash.String(), + "public key", cryptoHandler.GetAddress().String()) + signature, err := cryptoHandler.Sign(batchInfo.MessageHash) if err != nil { return err } - log.Info(string(val)) - log.Info("Batch signed", - "public key", cryptoHandler.GetAddress().String(), - "message hash", batchInfo.MessageHash.String(), - "signature", signature) + log.Info("Migration .json file contents: \n" + string(val)) jsonFilename := ctx.GlobalString(migrationJsonFile.Name) err = os.WriteFile(jsonFilename, val, os.ModePerm) @@ -200,6 +207,8 @@ func generateAndSign(ctx *cli.Context, cfg config.MigrationToolConfig) error { return err } + log.Info("Signature .json file contents: \n" + string(val)) + return os.WriteFile(sigFilename, val, os.ModePerm) } diff --git a/config/tomlConfigs_test.go b/config/tomlConfigs_test.go index 03d1ce67..3f7d72e4 100644 --- a/config/tomlConfigs_test.go +++ b/config/tomlConfigs_test.go @@ -483,6 +483,7 @@ func TestMigrationToolConfig(t *testing.T) { MultiversX: MultiversXConfig{ NetworkAddress: "https://devnet-gateway.multiversx.com", MultisigContractAddress: "erd1qqqqqqqqqqqqqpgqzyuaqg3dl7rqlkudrsnm5ek0j3a97qevd8sszj0glf", + SafeContractAddress: "erd1qqqqqqqqqqqqqpgqtvnswnzxxz8susupesys0hvg7q2z5nawrcjq06qdus", Proxy: ProxyConfig{ CacherExpirationSeconds: 600, RestAPIEntityType: "observer", @@ -518,7 +519,8 @@ func TestMigrationToolConfig(t *testing.T) { [MultiversX] NetworkAddress = "https://devnet-gateway.multiversx.com" # the network address - MultisigContractAddress = "erd1qqqqqqqqqqqqqpgqzyuaqg3dl7rqlkudrsnm5ek0j3a97qevd8sszj0glf" + MultisigContractAddress = "erd1qqqqqqqqqqqqqpgqzyuaqg3dl7rqlkudrsnm5ek0j3a97qevd8sszj0glf" # the multiversx address for the bridge contract + SafeContractAddress = "erd1qqqqqqqqqqqqqpgqtvnswnzxxz8susupesys0hvg7q2z5nawrcjq06qdus" # the multiversx address for the safe contract [MultiversX.Proxy] CacherExpirationSeconds = 600 # the caching time in seconds diff --git a/executors/ethereum/errors.go b/executors/ethereum/errors.go index c0c19f9c..2706fde9 100644 --- a/executors/ethereum/errors.go +++ b/executors/ethereum/errors.go @@ -8,4 +8,5 @@ var ( errNilErc20ContractsHolder = errors.New("nil ERC20 contracts holder") errNilSafeContractWrapper = errors.New("nil safe contract wrapper") errWrongERC20AddressResponse = errors.New("wrong ERC20 address response") + errNilLogger = errors.New("nil logger") ) diff --git a/executors/ethereum/migrationBatchCreator.go b/executors/ethereum/migrationBatchCreator.go index a7c4621c..680573da 100644 --- a/executors/ethereum/migrationBatchCreator.go +++ b/executors/ethereum/migrationBatchCreator.go @@ -4,12 +4,14 @@ import ( "context" "fmt" "math/big" + "strings" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/multiversx/mx-bridge-eth-go/clients/ethereum" "github.com/multiversx/mx-bridge-eth-go/core/batchProcessor" "github.com/multiversx/mx-chain-core-go/core/check" + logger "github.com/multiversx/mx-chain-logger-go" ) var zero = big.NewInt(0) @@ -20,6 +22,7 @@ type ArgsMigrationBatchCreator struct { Erc20ContractsHolder Erc20ContractsHolder SafeContractAddress common.Address SafeContractWrapper SafeContractWrapper + Logger logger.Logger } type migrationBatchCreator struct { @@ -27,6 +30,7 @@ type migrationBatchCreator struct { erc20ContractsHolder Erc20ContractsHolder safeContractAddress common.Address safeContractWrapper SafeContractWrapper + logger logger.Logger } // NewMigrationBatchCreator creates a new instance of type migrationBatchCreator that is able to generate the migration batch output file @@ -40,17 +44,23 @@ func NewMigrationBatchCreator(args ArgsMigrationBatchCreator) (*migrationBatchCr if check.IfNilReflect(args.SafeContractWrapper) { return nil, errNilSafeContractWrapper } + if check.IfNil(args.Logger) { + return nil, errNilLogger + } return &migrationBatchCreator{ mvxDataGetter: args.MvxDataGetter, erc20ContractsHolder: args.Erc20ContractsHolder, safeContractAddress: args.SafeContractAddress, safeContractWrapper: args.SafeContractWrapper, + logger: args.Logger, }, nil } // CreateBatchInfo creates an instance of type BatchInfo func (creator *migrationBatchCreator) CreateBatchInfo(ctx context.Context, newSafeAddress common.Address) (*BatchInfo, error) { + creator.logger.Info("started the batch creation process...") + batchesCount, err := creator.safeContractWrapper.BatchesCount(&bind.CallOpts{Context: ctx}) if err != nil { return nil, err @@ -61,21 +71,29 @@ func (creator *migrationBatchCreator) CreateBatchInfo(ctx context.Context, newSa return nil, err } + creator.logger.Info("fetched Ethereum contracts state", "batches count", batchesCount, "deposits count", depositsCount) + tokensList, err := creator.getTokensList(ctx) if err != nil { return nil, err } + creator.logger.Info("fetched known tokens", "tokens", strings.Join(tokensList, ", ")) + deposits, err := creator.fetchERC20ContractsAddresses(ctx, tokensList, depositsCount) if err != nil { return nil, err } + creator.logger.Info("fetched ERC20 contract addresses") + err = creator.fetchBalances(ctx, deposits) if err != nil { return nil, err } + creator.logger.Info("fetched balances contract addresses") + return creator.assembleBatchInfo(batchesCount, deposits, newSafeAddress) } diff --git a/executors/ethereum/migrationBatchCreator_test.go b/executors/ethereum/migrationBatchCreator_test.go index 801e2465..77c97056 100644 --- a/executors/ethereum/migrationBatchCreator_test.go +++ b/executors/ethereum/migrationBatchCreator_test.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/multiversx/mx-bridge-eth-go/testsCommon/bridge" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/stretchr/testify/assert" ) @@ -37,6 +38,7 @@ func createMockArgsForMigrationBatchCreator() ArgsMigrationBatchCreator { Erc20ContractsHolder: &bridge.ERC20ContractsHolderStub{}, SafeContractAddress: safeContractAddress, SafeContractWrapper: &bridge.SafeContractWrapperStub{}, + Logger: &testscommon.LoggerStub{}, } } @@ -73,6 +75,16 @@ func TestNewMigrationBatchCreator(t *testing.T) { assert.Nil(t, creator) assert.Equal(t, errNilSafeContractWrapper, err) }) + t.Run("nil logger should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsForMigrationBatchCreator() + args.Logger = nil + + creator, err := NewMigrationBatchCreator(args) + assert.Nil(t, creator) + assert.Equal(t, errNilLogger, err) + }) t.Run("should work", func(t *testing.T) { t.Parallel() From d2761700ac0fa5f1498798efcb93d1fcadfdcdd0 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 6 Sep 2024 11:41:41 +0300 Subject: [PATCH 3/3] - minor config fix --- cmd/migration/config/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/migration/config/config.toml b/cmd/migration/config/config.toml index e2e13976..801ac522 100644 --- a/cmd/migration/config/config.toml +++ b/cmd/migration/config/config.toml @@ -26,7 +26,7 @@ # valid options for ProxyRestAPIEntityType are "observer" and "proxy". Any other value will trigger an error. # "observer" is useful when querying an observer, directly and "proxy" is useful when querying a squad's proxy (gateway) - RestAPIEntityType = "proxy" + RestAPIEntityType = "observer" FinalityCheck = true MaxNoncesDelta = 7 # the number of maximum blocks allowed to be "in front" of what the metachain has notarized