Skip to content

Commit

Permalink
Merge pull request #6709 from multiversx/multiple-scrs-with-refund
Browse files Browse the repository at this point in the history
Multiple smart contract results with refund
  • Loading branch information
miiu96 authored Jan 16, 2025
2 parents 9caaba2 + 86fdeb9 commit f937fba
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 10 deletions.
5 changes: 5 additions & 0 deletions genesis/process/disabled/feeHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import (
type FeeHandler struct {
}

// ComputeGasUnitsFromRefundValue return 0
func (fh *FeeHandler) ComputeGasUnitsFromRefundValue(_ data.TransactionWithFeeHandler, _ *big.Int, _ uint32) uint64 {
return 0
}

// GasPriceModifier returns 1.0
func (fh *FeeHandler) GasPriceModifier() float64 {
return 1.0
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ require (
github.com/klauspost/cpuid/v2 v2.2.5
github.com/mitchellh/mapstructure v1.5.0
github.com/multiversx/mx-chain-communication-go v1.1.1
github.com/multiversx/mx-chain-core-go v1.2.24-0.20250109151319-81a62c045af8
github.com/multiversx/mx-chain-core-go v1.2.24-0.20250116081327-adb8c08089b4
github.com/multiversx/mx-chain-crypto-go v1.2.12
github.com/multiversx/mx-chain-es-indexer-go v1.7.13-0.20250109151711-ceaca49de8e1
github.com/multiversx/mx-chain-es-indexer-go v1.7.13-0.20250116081916-62f5c3451bed
github.com/multiversx/mx-chain-logger-go v1.0.15
github.com/multiversx/mx-chain-scenario-go v1.4.4
github.com/multiversx/mx-chain-storage-go v1.0.19-0.20250109152325-cf81acfd19bd
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -387,12 +387,12 @@ github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUY
github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o=
github.com/multiversx/mx-chain-communication-go v1.1.1 h1:y4DoQeQOJTaSUsRzczQFazf8JYQmInddypApqA3AkwM=
github.com/multiversx/mx-chain-communication-go v1.1.1/go.mod h1:WK6bP4pGEHGDDna/AYRIMtl6G9OA0NByI1Lw8PmOnRM=
github.com/multiversx/mx-chain-core-go v1.2.24-0.20250109151319-81a62c045af8 h1:0ivlwcl+dKK7BTVngm1uNM2aDneaXK2rhS0HVeBkvYg=
github.com/multiversx/mx-chain-core-go v1.2.24-0.20250109151319-81a62c045af8/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE=
github.com/multiversx/mx-chain-core-go v1.2.24-0.20250116081327-adb8c08089b4 h1:rWYFL38q5cbo5MtdW2DvAp4+WMaVp8e7gBjmrLQ9SCY=
github.com/multiversx/mx-chain-core-go v1.2.24-0.20250116081327-adb8c08089b4/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE=
github.com/multiversx/mx-chain-crypto-go v1.2.12 h1:zWip7rpUS4CGthJxfKn5MZfMfYPjVjIiCID6uX5BSOk=
github.com/multiversx/mx-chain-crypto-go v1.2.12/go.mod h1:HzcPpCm1zanNct/6h2rIh+MFrlXbjA5C8+uMyXj3LI4=
github.com/multiversx/mx-chain-es-indexer-go v1.7.13-0.20250109151711-ceaca49de8e1 h1:rHZS2Nw7M8thrtdN+s8qIf7TN9pi79r8n9J2gs0MaCc=
github.com/multiversx/mx-chain-es-indexer-go v1.7.13-0.20250109151711-ceaca49de8e1/go.mod h1:NMNBlIO60Wc026iSDp/eqnb0YmoiH05pEuphkdlW43k=
github.com/multiversx/mx-chain-es-indexer-go v1.7.13-0.20250116081916-62f5c3451bed h1:UOZ6c1MOANM8RLyYw/okKGwnowF+dRbzwPpzr11zaZ0=
github.com/multiversx/mx-chain-es-indexer-go v1.7.13-0.20250116081916-62f5c3451bed/go.mod h1:Q6qug6OodSOzwZuMrvrfDcMmPB2FcP7CKr9rqsn0OHQ=
github.com/multiversx/mx-chain-logger-go v1.0.15 h1:HlNdK8etyJyL9NQ+6mIXyKPEBo+wRqOwi3n+m2QIHXc=
github.com/multiversx/mx-chain-logger-go v1.0.15/go.mod h1:t3PRKaWB1M+i6gUfD27KXgzLJJC+mAQiN+FLlL1yoGQ=
github.com/multiversx/mx-chain-scenario-go v1.4.4 h1:DVE2V+FPeyD/yWoC+KEfPK3jsFzHeruelESfpTlf460=
Expand Down
5 changes: 5 additions & 0 deletions outport/mock/economicsDataMock.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ const (
type EconomicsHandlerMock struct {
}

// ComputeGasUnitsFromRefundValue -
func (e *EconomicsHandlerMock) ComputeGasUnitsFromRefundValue(_ coreData.TransactionWithFeeHandler, _ *big.Int, _ uint32) uint64 {
return 0
}

// MaxGasLimitPerBlock -
func (e *EconomicsHandlerMock) MaxGasLimitPerBlock(_ uint32) uint64 {
return 0
Expand Down
1 change: 1 addition & 0 deletions outport/process/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type GasConsumedProvider interface {

// EconomicsDataHandler defines the functionality needed for economics data
type EconomicsDataHandler interface {
ComputeGasUnitsFromRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) uint64
ComputeGasUsedAndFeeBasedOnRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int) (uint64, *big.Int)
ComputeTxFeeBasedOnGasUsed(tx data.TransactionWithFeeHandler, gasUsed uint64) *big.Int
ComputeTxFee(tx data.TransactionWithFeeHandler) *big.Int
Expand Down
1 change: 1 addition & 0 deletions outport/process/transactionsfee/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// FeesProcessorHandler defines the interface for the transaction fees processor
type FeesProcessorHandler interface {
ComputeGasUsedAndFeeBasedOnRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int) (uint64, *big.Int)
ComputeGasUnitsFromRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) uint64
ComputeTxFeeBasedOnGasUsed(tx data.TransactionWithFeeHandler, gasUsed uint64) *big.Int
ComputeTxFee(tx data.TransactionWithFeeHandler) *big.Int
ComputeGasLimit(tx data.TransactionWithFeeHandler) uint64
Expand Down
24 changes: 20 additions & 4 deletions outport/process/transactionsfee/transactionsFeeProcessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (tep *transactionsFeeProcessor) PutFeeAndGasUsed(pool *outportcore.Transact
txsWithResultsMap := prepareTransactionsAndScrs(pool)
tep.prepareNormalTxs(txsWithResultsMap, epoch)

return tep.prepareScrsNoTx(txsWithResultsMap)
return tep.prepareScrsNoTx(txsWithResultsMap, epoch)
}

func (tep *transactionsFeeProcessor) prepareInvalidTxs(pool *outportcore.TransactionPool) {
Expand Down Expand Up @@ -155,19 +155,24 @@ func (tep *transactionsFeeProcessor) prepareTxWithResults(
epoch uint32,
) {
hasRefund := false
totalRefunds := big.NewInt(0)
for _, scrHandler := range txWithResults.scrs {
scr, ok := scrHandler.GetTxHandler().(*smartContractResult.SmartContractResult)
if !ok {
continue
}

if isSCRForSenderWithRefund(scr, txHashHex, txWithResults.GetTxHandler()) || isRefundForRelayed(scr, txWithResults.GetTxHandler()) {
tep.setGasUsedAndFeeBasedOnRefundValue(txWithResults, userTx, scr.Value, epoch)
hasRefund = true
break
totalRefunds.Add(totalRefunds, scr.Value)
}
}

if totalRefunds.Cmp(big.NewInt(0)) > 0 {
tep.setGasUsedAndFeeBasedOnRefundValue(txWithResults, userTx, totalRefunds, epoch)

}

tep.prepareTxWithResultsBasedOnLogs(txHashHex, txWithResults, userTx, hasRefund, epoch)
}

Expand Down Expand Up @@ -274,6 +279,8 @@ func (tep *transactionsFeeProcessor) setGasUsedAndFeeBasedOnRefundValue(
refund *big.Int,
epoch uint32,
) {
txWithResults.GetFeeInfo().SetHadRefund()

isValidUserTxAfterBaseCostActivation := !check.IfNil(userTx) && tep.enableEpochsHandler.IsFlagEnabledInEpoch(common.FixRelayedBaseCostFlag, epoch)
if isValidUserTxAfterBaseCostActivation && !common.IsValidRelayedTxV3(txWithResults.GetTxHandler()) {
gasUsed, fee := tep.txFeeCalculator.ComputeGasUsedAndFeeBasedOnRefundValue(userTx, refund)
Expand All @@ -293,7 +300,7 @@ func (tep *transactionsFeeProcessor) setGasUsedAndFeeBasedOnRefundValue(
txWithResults.GetFeeInfo().SetFee(fee)
}

func (tep *transactionsFeeProcessor) prepareScrsNoTx(transactionsAndScrs *transactionsAndScrsHolder) error {
func (tep *transactionsFeeProcessor) prepareScrsNoTx(transactionsAndScrs *transactionsAndScrsHolder, epoch uint32) error {
for _, scrHandler := range transactionsAndScrs.scrsNoTx {
scr, ok := scrHandler.GetTxHandler().(*smartContractResult.SmartContractResult)
if !ok {
Expand Down Expand Up @@ -326,11 +333,20 @@ func (tep *transactionsFeeProcessor) prepareScrsNoTx(transactionsAndScrs *transa

userTx := tep.getUserTxOfRelayed(txFromStorage)
if check.IfNil(userTx) {
// relayed v3 and other txs
if isRelayedV3 {
gasUnits := tep.txFeeCalculator.ComputeGasUnitsFromRefundValue(txFromStorage, scr.Value, epoch)
scrHandler.GetFeeInfo().SetGasRefunded(gasUnits)
scrHandler.GetFeeInfo().SetFee(scr.Value)
continue
}

gasUsed, fee := tep.txFeeCalculator.ComputeGasUsedAndFeeBasedOnRefundValue(txFromStorage, scr.Value)

scrHandler.GetFeeInfo().SetGasUsed(gasUsed)
scrHandler.GetFeeInfo().SetFee(fee)
} else {
// relayed v1 and v2
gasUsed, fee := tep.txFeeCalculator.ComputeGasUsedAndFeeBasedOnRefundValue(userTx, scr.Value)

gasUsedRelayedTx := tep.txFeeCalculator.ComputeGasLimit(txFromStorage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,4 +673,5 @@ func TestPutFeeAndGasUsedRelayedTxV3(t *testing.T) {
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())
require.True(t, initialTx.GetFeeInfo().HadRefund)
}
9 changes: 9 additions & 0 deletions process/economics/economicsData.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,15 @@ func (ed *economicsData) ComputeGasLimitBasedOnBalance(tx data.TransactionWithFe
return ed.ComputeGasLimitBasedOnBalanceInEpoch(tx, balance, currentEpoch)
}

// ComputeGasUnitsFromRefundValue will compute the gas unit based on the refund value
func (ed *economicsData) ComputeGasUnitsFromRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) uint64 {
gasPrice := ed.GasPriceForProcessingInEpoch(tx, epoch)
refund := big.NewInt(0).Set(refundValue)
gasUnits := refund.Div(refund, big.NewInt(int64(gasPrice)))

return gasUnits.Uint64()
}

// ComputeGasLimitBasedOnBalanceInEpoch will compute gas limit for the given transaction based on the balance in a specific epoch
func (ed *economicsData) ComputeGasLimitBasedOnBalanceInEpoch(tx data.TransactionWithFeeHandler, balance *big.Int, epoch uint32) (uint64, error) {
balanceWithoutTransferValue := big.NewInt(0).Sub(balance, tx.GetValue())
Expand Down
1 change: 1 addition & 0 deletions process/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,7 @@ type feeHandler interface {
ComputeGasUsedAndFeeBasedOnRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int) (uint64, *big.Int)
ComputeTxFeeBasedOnGasUsed(tx data.TransactionWithFeeHandler, gasUsed uint64) *big.Int
ComputeGasLimitBasedOnBalance(tx data.TransactionWithFeeHandler, balance *big.Int) (uint64, error)
ComputeGasUnitsFromRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) uint64
ComputeTxFeeInEpoch(tx data.TransactionWithFeeHandler, epoch uint32) *big.Int
ComputeGasLimitInEpoch(tx data.TransactionWithFeeHandler, epoch uint32) uint64
ComputeGasUsedAndFeeBasedOnRefundValueInEpoch(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) (uint64, *big.Int)
Expand Down
10 changes: 10 additions & 0 deletions testscommon/economicsmocks/economicsDataHandlerStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ type EconomicsHandlerStub struct {
ComputeGasUsedAndFeeBasedOnRefundValueInEpochCalled func(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) (uint64, *big.Int)
ComputeTxFeeBasedOnGasUsedInEpochCalled func(tx data.TransactionWithFeeHandler, gasUsed uint64, epoch uint32) *big.Int
ComputeMoveBalanceFeeInEpochCalled func(tx data.TransactionWithFeeHandler, epoch uint32) *big.Int
ComputeGasUnitsFromRefundValueCalled func(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) uint64
}

// ComputeGasUnitsFromRefundValue -
func (e *EconomicsHandlerStub) ComputeGasUnitsFromRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) uint64 {
if e.ComputeGasUnitsFromRefundValueCalled != nil {
return e.ComputeGasUnitsFromRefundValueCalled(tx, refundValue, epoch)
}

return 0
}

// ComputeFeeForProcessing -
Expand Down
5 changes: 5 additions & 0 deletions testscommon/economicsmocks/economicsHandlerMock.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ type EconomicsHandlerMock struct {
ComputeTxFeeBasedOnGasUsedInEpochCalled func(tx data.TransactionWithFeeHandler, gasUsed uint64, epoch uint32) *big.Int
}

// ComputeGasUnitsFromRefundValue -
func (ehm *EconomicsHandlerMock) ComputeGasUnitsFromRefundValue(_ data.TransactionWithFeeHandler, _ *big.Int, _ uint32) uint64 {
return 0
}

// LeaderPercentage -
func (ehm *EconomicsHandlerMock) LeaderPercentage() float64 {
return ehm.LeaderPercentageCalled()
Expand Down

0 comments on commit f937fba

Please sign in to comment.