Skip to content

Commit

Permalink
- finished the refactor for the SC executor (part 3)
Browse files Browse the repository at this point in the history
  • Loading branch information
iulianpascalau committed Dec 27, 2024
1 parent 2eb7c1e commit 132992f
Show file tree
Hide file tree
Showing 15 changed files with 993 additions and 256 deletions.
2 changes: 1 addition & 1 deletion cmd/scCallsExecutor/config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
PollingIntervalInMillis = 6000

[RefundExecutor]
GasToExecute = 20000000
GasToExecute = 30000000
PollingIntervalInMillis = 6000

[Filter]
Expand Down
81 changes: 81 additions & 0 deletions executors/multiversx/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package multiversx

import (
"context"
"fmt"
"strings"

bridgeCore "github.com/multiversx/mx-bridge-eth-go/core"
"github.com/multiversx/mx-chain-core-go/core/check"
logger "github.com/multiversx/mx-chain-logger-go"
"github.com/multiversx/mx-sdk-go/data"
)

type baseExecutor struct {
scProxyBech32Addresses []string
proxy Proxy
transactionExecutor TransactionExecutor
codec Codec
filter ScCallsExecuteFilter
log logger.Logger
}

func (executor *baseExecutor) checkBaseComponents() error {
if check.IfNil(executor.proxy) {
return errNilProxy
}
if check.IfNil(executor.transactionExecutor) {
return errNilTransactionExecutor
}
if check.IfNil(executor.codec) {
return errNilCodec
}
if check.IfNil(executor.filter) {
return errNilFilter
}
if check.IfNil(executor.log) {
return errNilLogger
}

if len(executor.scProxyBech32Addresses) == 0 {
return errEmptyListOfBridgeSCProxy
}

for _, scProxyAddress := range executor.scProxyBech32Addresses {
_, err := data.NewAddressFromBech32String(scProxyAddress)
if err != nil {
return fmt.Errorf("%w for address %s", err, scProxyAddress)
}
}

return nil
}

func (executor *baseExecutor) executeOnAllScProxyAddress(ctx context.Context, handler func(ctx context.Context, address string) error) error {
errorStrings := make([]string, 0)
for _, scProxyAddress := range executor.scProxyBech32Addresses {
err := handler(ctx, scProxyAddress)
if err != nil {
errorStrings = append(errorStrings, err.Error())
}
}

if len(errorStrings) == 0 {
return nil
}

return fmt.Errorf("errors found during execution: %s", strings.Join(errorStrings, "\n"))
}

