-
Notifications
You must be signed in to change notification settings - Fork 204
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
Mempool: completely handle fees and transferred balances within "detectWillFeeExceedBalance()" #6637
Mempool: completely handle fees and transferred balances within "detectWillFeeExceedBalance()" #6637
Changes from 2 commits
1cb65c2
16e35e2
c1695d3
6090ae4
959affe
6e33cbf
59d7ec7
7eed6f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,58 @@ | ||
package preprocess | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"math/big" | ||
|
||
"github.com/multiversx/mx-chain-core-go/core" | ||
"github.com/multiversx/mx-chain-core-go/core/check" | ||
"github.com/multiversx/mx-chain-core-go/data" | ||
"github.com/multiversx/mx-chain-core-go/data/transaction" | ||
"github.com/multiversx/mx-chain-core-go/marshal" | ||
"github.com/multiversx/mx-chain-go/process" | ||
"github.com/multiversx/mx-chain-go/state" | ||
"github.com/multiversx/mx-chain-go/storage/txcache" | ||
vmcommon "github.com/multiversx/mx-chain-vm-common-go" | ||
"github.com/multiversx/mx-chain-vm-common-go/parsers" | ||
) | ||
|
||
type selectionSession struct { | ||
accountsAdapter state.AccountsAdapter | ||
transactionsProcessor process.TransactionProcessor | ||
callArgumentsParser process.CallArgumentsParser | ||
esdtTransferParser vmcommon.ESDTTransferParser | ||
} | ||
|
||
func newSelectionSession(accountsAdapter state.AccountsAdapter, transactionsProcessor process.TransactionProcessor) (*selectionSession, error) { | ||
if check.IfNil(accountsAdapter) { | ||
type argsSelectionSession struct { | ||
accountsAdapter state.AccountsAdapter | ||
transactionsProcessor process.TransactionProcessor | ||
marshalizer marshal.Marshalizer | ||
} | ||
|
||
func newSelectionSession(args argsSelectionSession) (*selectionSession, error) { | ||
if check.IfNil(args.accountsAdapter) { | ||
return nil, process.ErrNilAccountsAdapter | ||
} | ||
if check.IfNil(transactionsProcessor) { | ||
if check.IfNil(args.transactionsProcessor) { | ||
return nil, process.ErrNilTxProcessor | ||
} | ||
if check.IfNil(args.marshalizer) { | ||
return nil, process.ErrNilMarshalizer | ||
} | ||
|
||
argsParser := parsers.NewCallArgsParser() | ||
|
||
esdtTransferParser, err := parsers.NewESDTTransferParser(args.marshalizer) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &selectionSession{ | ||
accountsAdapter: accountsAdapter, | ||
transactionsProcessor: transactionsProcessor, | ||
accountsAdapter: args.accountsAdapter, | ||
transactionsProcessor: args.transactionsProcessor, | ||
callArgumentsParser: argsParser, | ||
esdtTransferParser: esdtTransferParser, | ||
}, nil | ||
} | ||
|
||
|
@@ -72,6 +98,58 @@ func (session *selectionSession) IsBadlyGuarded(tx data.TransactionHandler) bool | |
return errors.Is(err, process.ErrTransactionNotExecutable) | ||
} | ||
|
||
// GetTransferredValue returns the value transferred by a transaction. | ||
func (session *selectionSession) GetTransferredValue(tx data.TransactionHandler) *big.Int { | ||
hasValue := tx.GetValue() != nil && tx.GetValue().Sign() != 0 | ||
if hasValue { | ||
// Early exit (optimization): a transaction can either bear a regular value or be a "MultiESDTNFTTransfer". | ||
return tx.GetValue() | ||
} | ||
|
||
hasData := len(tx.GetData()) > 0 | ||
if !hasData { | ||
// Early exit (optimization): no "MultiESDTNFTTransfer" to parse. | ||
return tx.GetValue() | ||
} | ||
|
||
maybeMultiTransfer := bytes.HasPrefix(tx.GetData(), []byte(core.BuiltInFunctionMultiESDTNFTTransfer)) | ||
if !maybeMultiTransfer { | ||
// Early exit (optimization). | ||
return nil | ||
} | ||
|
||
function, args, err := session.callArgumentsParser.ParseData(string(tx.GetData())) | ||
if err != nil { | ||
return nil | ||
} | ||
|
||
if function != core.BuiltInFunctionMultiESDTNFTTransfer { | ||
// Early exit (optimization). | ||
return nil | ||
} | ||
|
||
esdtTransfers, err := session.esdtTransferParser.ParseESDTTransfers(tx.GetSndAddr(), tx.GetRcvAddr(), function, args) | ||
if err != nil { | ||
return nil | ||
} | ||
|
||
accumulatedNativeValue := big.NewInt(0) | ||
|
||
for _, transfer := range esdtTransfers.ESDTTransfers { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this add a negligible overhead? A lot of transactions are with MultiESDTNFTTransfer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very good question, will benchmark ASAP 🙌 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Thus, if we select ~10k, about 20 milliseconds (a bit much) will be spent in We can move the call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MX-16211 |
||
if transfer.ESDTTokenNonce != 0 { | ||
continue | ||
} | ||
if string(transfer.ESDTTokenName) != vmcommon.EGLDIdentifier { | ||
// We only care about native transfers. | ||
continue | ||
} | ||
|
||
_ = accumulatedNativeValue.Add(accumulatedNativeValue, transfer.ESDTValue) | ||
} | ||
|
||
return accumulatedNativeValue | ||
} | ||
|
||
// IsInterfaceNil returns true if there is no value under the interface | ||
func (session *selectionSession) IsInterfaceNil() bool { | ||
return session == nil | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Superfluous (somehow)?