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

fixed the computed fee for outport for relayed v3 #6706

Merged
merged 1 commit into from
Jan 14, 2025
Merged
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
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())
}
Loading