diff --git a/executors/multiversx/module/errors.go b/executors/multiversx/module/errors.go new file mode 100644 index 00000000..4222d4f1 --- /dev/null +++ b/executors/multiversx/module/errors.go @@ -0,0 +1,7 @@ +package module + +import "errors" + +var ( + errNilProxy = errors.New("nil proxy") +) diff --git a/executors/multiversx/module/scCallsModule.go b/executors/multiversx/module/scCallsModule.go index 19d2ff1b..e120e412 100644 --- a/executors/multiversx/module/scCallsModule.go +++ b/executors/multiversx/module/scCallsModule.go @@ -7,12 +7,11 @@ import ( "github.com/multiversx/mx-bridge-eth-go/executors/multiversx" "github.com/multiversx/mx-bridge-eth-go/executors/multiversx/filters" "github.com/multiversx/mx-bridge-eth-go/parsers" + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-crypto-go/signing" "github.com/multiversx/mx-chain-crypto-go/signing/ed25519" "github.com/multiversx/mx-chain-crypto-go/signing/ed25519/singlesig" logger "github.com/multiversx/mx-chain-logger-go" - "github.com/multiversx/mx-sdk-go/blockchain" - sdkCore "github.com/multiversx/mx-sdk-go/core" "github.com/multiversx/mx-sdk-go/core/polling" "github.com/multiversx/mx-sdk-go/interactors" "github.com/multiversx/mx-sdk-go/interactors/nonceHandlerV2" @@ -29,26 +28,30 @@ type scCallsModule struct { } // NewScCallsModule creates a starts a new scCallsModule instance -func NewScCallsModule(cfg config.ScCallsModuleConfig, log logger.Logger, chCloseApp chan struct{}) (*scCallsModule, error) { +func NewScCallsModule(cfg config.ScCallsModuleConfig, proxy multiversx.Proxy, log logger.Logger, chCloseApp chan struct{}) (*scCallsModule, error) { filter, err := filters.NewPendingOperationFilter(cfg.Filter, log) if err != nil { return nil, err } - - argsProxy := blockchain.ArgsProxy{ - ProxyURL: cfg.NetworkAddress, - SameScState: false, - ShouldBeSynced: false, - FinalityCheck: cfg.ProxyFinalityCheck, - AllowedDeltaToFinal: cfg.ProxyMaxNoncesDelta, - CacheExpirationTime: time.Second * time.Duration(cfg.ProxyCacherExpirationSeconds), - EntityType: sdkCore.RestAPIEntityType(cfg.ProxyRestAPIEntityType), + if check.IfNil(proxy) { + return nil, errNilProxy //TODO: add unit test for this } - proxy, err := blockchain.NewProxy(argsProxy) - if err != nil { - return nil, err - } + //TODO: move this where necessary + //argsProxy := blockchain.ArgsProxy{ + // ProxyURL: cfg.NetworkAddress, + // SameScState: false, + // ShouldBeSynced: false, + // FinalityCheck: cfg.ProxyFinalityCheck, + // AllowedDeltaToFinal: cfg.ProxyMaxNoncesDelta, + // CacheExpirationTime: time.Second * time.Duration(cfg.ProxyCacherExpirationSeconds), + // EntityType: sdkCore.RestAPIEntityType(cfg.ProxyRestAPIEntityType), + //} + // + //proxy, err := blockchain.NewProxy(argsProxy) + //if err != nil { + // return nil, err + //} module := &scCallsModule{} diff --git a/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go b/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go index 923e22e5..b1b835f4 100644 --- a/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go +++ b/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go @@ -19,6 +19,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/multiversx/mx-bridge-eth-go/integrationTests/mock" "github.com/multiversx/mx-bridge-eth-go/integrationTests/relayers/slowTests/framework" + "github.com/multiversx/mx-chain-core-go/data/transaction" logger "github.com/multiversx/mx-chain-logger-go" "github.com/multiversx/mx-sdk-go/data" "github.com/stretchr/testify/assert" @@ -198,7 +199,19 @@ func testRelayersWithChainSimulatorAndTokens(tb testing.TB, manualStopChan chan } } + firstProcessRun := true processFunc := func(tb testing.TB, setup *framework.TestSetup) bool { + if firstProcessRun { + firstProcessRun = false + + //TODO: remove this example + setup.ProxyWrapperInstance.RegisterBeforeTransactionSendHandler(func(tx *transaction.FrontendTransaction) { + if tx.Sender == setup.MultiversxHandler.SCExecutorKeys.MvxAddress.Bech32() { + log.Info("BEFORE SENDING a SC executor transaction. TODO: add more logic") + } + }) + } + allFlowsFinished := true for _, flow := range flows { allFlowsFinished = allFlowsFinished && flow.process() diff --git a/integrationTests/relayers/slowTests/framework/proxyWrapper.go b/integrationTests/relayers/slowTests/framework/proxyWrapper.go new file mode 100644 index 00000000..4d5b9139 --- /dev/null +++ b/integrationTests/relayers/slowTests/framework/proxyWrapper.go @@ -0,0 +1,62 @@ +package framework + +import ( + "context" + "sync" + + "github.com/multiversx/mx-bridge-eth-go/clients/multiversx" + "github.com/multiversx/mx-chain-core-go/data/transaction" +) + +type proxyWrapper struct { + multiversx.Proxy + + mutHandlers sync.RWMutex + beforeTxSendHandlers []func(tx *transaction.FrontendTransaction) +} + +// NewProxyWrapper will create a wrapper over the provided proxy +func NewProxyWrapper(proxy multiversx.Proxy) *proxyWrapper { + return &proxyWrapper{ + Proxy: proxy, + } +} + +// SendTransaction is a wrapper over the send transaction original functionality +func (wrapper *proxyWrapper) SendTransaction(ctx context.Context, tx *transaction.FrontendTransaction) (string, error) { + wrapper.callBeforeTransactionSendHandlers(tx) + + return wrapper.Proxy.SendTransaction(ctx, tx) +} + +// SendTransactions is a wrapper over the send transactions original functionality +func (wrapper *proxyWrapper) SendTransactions(ctx context.Context, txs []*transaction.FrontendTransaction) ([]string, error) { + for _, tx := range txs { + wrapper.callBeforeTransactionSendHandlers(tx) + } + + return wrapper.Proxy.SendTransactions(ctx, txs) +} + +func (wrapper *proxyWrapper) callBeforeTransactionSendHandlers(tx *transaction.FrontendTransaction) { + if tx == nil { + return + } + + wrapper.mutHandlers.RLock() + for _, handler := range wrapper.beforeTxSendHandlers { + handler(tx) + } + wrapper.mutHandlers.RUnlock() +} + +// RegisterBeforeTransactionSendHandler will register the handler to be called before a transaction is being sent +func (wrapper *proxyWrapper) RegisterBeforeTransactionSendHandler(handler func(tx *transaction.FrontendTransaction)) { + if handler == nil { + return + } + + wrapper.mutHandlers.Lock() + wrapper.beforeTxSendHandlers = append(wrapper.beforeTxSendHandlers, handler) + wrapper.mutHandlers.Unlock() +} diff --git a/integrationTests/relayers/slowTests/framework/testSetup.go b/integrationTests/relayers/slowTests/framework/testSetup.go index 960c8ee5..eea09f76 100644 --- a/integrationTests/relayers/slowTests/framework/testSetup.go +++ b/integrationTests/relayers/slowTests/framework/testSetup.go @@ -10,10 +10,12 @@ import ( "sync" "sync/atomic" "testing" + "time" "github.com/ethereum/go-ethereum/common" "github.com/multiversx/mx-bridge-eth-go/config" "github.com/multiversx/mx-bridge-eth-go/executors/multiversx/module" + "github.com/multiversx/mx-sdk-go/blockchain" sdkCore "github.com/multiversx/mx-sdk-go/core" "github.com/stretchr/testify/require" ) @@ -41,6 +43,7 @@ type TestSetup struct { ChainSimulator ChainSimulatorWrapper ScCallerKeys KeysHolder ScCallerModuleInstance SCCallerModule + ProxyWrapperInstance *proxyWrapper ctxCancel func() Ctx context.Context @@ -141,8 +144,22 @@ func (setup *TestSetup) startScCallerModule() { }, } - var err error - setup.ScCallerModuleInstance, err = module.NewScCallsModule(cfg, log, nil) + argsProxy := blockchain.ArgsProxy{ + ProxyURL: cfg.NetworkAddress, + SameScState: false, + ShouldBeSynced: false, + FinalityCheck: cfg.ProxyFinalityCheck, + AllowedDeltaToFinal: cfg.ProxyMaxNoncesDelta, + CacheExpirationTime: time.Second * time.Duration(cfg.ProxyCacherExpirationSeconds), + EntityType: sdkCore.RestAPIEntityType(cfg.ProxyRestAPIEntityType), + } + + proxy, err := blockchain.NewProxy(argsProxy) + require.Nil(setup, err) + + setup.ProxyWrapperInstance = NewProxyWrapper(proxy) + + setup.ScCallerModuleInstance, err = module.NewScCallsModule(cfg, setup.ProxyWrapperInstance, log, nil) require.Nil(setup, err) log.Info("started SC calls module", "monitoring SC proxy address", setup.MultiversxHandler.ScProxyAddress) }