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

New relayed v3 #6570

Merged
merged 14 commits into from
Nov 25, 2024
Merged

New relayed v3 #6570

merged 14 commits into from
Nov 25, 2024

Conversation

sstanculeanu
Copy link
Collaborator

Reasoning behind the pull request

  • new implementation for relayed transactions v3 was needed, in order to simplify the initial implementation

Proposed changes

  • new approach, with relayer signature on the relayed transaction

Testing procedure

  • scenarios + system test

Pre-requisites

Based on the Contributing Guidelines the PR author and the reviewers must check the following requirements are met:

  • was the PR targeted to the correct branch?
  • if this is a larger feature that probably needs more than one PR, is there a feat branch created?
  • if this is a feat branch merging, do all satellite projects have a proper tag inside go.mod?

Copy link

⚠️ No report was generated due to an error or cancellation of the process.
Please checkout gh action logs for details

Copy link

⚠️ No report was generated due to an error or cancellation of the process.
Please checkout gh action logs for details

Copy link

⚠️ No report was generated due to an error or cancellation of the process.
Please checkout gh action logs for details

Copy link

⚠️ No report was generated due to an error or cancellation of the process.
Please checkout gh action logs for details

cristure
cristure previously approved these changes Oct 31, 2024
@sasurobert sasurobert self-requested a review November 4, 2024 07:12
if !check.IfNil(userTx) && tep.enableEpochsHandler.IsFlagEnabledInEpoch(common.FixRelayedBaseCostFlag, epoch) {
tx := txWithResults.GetTxHandler()
relayedTx, isRelayedV3 := tx.(data.RelayedTransactionHandler)
if isRelayedV3 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have seen this code a few times. can't you make a common function for this in a core file and call from everywhere ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied the suggestion

@@ -83,6 +83,16 @@ func (tth *txTypeHandler) ComputeTransactionType(tx data.TransactionHandler) (pr
return process.InvalidTransaction, process.InvalidTransaction
}

relayedTxV3, ok := tx.(data.RelayedTransactionHandler)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above - we need a core function for all the checks.

tx := interceptedTx.Transaction()
relayedTx, ok := tx.(data.RelayedTransactionHandler)
if ok {
hasValidRelayer := len(relayedTx.GetRelayerAddr()) == len(tx.GetSndAddr()) && len(relayedTx.GetRelayerAddr()) > 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicated code again.

hasValidRelayerSignature := len(txInstance.GetRelayerSignature()) == len(txInstance.GetSignature()) && len(txInstance.GetRelayerSignature()) > 0
isRelayedV3 := hasValidRelayer && hasValidRelayerSignature
if isRelayedV3 {
gasLimit += ed.MinGasLimitInEpoch(epoch)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not a function like getExtraGasLimitRelayedTx(epoch) and than you can have the implementation there. As is in case of guarded txs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extracted in a new method

gasLimit += ed.getExtraGasLimitGuardedTx(epoch)
}

hasValidRelayer := len(txInstance.GetRelayerAddr()) == len(txInstance.GetSndAddr()) && len(txInstance.GetRelayerAddr()) > 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicated code here.

}

// early exit for relayed v3, the cost will be compared with the sender balance
if isRelayedV3 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need early exit here? it could go on and get its fee verified on the next lines.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be few lines later, indeed

the reason why it is needed is because this method is called from multiple places:

  1. for full relayed tx, before moving the funds from relayer to the sender. In this case, we need the early exit as the feePayer will be the relayer, but the txValue will be taken from the sender. So we don't want to check if the relayer also has the tx.Value.
  2. only for user tx, when the tx fee was already moved into the relayer account. At this point, the sender of the user tx will be verified if it has both the fee(moved from relayer) and the tx.Value (which is here defined as cost)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is too hard to understand the code and a lot of mistakes can happen because of it.

Can you have separate functions called as it should be ?

@@ -223,6 +232,36 @@ func isRelayedTx(funcName string) bool {
core.RelayedTransactionV2 == funcName
}

func isRelayedTxV3(tx *transaction.Transaction) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can be considered as relayed TX V3 if one of the 2 new fields is not nil. And if it is not nil and but data is inconsistent than it is a failed tx.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the method and reused the common one

the reason why I've added the extended check was to avoid treating txs that only have relayer address or relayer signature as relayed v3.. of course, these txs would have failed later

relayedNonce := tx.Nonce
relayerAddr := tx.SndAddr
if isUserTxOfRelayedV3 && !check.IfNil(relayerAcnt) {
relayedNonce = relayerAcnt.GetNonce() - 1 // nonce already increased inside processTxAtRelayer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah. but it is increased for the relayer. which is not really good.

In case of relayedV3 increase nonce should happen only at the user - and it has to be exactly as its transaction nonce has.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the code to avoid relayer nonce increase, thanks for clarification


userTx := *tx
// remove relayer addr and signature for tx type handler
userTx.RelayerAddr = nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it could work without these 2 lines.

Copy link
Collaborator Author

@sstanculeanu sstanculeanu Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the current implementation of ProcessTransactionType from txTypeHandler(first check if is relayed v3), if these fields won't be removed, the user tx will still be considered of type relayed v3

at this point, we want to get the proper type of the user tx for its processing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah. but this is not ok at all. somebody make a hash for the USER TX - and it gets completely different, links will be lost.

You may create a new function down the line - which works a little bit differently.

I would also separate into new function because we want to get rid of relayedV1 and relayedV2.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushed the suggestions + improved the comment of mentioned area

Copy link

📊 MultiversX Automated Test Report: View Report

🔄 Build Details:

  • mx-chain-go Commit Hash: 531aad5fefe9ca88daf115aebc40136b44cba949
  • Current Branch: relayedv3
  • mx-chain-go Target Branch: rc/v1.7.next1
  • mx-chain-simulator-go Target Branch: rc/v1.7.next1
  • mx-chain-testing-suite Target Branch: rc/v1.7.next1

🚀 Environment Variables:

  • TIMESTAMP: 11112024-112502
  • PYTEST_EXIT_CODE: 0
    🎉 MultiversX CI/CD Workflow Complete!

Copy link
Contributor

@sasurobert sasurobert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also - I think the target should be rc/barnard

common/common.go Outdated
import "github.com/multiversx/mx-chain-core-go/data"

// IsRelayedTxV3 returns true if the provided transaction is of type relayed v3
func IsRelayedTxV3(tx data.TransactionHandler) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it returns true only if it is a valid relayed v3 - thus the fields are filled correctly. Maybe a slight rename ?


_, err := txDispatcherNode.SendTransaction(relayedTx)
if err != nil {
fmt.Println(err.Error())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log.error - instead of this.

@@ -271,7 +271,8 @@ func (tep *transactionsFeeProcessor) setGasUsedAndFeeBasedOnRefundValue(
refund *big.Int,
epoch uint32,
) {
if !check.IfNil(userTx) && tep.enableEpochsHandler.IsFlagEnabledInEpoch(common.FixRelayedBaseCostFlag, epoch) {
isValidUserTxAfterBaseCostActivation := !check.IfNilReflect(userTx) && tep.enableEpochsHandler.IsFlagEnabledInEpoch(common.FixRelayedBaseCostFlag, epoch)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reflection, change to ifNil.

@@ -166,14 +171,35 @@ func (txProc *baseTxProcessor) checkTxValues(
txFee = core.SafeMul(tx.GasLimit, tx.GasPrice)
}

// early exit for relayed v3, the cost will be compared with the sender balance
if isRelayedV3 {
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the code now. Still a little hard to understand.


userTx := *tx
// remove relayer addr and signature for tx type handler
userTx.RelayerAddr = nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah. but this is not ok at all. somebody make a hash for the USER TX - and it gets completely different, links will be lost.

You may create a new function down the line - which works a little bit differently.

I would also separate into new function because we want to get rid of relayedV1 and relayedV2.

Copy link

📊 MultiversX Automated Test Report: View Report

🔄 Build Details:

  • mx-chain-go Commit Hash: 6c02c942752af944fe5d97363be7139e05e61a28
  • Current Branch: relayedv3
  • mx-chain-go Target Branch: rc/v1.7.next1
  • mx-chain-simulator-go Target Branch: rc/v1.7.next1
  • mx-chain-testing-suite Target Branch: rc/v1.7.next1

🚀 Environment Variables:

  • TIMESTAMP: 13112024-155719
  • PYTEST_EXIT_CODE: 0
    🎉 MultiversX CI/CD Workflow Complete!

@sstanculeanu sstanculeanu changed the base branch from rc/v1.7.next1 to rc/spica-patch-mempool November 19, 2024 08:29
@sstanculeanu
Copy link
Collaborator Author

sstanculeanu commented Nov 19, 2024

Run Tests:
mx-chain-simulator-go: main
mx-chain-testing-suite: main

@multiversx multiversx deleted a comment from github-actions bot Nov 19, 2024
@multiversx multiversx deleted a comment from github-actions bot Nov 19, 2024
@multiversx multiversx deleted a comment from github-actions bot Nov 19, 2024
@multiversx multiversx deleted a comment from github-actions bot Nov 19, 2024
@multiversx multiversx deleted a comment from github-actions bot Nov 19, 2024
Copy link

📊 MultiversX Automated Test Report: View Report

🔄 Build Details:

  • mx-chain-go Commit Hash: ea799ab74103af94b86408aecb4e938cb05bb6ee
  • Current Branch: relayedv3
  • mx-chain-go Target Branch: rc/spica-patch-mempool
  • mx-chain-simulator-go Target Branch: main
  • mx-chain-testing-suite Target Branch: main

🚀 Environment Variables:

  • TIMESTAMP: 19112024-102035
  • PYTEST_EXIT_CODE: 0
    🎉 MultiversX CI/CD Workflow Complete!

@sstanculeanu sstanculeanu changed the base branch from rc/spica-patch-mempool to feat/relayedv3 November 21, 2024 19:08
@@ -306,7 +308,7 @@ func (txProc *txProcessor) executingFailedTransaction(
return err
}

acntSnd.IncreaseNonce(1)
relayerAccount.IncreaseNonce(1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this correct ?

With the new model the increase of the nonce has to be Tx.Sender, not tx.RelayerAddress.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed this was wrong.. reverted the changes done for this method and created a new one for relayed v3, thus further separating the code

userTx *transaction.Transaction,
) (vmcommon.ReturnCode, error) {
computedFees := txProc.computeRelayedTxV3Fees(tx, userTx)
txHash, err := txProc.processTxV3AtRelayer(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not necessary processing, but taking out fees from relayer. maybe rename the function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed to consumeFeeFromRelayer

return nil, err
}

txProc.txFeeHandler.ProcessTransactionFee(relayerFee, big.NewInt(0), txHash)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't the fee the Total Fee in this case ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should stay relayerFee, same as relayed v1 and v2, as the cost of execution is added to txFeeHandler as part of sc processor

@sstanculeanu
Copy link
Collaborator Author

Run Tests:
mx-chain-simulator-go: main
mx-chain-testing-suite: main

Copy link

📊 MultiversX Automated Test Report: View Report

🔄 Build Details:

  • mx-chain-go Commit Hash: 4c24359ab89654bee5b184d2506d31cd959165bf
  • Current Branch: master
  • mx-chain-go Target Branch: ``
  • mx-chain-simulator-go Target Branch: main
  • mx-chain-testing-suite Target Branch: main

🚀 Environment Variables:

  • TIMESTAMP: 25112024-110118
  • PYTEST_EXIT_CODE: 0
    🎉 MultiversX CI/CD Workflow Complete!

@sstanculeanu sstanculeanu merged commit b8487af into feat/relayedv3 Nov 25, 2024
4 checks passed
@sstanculeanu sstanculeanu deleted the relayedv3 branch November 25, 2024 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants