Skip to content

Commit

Permalink
- fix max gas limit on executor
Browse files Browse the repository at this point in the history
  • Loading branch information
iulianpascalau committed Oct 17, 2024
1 parent 3f4ddc1 commit 5426764
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
6 changes: 6 additions & 0 deletions executors/multiversx/scCallsExecutor.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
scProxyCallFunction = "execute"
minCheckValues = 1
transactionNotFoundErrString = "transaction not found"
maxGasLimitToExecute = 249999999 // 250 million - 1
)

// ArgsScCallExecutor represents the DTO struct for creating a new instance of type scCallExecutor
Expand Down Expand Up @@ -280,6 +281,11 @@ func (executor *scCallExecutor) executeOperation(
Value: "0",
}

if tx.GasLimit > maxGasLimitToExecute {
executor.log.Warn("capped the gas limit", "computed gas limit", tx.GasLimit, "capped to", maxGasLimitToExecute)
tx.GasLimit = maxGasLimitToExecute
}

err = executor.nonceTxHandler.ApplyNonceAndGasPrice(ctx, executor.senderAddress, tx)
if err != nil {
return err
Expand Down
93 changes: 93 additions & 0 deletions executors/multiversx/scCallsExecutor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,99 @@ func TestScCallExecutor_Execute(t *testing.T) {

executor, _ := NewScCallExecutor(args)

err := executor.Execute(context.Background())
assert.Nil(t, err)
assert.True(t, sendWasCalled)
assert.Equal(t, uint32(1), executor.GetNumSentTransaction())
})
t.Run("should work even if the gas limit exceeds the maximum allowed", func(t *testing.T) {
t.Parallel()

args := createMockArgsScCallExecutor()

nonceCounter := uint64(100)
sendWasCalled := false

args.Proxy = &interactors.ProxyStub{
ExecuteVMQueryCalled: func(ctx context.Context, vmRequest *data.VmValueRequest) (*data.VmValuesResponseData, error) {
assert.Equal(t, args.ScProxyBech32Address, vmRequest.Address)
assert.Equal(t, getPendingTransactionsFunction, vmRequest.FuncName)

return &data.VmValuesResponseData{
Data: &vm.VMOutputApi{
ReturnCode: okCodeAfterExecution,
ReturnData: [][]byte{
{0x01},
[]byte("ProxySCCompleteCallData 1"),
{0x02},
[]byte("ProxySCCompleteCallData 2"),
},
},
}, nil
},
GetNetworkConfigCalled: func(ctx context.Context) (*data.NetworkConfig, error) {
return &data.NetworkConfig{
ChainID: "TEST",
MinTransactionVersion: 111,
}, nil
},
}
args.Codec = &testsCommon.MultiversxCodecStub{
DecodeProxySCCompleteCallDataCalled: func(buff []byte) (parsers.ProxySCCompleteCallData, error) {
if string(buff) == "ProxySCCompleteCallData 1" {
return createTestProxySCCompleteCallData("tkn1"), nil
}
if string(buff) == "ProxySCCompleteCallData 2" {
return createTestProxySCCompleteCallData("tkn2"), nil
}

return parsers.ProxySCCompleteCallData{}, errors.New("wrong buffer")
},
ExtractGasLimitFromRawCallDataCalled: func(buff []byte) (uint64, error) {
return maxGasLimitToExecute - args.ExtraGasToExecute + 1, nil
},
}
args.Filter = &testsCommon.ScCallsExecuteFilterStub{
ShouldExecuteCalled: func(callData parsers.ProxySCCompleteCallData) bool {
return callData.Token == "tkn2"
},
}
args.NonceTxHandler = &testsCommon.TxNonceHandlerV2Stub{
ApplyNonceAndGasPriceCalled: func(ctx context.Context, address core.AddressHandler, tx *transaction.FrontendTransaction) error {
tx.Nonce = nonceCounter
tx.GasPrice = 101010
nonceCounter++
return nil
},
SendTransactionCalled: func(ctx context.Context, tx *transaction.FrontendTransaction) (string, error) {
assert.Equal(t, "TEST", tx.ChainID)
assert.Equal(t, uint32(111), tx.Version)
assert.Equal(t, uint64(maxGasLimitToExecute), tx.GasLimit) // the cap was done
assert.Equal(t, nonceCounter-1, tx.Nonce)
assert.Equal(t, uint64(101010), tx.GasPrice)
assert.Equal(t, hex.EncodeToString([]byte("sig")), tx.Signature)
_, err := data.NewAddressFromBech32String(tx.Sender)
assert.Nil(t, err)
assert.Equal(t, "erd1qqqqqqqqqqqqqpgqk839entmk46ykukvhpn90g6knskju3dtanaq20f66e", tx.Receiver)
assert.Equal(t, "0", tx.Value)

// only the second pending operation gor through the filter
expectedData := scProxyCallFunction + "@02"
assert.Equal(t, expectedData, string(tx.Data))

sendWasCalled = true

return "", nil
},
}
args.SingleSigner = &testCrypto.SingleSignerStub{
SignCalled: func(private crypto.PrivateKey, msg []byte) ([]byte, error) {
return []byte("sig"), nil
},
}

executor, _ := NewScCallExecutor(args)

err := executor.Execute(context.Background())
assert.Nil(t, err)
assert.True(t, sendWasCalled)
Expand Down

0 comments on commit 5426764

Please sign in to comment.