Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added TTL for failed executed operations based on IDs #405

Open
wants to merge 3 commits into
base: feat/v3.1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions cmd/scCallsExecutor/config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
MaxGasLimitToUse = 249999999 # this is a safe max gas limit to use both intra-shard & cross-shard
GasLimitForOutOfGasTransactions = 30000000 # this value will be used when a transaction specified a gas limit > 249999999
PollingIntervalInMillis = 6000
TTLForFailedRefundIdInSeconds = 3600

[RefundExecutor]
GasToExecute = 30000000
PollingIntervalInMillis = 6000
TTLForFailedRefundIdInSeconds = 86400

[Filter]
AllowedEthAddresses = ["*"] # execute SC calls from all ETH addresses
Expand All @@ -30,9 +32,5 @@
LogFileLifeSpanInMB = 1024 # 1GB

[TransactionChecks]
CheckTransactionResults = true # enable or disable the transaction execution checking
TimeInSecondsBetweenChecks = 6 # the number of seconds to recheck the status of the transaction
ExecutionTimeoutInSeconds = 120 # the number of seconds reserved for each execution to complete
CloseAppOnError = false # enable or disable if the executor should automatically close on a transaction execution error
ExtraDelayInSecondsOnError = 300 # extra delay in seconds if the transaction execution errored

12 changes: 4 additions & 8 deletions cmd/scCallsExecutor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,21 +106,17 @@ func startExecutor(ctx *cli.Context, version string) error {
return fmt.Errorf("empty NetworkAddress in config file")
}

chCloseApp := make(chan struct{}, 1)
scCallsExecutor, err := module.NewScCallsModule(cfg, log, chCloseApp)
scCallsExecutor, err := module.NewScCallsModule(cfg, log)
if err != nil {
return err
}

sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

select {
case <-sigs:
log.Info("application closing by user error input, calling Close on all subcomponents...")
case <-chCloseApp:
log.Info("application closing, requested internally, calling Close on all subcomponents...")
}
<-sigs

log.Info("application closing by user error input, calling Close on all subcomponents...")

return scCallsExecutor.Close()
}
Expand Down
9 changes: 4 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,21 +225,20 @@ type ScCallsExecutorConfig struct {
MaxGasLimitToUse uint64
GasLimitForOutOfGasTransactions uint64
PollingIntervalInMillis uint64
TTLForFailedRefundIdInSeconds uint64
}

// RefundExecutorConfig will hold the settings for the refund executor
type RefundExecutorConfig struct {
GasToExecute uint64
PollingIntervalInMillis uint64
GasToExecute uint64
PollingIntervalInMillis uint64
TTLForFailedRefundIdInSeconds uint64
}

// TransactionChecksConfig will hold the setting for how to handle the transaction execution
type TransactionChecksConfig struct {
CheckTransactionResults bool
TimeInSecondsBetweenChecks uint64
ExecutionTimeoutInSeconds uint64
CloseAppOnError bool
ExtraDelayInSecondsOnError uint64
}

// MigrationToolConfig is the migration tool config struct
Expand Down
16 changes: 7 additions & 9 deletions config/tomlConfigs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,12 @@ func TestScCallsExecutorConfigs(t *testing.T) {
MaxGasLimitToUse: 249999999,
GasLimitForOutOfGasTransactions: 30000000,
PollingIntervalInMillis: 6000,
TTLForFailedRefundIdInSeconds: 3600,
},
RefundExecutor: RefundExecutorConfig{
GasToExecute: 20000000,
PollingIntervalInMillis: 6000,
GasToExecute: 20000000,
PollingIntervalInMillis: 6000,
TTLForFailedRefundIdInSeconds: 86400,
},
Filter: PendingOperationsFilterConfig{
AllowedEthAddresses: []string{"*"},
Expand All @@ -453,11 +455,8 @@ func TestScCallsExecutorConfigs(t *testing.T) {
LogFileLifeSpanInMB: 1024,
},
TransactionChecks: TransactionChecksConfig{
CheckTransactionResults: true,
TimeInSecondsBetweenChecks: 6,
ExecutionTimeoutInSeconds: 120,
CloseAppOnError: false,
ExtraDelayInSecondsOnError: 120,
},
}

Expand All @@ -480,10 +479,12 @@ func TestScCallsExecutorConfigs(t *testing.T) {
MaxGasLimitToUse = 249999999 # this is a safe max gas limit to use both intra-shard & cross-shard
GasLimitForOutOfGasTransactions = 30000000 # this value will be used when a transaction specified a gas limit > 249999999
PollingIntervalInMillis = 6000
TTLForFailedRefundIdInSeconds = 3600

[RefundExecutor]
GasToExecute = 20000000
PollingIntervalInMillis = 6000
TTLForFailedRefundIdInSeconds = 86400

[Filter]
AllowedEthAddresses = ["*"] # execute SC calls from all ETH addresses
Expand All @@ -495,11 +496,8 @@ func TestScCallsExecutorConfigs(t *testing.T) {
LogFileLifeSpanInMB = 1024 # 1GB

[TransactionChecks]
CheckTransactionResults = true # enable or disable the transaction execution checking
TimeInSecondsBetweenChecks = 6 # the number of seconds to recheck the status of the transaction
ExecutionTimeoutInSeconds = 120 # the number of seconds after the transaction is considered failed if it was not seen by the blockchain
CloseAppOnError = false # enable or disable if the executor should automatically close on a transaction execution error
ExtraDelayInSecondsOnError = 120 # extra delay in seconds if the transaction execution errored
ExecutionTimeoutInSeconds = 120 # the number of seconds after the transaction is considered failed if it was not seen by the blockchain
`

cfg := ScCallsModuleConfig{}
Expand Down
51 changes: 49 additions & 2 deletions executors/multiversx/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"fmt"
"strings"
"sync"
"time"

bridgeCore "github.com/multiversx/mx-bridge-eth-go/core"
"github.com/multiversx/mx-bridge-eth-go/errors"
Expand All @@ -12,13 +14,20 @@ import (
"github.com/multiversx/mx-sdk-go/data"
)

const (
minTTLForFailedRefundID = time.Second
)

type baseExecutor struct {
scProxyBech32Addresses []string
proxy Proxy
transactionExecutor TransactionExecutor
codec Codec
filter ScCallsExecuteFilter
log logger.Logger
ttlForFailedRefundID time.Duration
mutFailedRefundMap sync.RWMutex
failedRefundMap map[uint64]time.Time
}

func (executor *baseExecutor) checkBaseComponents() error {
Expand All @@ -37,6 +46,9 @@ func (executor *baseExecutor) checkBaseComponents() error {
if check.IfNil(executor.log) {
return errNilLogger
}
if executor.ttlForFailedRefundID < minTTLForFailedRefundID {
return fmt.Errorf("%w for TTLForFailedRefundID: provided: %v, absolute minimum required: %v", errInvalidValue, executor.ttlForFailedRefundID, minTTLForFailedRefundID)
}

if len(executor.scProxyBech32Addresses) == 0 {
return errEmptyListOfBridgeSCProxy
Expand Down Expand Up @@ -71,16 +83,51 @@ func (executor *baseExecutor) executeOnAllScProxyAddress(ctx context.Context, ha
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
if !executor.filter.ShouldExecute(callData) {
continue
}
if executor.isFailed(id) {
continue
}

result[id] = callData
}

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

return result
}

func (executor *baseExecutor) isFailed(id uint64) bool {
executor.mutFailedRefundMap.RLock()
defer executor.mutFailedRefundMap.RUnlock()

_, found := executor.failedRefundMap[id]
return found
}

func (executor *baseExecutor) addFailed(id uint64) {
executor.mutFailedRefundMap.Lock()
defer executor.mutFailedRefundMap.Unlock()

executor.failedRefundMap[id] = time.Now()
}

func (executor *baseExecutor) cleanupTTLCache(source string) {
executor.mutFailedRefundMap.Lock()
defer executor.mutFailedRefundMap.Unlock()

for id, insertedTime := range executor.failedRefundMap {
if insertedTime.Add(executor.ttlForFailedRefundID).Unix() < time.Now().Unix() {
executor.log.Debug("TTL expired, remove from cache",
"ID", id,
"executor", source,
"TTL", executor.ttlForFailedRefundID)
delete(executor.failedRefundMap, id)
}
}
}

func (executor *baseExecutor) executeVmQuery(ctx context.Context, scProxyAddress string, function string) (*data.VmValuesResponseData, error) {
request := &data.VmValueRequest{
Address: scProxyAddress,
Expand Down
9 changes: 4 additions & 5 deletions executors/multiversx/module/scCallsModule.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ 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, log logger.Logger) (*scCallsModule, error) {
module := &scCallsModule{
cfg: cfg,
log: log,
Expand All @@ -56,7 +56,7 @@ func NewScCallsModule(cfg config.ScCallsModuleConfig, log logger.Logger, chClose
return nil, err
}

err = module.createTransactionExecutor(chCloseApp)
err = module.createTransactionExecutor()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -110,7 +110,7 @@ func (module *scCallsModule) createNonceTxHandler() error {
return err
}

func (module *scCallsModule) createTransactionExecutor(chCloseApp chan struct{}) error {
func (module *scCallsModule) createTransactionExecutor() error {
wallet := interactors.NewWallet()
multiversXPrivateKeyBytes, err := wallet.LoadPrivateKeyFromPemFile(module.cfg.General.PrivateKeyFile)
if err != nil {
Expand All @@ -129,7 +129,6 @@ func (module *scCallsModule) createTransactionExecutor(chCloseApp chan struct{})
PrivateKey: privateKey,
SingleSigner: singleSigner,
TransactionChecks: module.cfg.TransactionChecks,
CloseAppChan: chCloseApp,
}

module.txExecutor, err = multiversx.NewTransactionExecutor(argsTxExecutor)
Expand Down Expand Up @@ -184,7 +183,7 @@ func (module *scCallsModule) createRefundExecutor() error {
Codec: &parsers.MultiversxCodec{},
Filter: module.filter,
Log: module.log,
GasToExecute: module.cfg.RefundExecutor.GasToExecute,
RefundConfig: module.cfg.RefundExecutor,
}

executorInstance, err := multiversx.NewRefundExecutor(argsExecutor)
Expand Down
Loading
Loading