Skip to content

Commit

Permalink
Merge pull request #6706 from multiversx/fix_computed_fee_on_outport
Browse files Browse the repository at this point in the history
fixed the computed fee for outport for relayed v3
  • Loading branch information
sstanculeanu authored Jan 14, 2025
2 parents 7c3462b + e66a20a commit 545d15e
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 13 deletions.
8 changes: 2 additions & 6 deletions node/external/transactionAPI/gasUsedAndFeeProcessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ func (gfp *gasUsedAndFeeProcessor) computeAndAttachGasUsedAndFee(tx *transaction
tx.GasUsed = big.NewInt(0).Div(initialTotalFee, big.NewInt(0).SetUint64(tx.GasPrice)).Uint64()
}

hasValidRelayer := len(tx.RelayerAddress) == len(tx.Sender) && len(tx.RelayerAddress) > 0
hasValidRelayerSignature := len(tx.RelayerSignature) == len(tx.Signature) && len(tx.RelayerSignature) > 0
isRelayedV3 := hasValidRelayer && hasValidRelayerSignature
isRelayedV3 := common.IsValidRelayedTxV3(tx.Tx)
hasRefundForSender := false
for _, scr := range tx.SmartContractResults {
if !scr.IsRefund {
Expand All @@ -86,9 +84,7 @@ func (gfp *gasUsedAndFeeProcessor) getFeeOfRelayedV1V2(tx *transaction.ApiTransa
return nil, nil, false
}

hasValidRelayer := len(tx.RelayerAddress) == len(tx.Sender) && len(tx.RelayerAddress) > 0
hasValidRelayerSignature := len(tx.RelayerSignature) == len(tx.Signature) && len(tx.RelayerSignature) > 0
isRelayedV3 := hasValidRelayer && hasValidRelayerSignature
isRelayedV3 := common.IsValidRelayedTxV3(tx.Tx)
if isRelayedV3 {
return nil, nil, false
}
Expand Down
17 changes: 16 additions & 1 deletion outport/process/transactionsfee/transactionChecker.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/multiversx/mx-chain-core-go/core"
"github.com/multiversx/mx-chain-core-go/data"
"github.com/multiversx/mx-chain-core-go/data/smartContractResult"
"github.com/multiversx/mx-chain-go/common"
vmcommon "github.com/multiversx/mx-chain-vm-common-go"
)

Expand Down Expand Up @@ -47,11 +48,25 @@ func isSCRForSenderWithRefund(scr *smartContractResult.SmartContractResult, txHa
}

func isRefundForRelayed(dbScResult *smartContractResult.SmartContractResult, tx data.TransactionHandler) bool {
isRelayedV3 := common.IsRelayedTxV3(tx)
isForRelayed := string(dbScResult.ReturnMessage) == core.GasRefundForRelayerMessage
isForSender := bytes.Equal(dbScResult.RcvAddr, tx.GetSndAddr())
isForRelayerV3 := isForRelayerOfV3(dbScResult, tx)
differentHash := !bytes.Equal(dbScResult.OriginalTxHash, dbScResult.PrevTxHash)

return isForRelayed && isForSender && differentHash
isRefundForRelayedV1V2 := isForRelayed && isForSender && differentHash && !isRelayedV3
isRefundForRelayedV3 := isForRelayed && isForRelayerV3 && isRelayedV3

return isRefundForRelayedV1V2 || isRefundForRelayedV3
}

func isForRelayerOfV3(scr *smartContractResult.SmartContractResult, tx data.TransactionHandler) bool {
relayedTx, isRelayedV3 := tx.(data.RelayedTransactionHandler)
if !isRelayedV3 {
return false
}

return bytes.Equal(relayedTx.GetRelayerAddr(), scr.RcvAddr)
}

func isDataOk(data []byte) bool {
Expand Down
19 changes: 13 additions & 6 deletions outport/process/transactionsfee/transactionsFeeProcessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,12 @@ func (tep *transactionsFeeProcessor) prepareNormalTxs(transactionsAndScrs *trans
feeInfo.SetFee(initialPaidFee)
}

userTx, totalFee, isRelayed := tep.getFeeOfRelayed(txWithResult)
isRelayedAfterFix := isRelayed && isFeeFixActive
userTx, totalFee, isRelayedV1V2 := tep.getFeeOfRelayedV1V2(txWithResult)
isRelayedAfterFix := isRelayedV1V2 && isFeeFixActive
if isRelayedAfterFix {
feeInfo.SetFee(totalFee)
feeInfo.SetInitialPaidFee(totalFee)
feeInfo.SetGasUsed(big.NewInt(0).Div(totalFee, big.NewInt(0).SetUint64(txHandler.GetGasPrice())).Uint64())

}

tep.prepareTxWithResults(txHashHex, txWithResult, userTx, epoch)
Expand Down Expand Up @@ -172,7 +171,11 @@ func (tep *transactionsFeeProcessor) prepareTxWithResults(
tep.prepareTxWithResultsBasedOnLogs(txHashHex, txWithResults, userTx, hasRefund, epoch)
}

func (tep *transactionsFeeProcessor) getFeeOfRelayed(tx *transactionWithResults) (data.TransactionHandler, *big.Int, bool) {
func (tep *transactionsFeeProcessor) getFeeOfRelayedV1V2(tx *transactionWithResults) (data.TransactionHandler, *big.Int, bool) {
if common.IsValidRelayedTxV3(tx.GetTxHandler()) {
return nil, nil, false
}

if len(tx.GetTxHandler().GetData()) == 0 {
return nil, nil, false
}
Expand Down Expand Up @@ -272,7 +275,7 @@ func (tep *transactionsFeeProcessor) setGasUsedAndFeeBasedOnRefundValue(
epoch uint32,
) {
isValidUserTxAfterBaseCostActivation := !check.IfNil(userTx) && tep.enableEpochsHandler.IsFlagEnabledInEpoch(common.FixRelayedBaseCostFlag, epoch)
if isValidUserTxAfterBaseCostActivation && !common.IsRelayedTxV3(txWithResults.GetTxHandler()) {
if isValidUserTxAfterBaseCostActivation && !common.IsValidRelayedTxV3(txWithResults.GetTxHandler()) {
gasUsed, fee := tep.txFeeCalculator.ComputeGasUsedAndFeeBasedOnRefundValue(userTx, refund)

tx := txWithResults.GetTxHandler()
Expand Down Expand Up @@ -312,8 +315,12 @@ func (tep *transactionsFeeProcessor) prepareScrsNoTx(transactionsAndScrs *transa
continue
}

isRelayedV3 := common.IsValidRelayedTxV3(txFromStorage)
isForInitialTxSender := bytes.Equal(scr.RcvAddr, txFromStorage.SndAddr)
if !isForInitialTxSender {
isForRelayerV3 := bytes.Equal(scr.RcvAddr, txFromStorage.RelayerAddr)
shouldSkipRelayedV3 := isRelayedV3 && !isForRelayerV3
shouldSkipTx := !isRelayedV3 && !isForInitialTxSender || shouldSkipRelayedV3
if shouldSkipTx {
continue
}

Expand Down
77 changes: 77 additions & 0 deletions outport/process/transactionsfee/transactionsFeeProcessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import (
outportcore "github.com/multiversx/mx-chain-core-go/data/outport"
"github.com/multiversx/mx-chain-core-go/data/smartContractResult"
"github.com/multiversx/mx-chain-core-go/data/transaction"
"github.com/multiversx/mx-chain-go/common"
"github.com/multiversx/mx-chain-go/outport/mock"
"github.com/multiversx/mx-chain-go/process"
"github.com/multiversx/mx-chain-go/process/economics"
"github.com/multiversx/mx-chain-go/testscommon"
"github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock"
"github.com/multiversx/mx-chain-go/testscommon/epochNotifier"
"github.com/multiversx/mx-chain-go/testscommon/genericMocks"
"github.com/multiversx/mx-chain-go/testscommon/marshallerMock"
logger "github.com/multiversx/mx-chain-logger-go"
Expand All @@ -22,6 +25,18 @@ import (

var pubKeyConverter, _ = pubkeyConverter.NewBech32PubkeyConverter(32, "erd")

func createEconomicsData(enableEpochsHandler common.EnableEpochsHandler) process.EconomicsDataHandler {
economicsConfig := testscommon.GetEconomicsConfig()
economicsData, _ := economics.NewEconomicsData(economics.ArgsNewEconomicsData{
Economics: &economicsConfig,
EnableEpochsHandler: enableEpochsHandler,
TxVersionChecker: &testscommon.TxVersionCheckerStub{},
EpochNotifier: &epochNotifier.EpochNotifierStub{},
})

return economicsData
}

func prepareMockArg() ArgTransactionsFeeProcessor {
return ArgTransactionsFeeProcessor{
Marshaller: marshallerMock.MarshalizerMock{},
Expand Down Expand Up @@ -597,3 +612,65 @@ func TestMoveBalanceWithSignalError(t *testing.T) {
require.Nil(t, err)
require.Equal(t, uint64(225_500), initialTx.GetFeeInfo().GetGasUsed())
}

func TestPutFeeAndGasUsedRelayedTxV3(t *testing.T) {
t.Parallel()

txHash := []byte("relayedTxV3")
scrWithRefund := []byte("scrWithRefund")
refundValueBig, _ := big.NewInt(0).SetString("37105580000000", 10)
initialTx := &outportcore.TxInfo{
Transaction: &transaction.Transaction{
Nonce: 9,
SndAddr: []byte("erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx"),
RcvAddr: []byte("erd1qqqqqqqqqqqqqpgq2nfn5uxjjkjlrzad3jrak8p3p30v79pseddsm73zpw"),
RelayerAddr: []byte("erd1at9keal0jfhamc67ulq4csmchh33eek87yf5hhzcvlw8e5qlx8zq5hjwjl"),
GasLimit: 5000000,
GasPrice: 1000000000,
Data: []byte("add@01"),
Value: big.NewInt(0),
},
FeeInfo: &outportcore.FeeInfo{Fee: big.NewInt(0)},
}

pool := &outportcore.TransactionPool{
Transactions: map[string]*outportcore.TxInfo{
hex.EncodeToString(txHash): initialTx,
},
SmartContractResults: map[string]*outportcore.SCRInfo{
hex.EncodeToString(scrWithRefund): {
SmartContractResult: &smartContractResult.SmartContractResult{
Nonce: 10,
GasPrice: 1000000000,
GasLimit: 0,
Value: refundValueBig,
SndAddr: []byte("erd1qqqqqqqqqqqqqpgq2nfn5uxjjkjlrzad3jrak8p3p30v79pseddsm73zpw"),
RcvAddr: []byte("erd1at9keal0jfhamc67ulq4csmchh33eek87yf5hhzcvlw8e5qlx8zq5hjwjl"),
Data: []byte(""),
PrevTxHash: txHash,
OriginalTxHash: txHash,
ReturnMessage: []byte("gas refund for relayer"),
},
FeeInfo: &outportcore.FeeInfo{
Fee: big.NewInt(0),
},
},
},
}

arg := prepareMockArg()
arg.TxFeeCalculator = createEconomicsData(&enableEpochsHandlerMock.EnableEpochsHandlerStub{
IsFlagEnabledInEpochCalled: func(flag core.EnableEpochFlag, epoch uint32) bool {
return true
},
})
txsFeeProc, err := NewTransactionsFeeProcessor(arg)
require.NotNil(t, txsFeeProc)
require.Nil(t, err)

err = txsFeeProc.PutFeeAndGasUsed(pool, 0)
require.Nil(t, err)
require.Equal(t, big.NewInt(120804420000000), initialTx.GetFeeInfo().GetFee())
require.Equal(t, uint64(1289442), initialTx.GetFeeInfo().GetGasUsed())
require.Equal(t, "157910000000000", initialTx.GetFeeInfo().GetInitialPaidFee().String())
}

0 comments on commit 545d15e

Please sign in to comment.