diff --git a/factory/interface.go b/factory/interface.go index ae3435e6..e4a22950 100644 --- a/factory/interface.go +++ b/factory/interface.go @@ -1,5 +1,9 @@ package factory +import ( + "github.com/multiversx/mx-chain-proxy-go/process" +) + // ComponentHandler defines the actions common to all component handlers type ComponentHandler interface { Create() error @@ -16,6 +20,7 @@ type RunTypeComponentsHandler interface { // RunTypeComponentsHolder holds the run type components type RunTypeComponentsHolder interface { + TxNotarizationCheckerHandlerCreator() process.TxNotarizationCheckerHandler Create() error Close() error CheckSubcomponents() error diff --git a/factory/runType/runTypeComponents.go b/factory/runType/runTypeComponents.go index c960293b..db4a7a5f 100644 --- a/factory/runType/runTypeComponents.go +++ b/factory/runType/runTypeComponents.go @@ -1,6 +1,12 @@ package runType -type runTypeComponents struct{} +import ( + "github.com/multiversx/mx-chain-proxy-go/process" +) + +type runTypeComponents struct { + txNotarizationCheckerHandlerCreator process.TxNotarizationCheckerHandler +} // Close does nothing func (rtc *runTypeComponents) Close() error { diff --git a/factory/runType/runTypeComponentsFactory.go b/factory/runType/runTypeComponentsFactory.go index 24ad9f56..30ec5f53 100644 --- a/factory/runType/runTypeComponentsFactory.go +++ b/factory/runType/runTypeComponentsFactory.go @@ -1,5 +1,9 @@ package runType +import ( + "github.com/multiversx/mx-chain-proxy-go/process/factory" +) + type runTypeComponentsFactory struct{} // NewRunTypeComponentsFactory will return a new instance of run type components factory @@ -9,7 +13,9 @@ func NewRunTypeComponentsFactory() *runTypeComponentsFactory { // Create will create the run type components func (rtcf *runTypeComponentsFactory) Create() *runTypeComponents { - return &runTypeComponents{} + return &runTypeComponents{ + txNotarizationCheckerHandlerCreator: factory.NewTxNotarizationChecker(), + } } // IsInterfaceNil returns true if there is no value under the interface diff --git a/factory/runType/runTypeComponentsHandler.go b/factory/runType/runTypeComponentsHandler.go index 0f2424d0..b098f309 100644 --- a/factory/runType/runTypeComponentsHandler.go +++ b/factory/runType/runTypeComponentsHandler.go @@ -6,6 +6,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-proxy-go/factory" + "github.com/multiversx/mx-chain-proxy-go/process" ) const runTypeComponentsName = "managedRunTypeComponents" @@ -69,9 +70,24 @@ func (mrtc *managedRunTypeComponents) CheckSubcomponents() error { if check.IfNil(mrtc.runTypeComponents) { return errNilRunTypeComponents } + if check.IfNil(mrtc.txNotarizationCheckerHandlerCreator) { + return process.ErrNilTxNotarizationCheckerHandler + } return nil } +// TxNotarizationCheckerHandlerCreator returns tx notarization checker handler +func (mrtc *managedRunTypeComponents) TxNotarizationCheckerHandlerCreator() process.TxNotarizationCheckerHandler { + mrtc.mutRunTypeCoreComponents.RLock() + defer mrtc.mutRunTypeCoreComponents.RUnlock() + + if check.IfNil(mrtc.runTypeComponents) { + return nil + } + + return mrtc.runTypeComponents.txNotarizationCheckerHandlerCreator +} + // IsInterfaceNil returns true if the interface is nil func (mrtc *managedRunTypeComponents) IsInterfaceNil() bool { return mrtc == nil diff --git a/factory/runType/runTypeComponentsHandler_test.go b/factory/runType/runTypeComponentsHandler_test.go index cfa94cec..3e1991d8 100644 --- a/factory/runType/runTypeComponentsHandler_test.go +++ b/factory/runType/runTypeComponentsHandler_test.go @@ -38,9 +38,13 @@ func TestManagedRunTypeComponents_Create(t *testing.T) { managedRunTypeComponents, err := createComponents() require.NoError(t, err) + require.Nil(t, managedRunTypeComponents.TxNotarizationCheckerHandlerCreator()) + err = managedRunTypeComponents.Create() require.NoError(t, err) + require.NotNil(t, managedRunTypeComponents.TxNotarizationCheckerHandlerCreator()) + require.Equal(t, runTypeComponentsName, managedRunTypeComponents.String()) require.NoError(t, managedRunTypeComponents.Close()) }) @@ -56,6 +60,7 @@ func TestManagedRunTypeComponents_Close(t *testing.T) { require.NoError(t, err) require.NoError(t, managedRunTypeComponents.Close()) + require.Nil(t, managedRunTypeComponents.TxNotarizationCheckerHandlerCreator()) } func TestManagedRunTypeComponents_CheckSubcomponents(t *testing.T) { diff --git a/factory/runType/sovereignRunTypeComponentsFactory.go b/factory/runType/sovereignRunTypeComponentsFactory.go index fd5226a5..33717b36 100644 --- a/factory/runType/sovereignRunTypeComponentsFactory.go +++ b/factory/runType/sovereignRunTypeComponentsFactory.go @@ -1,5 +1,9 @@ package runType +import ( + "github.com/multiversx/mx-chain-proxy-go/process/factory" +) + type sovereignRunTypeComponentsFactory struct{} // NewSovereignRunTypeComponentsFactory will return a new instance of sovereign run type components factory @@ -9,7 +13,9 @@ func NewSovereignRunTypeComponentsFactory() *sovereignRunTypeComponentsFactory { // Create will create the run type components func (srtcf *sovereignRunTypeComponentsFactory) Create() *runTypeComponents { - return &runTypeComponents{} + return &runTypeComponents{ + txNotarizationCheckerHandlerCreator: factory.NewSovereignTxNotarizationChecker(), + } } // IsInterfaceNil returns true if there is no value under the interface diff --git a/process/errors.go b/process/errors.go index 8060b7b4..3f8279a6 100644 --- a/process/errors.go +++ b/process/errors.go @@ -112,3 +112,6 @@ var ErrEmptyPubKey = errors.New("public key is empty") // ErrNilHttpClient signals that a nil http client has been provided var ErrNilHttpClient = errors.New("nil http client") + +// ErrNilTxNotarizationCheckerHandler signals that nil tx notarization checker handler has been provided +var ErrNilTxNotarizationCheckerHandler = errors.New("nil tx notarization checker handler has been provided") diff --git a/process/factory/sovereignTxNotarizationChecker.go b/process/factory/sovereignTxNotarizationChecker.go new file mode 100644 index 00000000..9712861e --- /dev/null +++ b/process/factory/sovereignTxNotarizationChecker.go @@ -0,0 +1,22 @@ +package factory + +import ( + "github.com/multiversx/mx-chain-core-go/data/transaction" +) + +type sovereignTxNotarizationChecker struct{} + +// NewSovereignTxNotarizationChecker creates a new sovereign tx notarization checker +func NewSovereignTxNotarizationChecker() *sovereignTxNotarizationChecker { + return &sovereignTxNotarizationChecker{} +} + +// IsNotarized returns true +func (stnc *sovereignTxNotarizationChecker) IsNotarized(_ transaction.ApiTransactionResult) bool { + return true +} + +// IsInterfaceNil returns true if there is no value under the interface +func (stnc *sovereignTxNotarizationChecker) IsInterfaceNil() bool { + return stnc == nil +} diff --git a/process/factory/sovereignTxNotarizationChecker_test.go b/process/factory/sovereignTxNotarizationChecker_test.go new file mode 100644 index 00000000..25e18504 --- /dev/null +++ b/process/factory/sovereignTxNotarizationChecker_test.go @@ -0,0 +1,23 @@ +package factory + +import ( + "testing" + + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/stretchr/testify/require" +) + +func TestSovereignTxNotarizationChecker(t *testing.T) { + t.Parallel() + + tnc := NewTxNotarizationChecker() + require.False(t, tnc.IsInterfaceNil()) +} + +func TestSovereignTxNotarizationChecker_IsNotarized(t *testing.T) { + t.Parallel() + + tnc := NewTxNotarizationChecker() + isNotarized := tnc.IsNotarized(transaction.ApiTransactionResult{}) + require.True(t, isNotarized) +} diff --git a/process/factory/transactionProcessorFactory.go b/process/factory/transactionProcessorFactory.go index 8f563251..0e46503f 100644 --- a/process/factory/transactionProcessorFactory.go +++ b/process/factory/transactionProcessorFactory.go @@ -41,5 +41,6 @@ func CreateTransactionProcessor( newTxCostProcessor, logsMerger, allowEntireTxPoolFetch, + runTypeComponents.TxNotarizationCheckerHandlerCreator(), ) } diff --git a/process/factory/txNotarizationChecker.go b/process/factory/txNotarizationChecker.go new file mode 100644 index 00000000..5db993f1 --- /dev/null +++ b/process/factory/txNotarizationChecker.go @@ -0,0 +1,22 @@ +package factory + +import ( + "github.com/multiversx/mx-chain-core-go/data/transaction" +) + +type txNotarizationChecker struct{} + +// NewTxNotarizationChecker creates a new tx notarization checker +func NewTxNotarizationChecker() *txNotarizationChecker { + return &txNotarizationChecker{} +} + +// IsNotarized returns if tx is notarized +func (tnc *txNotarizationChecker) IsNotarized(tx transaction.ApiTransactionResult) bool { + return tx.NotarizedAtSourceInMetaNonce > 0 && tx.NotarizedAtDestinationInMetaNonce > 0 +} + +// IsInterfaceNil returns true if there is no value under the interface +func (tnc *txNotarizationChecker) IsInterfaceNil() bool { + return tnc == nil +} diff --git a/process/factory/txNotarizationChecker_test.go b/process/factory/txNotarizationChecker_test.go new file mode 100644 index 00000000..be530ca0 --- /dev/null +++ b/process/factory/txNotarizationChecker_test.go @@ -0,0 +1,34 @@ +package factory + +import ( + "testing" + + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/stretchr/testify/require" +) + +func TestTxNotarizationChecker(t *testing.T) { + t.Parallel() + + tnc := NewTxNotarizationChecker() + require.False(t, tnc.IsInterfaceNil()) +} + +func TestTxNotarizationChecker_IsNotarized(t *testing.T) { + t.Parallel() + + t.Run("tx is notarized", func(t *testing.T) { + tnc := NewTxNotarizationChecker() + tx := transaction.ApiTransactionResult{ + NotarizedAtSourceInMetaNonce: 1, + NotarizedAtDestinationInMetaNonce: 1, + } + isNotarized := tnc.IsNotarized(tx) + require.True(t, isNotarized) + }) + t.Run("tx is not notarized", func(t *testing.T) { + tnc := NewTxNotarizationChecker() + isNotarized := tnc.IsNotarized(transaction.ApiTransactionResult{}) + require.False(t, isNotarized) + }) +} diff --git a/process/interface.go b/process/interface.go index f424bdfc..7e5681f2 100644 --- a/process/interface.go +++ b/process/interface.go @@ -7,6 +7,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-core-go/data/vm" crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-proxy-go/common" "github.com/multiversx/mx-chain-proxy-go/data" "github.com/multiversx/mx-chain-proxy-go/observer" @@ -85,3 +86,9 @@ type StatusMetricsProvider interface { type HttpClient interface { Do(req *http.Request) (*http.Response, error) } + +// TxNotarizationCheckerHandler defines what tx notarization checked should do +type TxNotarizationCheckerHandler interface { + IsNotarized(tx transaction.ApiTransactionResult) bool + IsInterfaceNil() bool +} diff --git a/process/transactionProcessor.go b/process/transactionProcessor.go index b91cf6c2..4c854b7d 100644 --- a/process/transactionProcessor.go +++ b/process/transactionProcessor.go @@ -11,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-proxy-go/api/errors" "github.com/multiversx/mx-chain-proxy-go/data" ) @@ -83,6 +84,7 @@ type TransactionProcessor struct { newTxCostProcessor func() (TransactionCostHandler, error) mergeLogsHandler LogsMergerHandler shouldAllowEntireTxPoolFetch bool + txNotarizationChecker TxNotarizationCheckerHandler } // NewTransactionProcessor creates a new instance of TransactionProcessor @@ -94,6 +96,7 @@ func NewTransactionProcessor( newTxCostProcessor func() (TransactionCostHandler, error), logsMerger LogsMergerHandler, allowEntireTxPoolFetch bool, + txNotarizationChecker TxNotarizationCheckerHandler, ) (*TransactionProcessor, error) { if check.IfNil(proc) { return nil, ErrNilCoreProcessor @@ -113,6 +116,9 @@ func NewTransactionProcessor( if check.IfNil(logsMerger) { return nil, ErrNilLogsMerger } + if check.IfNil(txNotarizationChecker) { + return nil, ErrNilTxNotarizationCheckerHandler + } // no reason to get this from configs. If we are going to change the marshaller for the relayed transaction v1, // we will need also an enable epoch handler @@ -126,6 +132,7 @@ func NewTransactionProcessor( mergeLogsHandler: logsMerger, shouldAllowEntireTxPoolFetch: allowEntireTxPoolFetch, relayedTxsMarshaller: relayedTxsMarshaller, + txNotarizationChecker: txNotarizationChecker, }, nil } @@ -453,7 +460,7 @@ func (tp *TransactionProcessor) computeTransactionStatus(tx *transaction.ApiTran } } - if checkIfMoveBalanceNotarized(tx) { + if tp.checkIfMoveBalanceNotarized(tx) { return &data.ProcessStatusResponse{ Status: string(tx.Status), } @@ -580,9 +587,8 @@ func checkIfCompleted(logs []*transaction.ApiLogs) bool { return found } -func checkIfMoveBalanceNotarized(tx *transaction.ApiTransactionResult) bool { - isNotarized := tx.NotarizedAtSourceInMetaNonce > 0 && tx.NotarizedAtDestinationInMetaNonce > 0 - if !isNotarized { +func (tp *TransactionProcessor) checkIfMoveBalanceNotarized(tx *transaction.ApiTransactionResult) bool { + if !tp.txNotarizationChecker.IsNotarized(*tx) { return false } isMoveBalance := tx.ProcessingTypeOnSource == moveBalanceDescriptor && tx.ProcessingTypeOnDestination == moveBalanceDescriptor