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

Relayed v3 #5572

Merged
merged 13 commits into from
Oct 11, 2023
Merged

Relayed v3 #5572

merged 13 commits into from
Oct 11, 2023

Conversation

sstanculeanu
Copy link
Collaborator

@sstanculeanu sstanculeanu commented Sep 8, 2023

Reasoning behind the pull request

  • New approach for relayed txs, v3, where the user tx is set as a new field of the parent tx, which would simplify and lower the processing cost to the cost of 2 different txs, as there will be no more extra data field.

Proposed changes

  • implement the changes needed

Testing procedure

  • standard system test
  • relayed v3 specific tests

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?

@sstanculeanu sstanculeanu self-assigned this Sep 8, 2023
@codecov
Copy link

codecov bot commented Sep 8, 2023

Codecov Report

All modified lines are covered by tests ✅

❗ No coverage uploaded for pull request base (feat/relayedv3@5fe5258). Click here to learn what that means.

❗ Current head fe4c31c differs from pull request most recent head ca23f1b. Consider uploading reports for the commit ca23f1b to get more accurate results

Additional details and impacted files
@@                Coverage Diff                @@
##             feat/relayedv3    #5572   +/-   ##
=================================================
  Coverage                  ?   80.05%           
=================================================
  Files                     ?      706           
  Lines                     ?    93789           
  Branches                  ?        0           
=================================================
  Hits                      ?    75081           
  Misses                    ?    13369           
  Partials                  ?     5339           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@sstanculeanu sstanculeanu marked this pull request as ready for review September 25, 2023 06:02
@sstanculeanu sstanculeanu changed the base branch from rc/v1.6.0 to feat/relayedv3 September 25, 2023 07:10
@sasurobert sasurobert self-requested a review September 25, 2023 07:11
@AdoAdoAdo AdoAdoAdo self-requested a review September 25, 2023 10:58
"github.com/stretchr/testify/assert"
)

func TestRelayedTransactionV2InMultiShardEnvironmentWithSmartContractTX(t *testing.T) {
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 delete this ? Until v1 and v2 features are not obsolete, like they are not taken out with an activation flag the tests have to stay.

Copy link
Contributor

Choose a reason for hiding this comment

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

They are somewhat duplicated - but sometimes these obsolete tests catch some issues.

Copy link
Collaborator Author

@sstanculeanu sstanculeanu Sep 26, 2023

Choose a reason for hiding this comment

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

the code is not lost, but moved here, in order to reuse it for different types of relayed

TestRelayedTransactionV2InMultiShardEnvironmentWithSmartContractTX is now TestRelayedTransactionInMultiShardEnvironmentWithSmartContractTX/relayed v2

node/node.go Outdated
@@ -54,7 +54,8 @@ var log = logger.GetOrCreate("node")
var _ facade.NodeHandler = (*Node)(nil)

// Option represents a functional configuration parameter that can operate
// over the None struct.
//
Copy link
Contributor

Choose a reason for hiding this comment

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

indent. delete empty line

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed

return false
}

return rtx.GetInnerTransaction() != nil
Copy link
Contributor

Choose a reason for hiding this comment

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

check.Ifnil