func (executor *baseExecutor) filterOperations(component string, pendingOperations map[uint64]bridgeCore.ProxySCCompleteCallData) map[uint64]bridgeCore.ProxySCCompleteCallData {
result := make(map[uint64]bridgeCore.ProxySCCompleteCallData)
for id, callData := range pendingOperations {
if executor.filter.ShouldExecute(callData) {
result[id] = callData
}
}

executor.log.Debug(component, "input pending ops", len(pendingOperations), "result pending ops", len(result))

return result
}
1 change: 0 additions & 1 deletion executors/multiversx/module/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,5 @@ type pollingHandler interface {

type executor interface {
Execute(ctx context.Context) error
GetNumSentTransaction() uint32
IsInterfaceNil() bool
}
204 changes: 152 additions & 52 deletions executors/multiversx/module/scCallsModule.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,118 +23,218 @@ var keyGen = signing.NewKeyGenerator(suite)
var singleSigner = &singlesig.Ed25519Signer{}

type scCallsModule struct {
nonceTxsHandler nonceTransactionsHandler
pollingHandler pollingHandler
executorInstance executor
cfg config.ScCallsModuleConfig
log logger.Logger
filter multiversx.ScCallsExecuteFilter
proxy multiversx.Proxy
nonceTxsHandler nonceTransactionsHandler
txExecutor multiversx.TransactionExecutor

pollingHandlers []pollingHandler
executors []executor
}

// NewScCallsModule creates a starts a new scCallsModule instance
func NewScCallsModule(cfg config.ScCallsModuleConfig, log logger.Logger, chCloseApp chan struct{}) (*scCallsModule, error) {
filter, err := filters.NewPendingOperationFilter(cfg.Filter, log)
module := &scCallsModule{
cfg: cfg,
log: log,
}

err := module.createFilter()
if err != nil {
return nil, err
}

argsProxy := blockchain.ArgsProxy{
ProxyURL: cfg.General.NetworkAddress,
SameScState: false,
ShouldBeSynced: false,
FinalityCheck: cfg.General.ProxyFinalityCheck,
AllowedDeltaToFinal: cfg.General.ProxyMaxNoncesDelta,
CacheExpirationTime: time.Second * time.Duration(cfg.General.ProxyCacherExpirationSeconds),
EntityType: sdkCore.RestAPIEntityType(cfg.General.ProxyRestAPIEntityType),
err = module.createProxy()
if err != nil {
return nil, err
}

proxy, err := blockchain.NewProxy(argsProxy)
err = module.createNonceTxHandler()
if err != nil {
return nil, err
}

module := &scCallsModule{}
err = module.createTransactionExecutor(chCloseApp)
if err != nil {
return nil, err
}

argNonceHandler := nonceHandlerV2.ArgsNonceTransactionsHandlerV2{
Proxy: proxy,
IntervalToResend: time.Second * time.Duration(cfg.General.IntervalToResendTxsInSeconds),
err = module.createScCallsExecutor()
if err != nil {
return nil, err
}
module.nonceTxsHandler, err = nonceHandlerV2.NewNonceTransactionHandlerV2(argNonceHandler)

err = module.createRefundExecutor()
if err != nil {
return nil, err
}

return module, nil
}

func (module *scCallsModule) createFilter() error {
var err error
module.filter, err = filters.NewPendingOperationFilter(module.cfg.Filter, module.log)

return err
}

func (module *scCallsModule) createProxy() error {
argsProxy := blockchain.ArgsProxy{
ProxyURL: module.cfg.General.NetworkAddress,
SameScState: false,
ShouldBeSynced: false,
FinalityCheck: module.cfg.General.ProxyFinalityCheck,
AllowedDeltaToFinal: module.cfg.General.ProxyMaxNoncesDelta,
CacheExpirationTime: time.Second * time.Duration(module.cfg.General.ProxyCacherExpirationSeconds),
EntityType: sdkCore.RestAPIEntityType(module.cfg.General.ProxyRestAPIEntityType),
}

var err error
module.proxy, err = blockchain.NewProxy(argsProxy)

return err
}

func (module *scCallsModule) createNonceTxHandler() error {
argNonceHandler := nonceHandlerV2.ArgsNonceTransactionsHandlerV2{
Proxy: module.proxy,
IntervalToResend: time.Second * time.Duration(module.cfg.General.IntervalToResendTxsInSeconds),
}

var err error
module.nonceTxsHandler, err = nonceHandlerV2.NewNonceTransactionHandlerV2(argNonceHandler)

return err
}

func (module *scCallsModule) createTransactionExecutor(chCloseApp chan struct{}) error {
wallet := interactors.NewWallet()
multiversXPrivateKeyBytes, err := wallet.LoadPrivateKeyFromPemFile(cfg.General.PrivateKeyFile)
multiversXPrivateKeyBytes, err := wallet.LoadPrivateKeyFromPemFile(module.cfg.General.PrivateKeyFile)
if err != nil {
return nil, err
return err
}

privateKey, err := keyGen.PrivateKeyFromByteArray(multiversXPrivateKeyBytes)
if err != nil {
return nil, err
return err
}

argsTxExecutor := multiversx.ArgsTransactionExecutor{
Proxy: proxy,
Log: log,
Proxy: module.proxy,
Log: module.log,
NonceTxHandler: module.nonceTxsHandler,
PrivateKey: privateKey,
SingleSigner: singleSigner,
TransactionChecks: cfg.TransactionChecks,
TransactionChecks: module.cfg.TransactionChecks,
CloseAppChan: chCloseApp,
}

transactionExecutor, err := multiversx.NewTransactionExecutor(argsTxExecutor)
if err != nil {
return nil, err
}
module.txExecutor, err = multiversx.NewTransactionExecutor(argsTxExecutor)

return err
}

func (module *scCallsModule) createScCallsExecutor() error {
argsExecutor := multiversx.ArgsScCallExecutor{
ScProxyBech32Addresses: cfg.General.ScProxyBech32Addresses,
TransactionExecutor: transactionExecutor,
Proxy: proxy,
ScProxyBech32Addresses: module.cfg.General.ScProxyBech32Addresses,
TransactionExecutor: module.txExecutor,
Proxy: module.proxy,
Codec: &parsers.MultiversxCodec{},
Filter: filter,
Log: log,
ExecutorConfig: cfg.ScCallsExecutor,
TransactionChecks: cfg.TransactionChecks,
Filter: module.filter,
Log: module.log,
ExecutorConfig: module.cfg.ScCallsExecutor,
}
module.executorInstance, err = multiversx.NewScCallExecutor(argsExecutor)

executorInstance, err := multiversx.NewScCallExecutor(argsExecutor)
if err != nil {
return nil, err
return err
}
module.executors = append(module.executors, executorInstance)

argsPollingHandler := polling.ArgsPollingHandler{
Log: log,
Log: module.log,
Name: "MultiversX SC calls",
PollingInterval: time.Duration(cfg.ScCallsExecutor.PollingIntervalInMillis) * time.Millisecond,
PollingWhenError: time.Duration(cfg.ScCallsExecutor.PollingIntervalInMillis) * time.Millisecond,
Executor: module.executorInstance,
PollingInterval: time.Duration(module.cfg.ScCallsExecutor.PollingIntervalInMillis) * time.Millisecond,
PollingWhenError: time.Duration(module.cfg.ScCallsExecutor.PollingIntervalInMillis) * time.Millisecond,
Executor: executorInstance,
}

module.pollingHandler, err = polling.NewPollingHandler(argsPollingHandler)
pollingHandlerInstance, err := polling.NewPollingHandler(argsPollingHandler)
if err != nil {
return nil, err
return err
}

err = module.pollingHandler.StartProcessingLoop()
err = pollingHandlerInstance.StartProcessingLoop()
if err != nil {
return nil, err
return err
}
module.pollingHandlers = append(module.pollingHandlers, pollingHandlerInstance)

return module, nil
return nil
}

func (module *scCallsModule) createRefundExecutor() error {
argsExecutor := multiversx.ArgsRefundExecutor{
ScProxyBech32Addresses: module.cfg.General.ScProxyBech32Addresses,
TransactionExecutor: module.txExecutor,
Proxy: module.proxy,
Codec: &parsers.MultiversxCodec{},
Filter: module.filter,
Log: module.log,
GasToExecute: module.cfg.RefundExecutor.GasToExecute,
}

executorInstance, err := multiversx.NewRefundExecutor(argsExecutor)
if err != nil {
return err
}
module.executors = append(module.executors, executorInstance)

argsPollingHandler := polling.ArgsPollingHandler{
Log: module.log,
Name: "MultiversX refund executor",
PollingInterval: time.Duration(module.cfg.RefundExecutor.PollingIntervalInMillis) * time.Millisecond,
PollingWhenError: time.Duration(module.cfg.RefundExecutor.PollingIntervalInMillis) * time.Millisecond,
Executor: executorInstance,
}

pollingHandlerInstance, err := polling.NewPollingHandler(argsPollingHandler)
if err != nil {
return err
}

err = pollingHandlerInstance.StartProcessingLoop()
if err != nil {
return err
}
module.pollingHandlers = append(module.pollingHandlers, pollingHandlerInstance)

return nil
}

// GetNumSentTransaction returns the total sent transactions
func (module *scCallsModule) GetNumSentTransaction() uint32 {
return module.executorInstance.GetNumSentTransaction()
return module.txExecutor.GetNumSentTransaction()
}

// Close closes any components started
func (module *scCallsModule) Close() error {
errPollingHandler := module.pollingHandler.Close()
errNonceTxsHandler := module.nonceTxsHandler.Close()
var lastError error

if errPollingHandler != nil {
return errPollingHandler
for _, handlers := range module.pollingHandlers {
err := handlers.Close()
if err != nil {
lastError = err
}
}
return errNonceTxsHandler

err := module.nonceTxsHandler.Close()
if err != nil {
lastError = err
}

return lastError
}
Loading

0 comments on commit 132992f

Please sign in to comment.