@@ -16,6 +17,10 @@ import (

var _ process.TxTypeHandler = (*txTypeHandler)(nil)

type relayedV3TransactionHandler interface {
GetInnerTransaction() *transaction.Transaction
Copy link
Contributor

Choose a reason for hiding this comment

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

can't you add this function to the data.TransactionHandler interface ? and have GetInnerTransaction() data.TransactionHandler as the actual function ? It is better if we do not have concrete structure here.

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 TransactionHandler interface

@@ -115,6 +121,12 @@ func (txv *txValidator) getSenderUserAccount(
}

func (txv *txValidator) checkBalance(interceptedTx process.InterceptedTransactionHandler, account state.UserAccountHandler) error {
rTx, ok := interceptedTx.Transaction().(relayedV3TransactionHandler)
if ok && len(rTx.GetRelayerAddr()) > 0 {
// early return if this is a user tx of relayed v3, no need to check balance
Copy link
Contributor

Choose a reason for hiding this comment

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

check balance of relayer is a must.

Like the transaction sender is the relayer, if it has InnerTransaction - the inner TX should be for the user. First we execute the balance transfer from the relayer to the user, and execute the inner TX after.

GetRelayerAddr should be a field in the InnerTransaction and in the SmartContractResults.

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 won't apply for the relayed transaction

this check is only valid for the inner transaction. Reason: only transaction is castable to this structure, then only an inner transaction would have the relayer address set

the reason why this bypass is needed is because now, at api level, we also create the inner transaction, which would fail in the following scenario:

  • User A with 0 egld signs a tx to move some ESDT
  • Relayer B will pay the fee for it
  • Since A does not have EGLD, the inner tx creation at API level would have failed

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok. I get that this is for user tx only. so it is the check for inner 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.

exactly, but does not work as expected.. on it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

completely removed it, not needed

if !bytes.Equal(innerTx.SndAddr, tx.RcvAddr) {
return process.ErrRelayedTxV3BeneficiaryDoesNotMatchReceiver
}
if len(innerTx.RelayerAddr) == 0 {
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 a relayerAddress in the innerTX ? it is not needed. Duplicate information. You have the relayerAddress from the tx.SndAddr

Copy link
Collaborator Author

@sstanculeanu sstanculeanu Sep 26, 2023

Choose a reason for hiding this comment

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

added it for an extra check, to be the same with (parent tx).SndAddr, as discussed with @AdoAdoAdo

Copy link
Contributor

Choose a reason for hiding this comment

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

that's good. As the user can choose the relayer.

Copy link
Contributor

Choose a reason for hiding this comment

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

But add the check

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added

@@ -103,7 +103,7 @@ func (ate *apiTransactionEvaluator) ComputeTransactionGasLimit(tx *transaction.T
switch txTypeOnSender {
case process.SCDeployment, process.SCInvoking, process.BuiltInFunctionCall, process.MoveBalance:
return ate.simulateTransactionCost(tx, txTypeOnSender)
case process.RelayedTx, process.RelayedTxV2:
case process.RelayedTx, process.RelayedTxV2, process.RelayedTxV3:
// TODO implement in the next PR
Copy link
Contributor

Choose a reason for hiding this comment

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

let's add a task for this on Jira - a long forgotten TODO.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

relayerAcnt, acntDst state.UserAccountHandler,
) (vmcommon.ReturnCode, error) {
if !txProc.enableEpochsHandler.IsRelayedTransactionsV3FlagEnabled() {
return vmcommon.UserError, txProc.executingFailedTransaction(tx, relayerAcnt, process.ErrRelayedTxV3Disabled)
Copy link
Contributor

Choose a reason for hiding this comment

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

this has to be backward compatible. So let's make sure that TX is not accepted in the pool if it is of RelayedV3 and the flag is not active. This check should be done at transaction interceptor level.

The problem is nodes with different software will run at the same time in the first few days of the announcement of the new release.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added

if !bytes.Equal(tx.RcvAddr, userTx.SndAddr) {
return vmcommon.UserError, txProc.executingFailedTransaction(tx, relayerAcnt, process.ErrRelayedTxV3BeneficiaryDoesNotMatchReceiver)
}
if len(userTx.RelayerAddr) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

I do not see the need for the user to put a relayerAddress in his own TX. This was used internally, in case of relayedV1 and v2. It was not the user who field this value, but the protocol in case of processing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added on inner txs only, for extra check on relayed v3, as mentioned above

Copy link
Contributor

Choose a reason for hiding this comment

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

add the full check here as well userTx.RelayerAddr = tx.SenderAddr

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added

api/groups/transactionGroup.go Show resolved Hide resolved
Version: minTxVersion,
InnerTransaction: innerTx,
}
txi, _ := createInterceptedTxFromPlainTxWithArgParser(tx)
Copy link
Contributor

Choose a reason for hiding this comment

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

this test is a bit long, could you create separate t.run for the cases tested ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

assert.Equal(t, process.ErrFailedTransaction, err)
assert.Equal(t, vmcommon.UserError, returnCode)
})
t.Run("value on relayed tx should error", func(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

"value on relay ...tx"?
the relayed tx is the user 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.

fixed

AdoAdoAdo
AdoAdoAdo previously approved these changes Oct 5, 2023
… to be the same with parent tx sender and removed skip for balance check as it is not needed anymore
@sstanculeanu sstanculeanu merged commit 34e8ba4 into feat/relayedv3 Oct 11, 2023
5 checks passed
@sstanculeanu sstanculeanu deleted the relayedV3 branch October 11, 2023 07:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants