github.com/klaytn/klaytn@v1.10.2/tests/tx_gas_overflow_test.go (about)

     1  // Copyright 2019 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The klaytn library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package tests
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/klaytn/klaytn/blockchain"
    23  	"github.com/klaytn/klaytn/blockchain/types"
    24  	"github.com/klaytn/klaytn/blockchain/types/accountkey"
    25  	"github.com/klaytn/klaytn/common/math"
    26  	"github.com/klaytn/klaytn/params"
    27  )
    28  
    29  type overflowCheckFunc func(t *testing.T)
    30  
    31  func TestGasOverflow(t *testing.T) {
    32  	testFunctions := []struct {
    33  		Name                 string
    34  		gasOverflowCheckFunc overflowCheckFunc
    35  	}{
    36  		{"LegacyTransaction", testGasOverflowLegacyTransaction},
    37  
    38  		{"ValueTransfer", testGasOverflowValueTransfer},
    39  		{"FeeDelegatedValueTransfer", testGasOverflowFeeDelegatedValueTransfer},
    40  		{"FeeDelegatedWithRatioValueTransfer", testGasOverflowFeeDelegatedWithRatioValueTransfer},
    41  
    42  		{"ValueTransferWithMemo", testGasOverflowValueTransferWithMemo},
    43  		{"FeeDelegatedValueTransferWithMemo", testGasOverflowFeeDelegatedValueTransferWithMemo},
    44  		{"FeeDelegatedWithRatioValueTransferWithMemo", testGasOverflowFeeDelegatedWithRatioValueTransferWithMemo},
    45  
    46  		{"AccountUpdate", testGasOverflowAccountUpdate},
    47  		{"FeeDelegatedAccountUpdate", testGasOverflowFeeDelegatedAccountUpdate},
    48  		{"FeeDelegatedWithRatioAccountUpdate", testGasOverflowFeeDelegatedWithRatioAccountUpdate},
    49  
    50  		{"SmartContractDeploy", testGasOverflowSmartContractDeploy},
    51  		{"FeeDelegatedSmartContractDeploy", testGasOverflowFeeDelegatedSmartContractDeploy},
    52  		{"FeeDelegatedWithRatioSmartContractDeploy", testGasOverflowFeeDelegatedWithRatioSmartContractDeploy},
    53  
    54  		{"SmartContractExecution", testGasOverflowSmartContractExecution},
    55  		{"FeeDelegatedSmartContractExecution", testGasOverflowFeeDelegatedSmartContractExecution},
    56  		{"FeeDelegatedWithRatioSmartContractExecution", testGasOverflowFeeDelegatedWithRatioSmartContractExecution},
    57  
    58  		{"Cancel", testGasOverflowCancel},
    59  		{"FeeDelegatedCancel", testGasOverflowFeeDelegatedCancel},
    60  		{"FeeDelegatedWithRatioCancel", testGasOverflowFeeDelegatedWithRatioCancel},
    61  
    62  		{"ChainDataAnchoring", testGasOverflowChainDataAnchoring},
    63  		{"FeeDelegatedChainDataAnchoring", testGasOverflowFeeDelegatedChainDataAnchoring},
    64  		{"FeeDelegatedWithRatioChainDataAnchoring", testGasOverflowFeeDelegatedWithRatioChainDataAnchoring},
    65  	}
    66  
    67  	for _, f := range testFunctions {
    68  		t.Run(f.Name, func(t *testing.T) {
    69  			f.gasOverflowCheckFunc(t)
    70  		})
    71  	}
    72  }
    73  
    74  func testGasOverflowLegacyTransaction(t *testing.T) {
    75  	intrinsic := getIntrinsicGas(types.TxTypeLegacyTransaction)
    76  	senderValidationGas := getMaxValidationKeyGas(t)
    77  
    78  	maxDataGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataNonZeroGas)
    79  
    80  	gas := addUint64(t, intrinsic, senderValidationGas)
    81  	gas = addUint64(t, gas, maxDataGas)
    82  }
    83  
    84  func testGasOverflowValueTransfer(t *testing.T) {
    85  	intrinsic := getIntrinsicGas(types.TxTypeValueTransfer)
    86  	senderValidationGas := getMaxValidationKeyGas(t)
    87  
    88  	addUint64(t, intrinsic, senderValidationGas)
    89  }
    90  
    91  func testGasOverflowFeeDelegatedValueTransfer(t *testing.T) {
    92  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedValueTransfer)
    93  	senderValidationGas := getMaxValidationKeyGas(t)
    94  	payerValidationGas := getMaxValidationKeyGas(t)
    95  
    96  	gas := addUint64(t, intrinsic, senderValidationGas)
    97  	gas = addUint64(t, gas, payerValidationGas)
    98  }
    99  
   100  func testGasOverflowFeeDelegatedWithRatioValueTransfer(t *testing.T) {
   101  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedValueTransferWithRatio)
   102  	senderValidationGas := getMaxValidationKeyGas(t)
   103  	payerValidationGas := getMaxValidationKeyGas(t)
   104  
   105  	gas := addUint64(t, intrinsic, senderValidationGas)
   106  	gas = addUint64(t, gas, payerValidationGas)
   107  }
   108  
   109  func testGasOverflowValueTransferWithMemo(t *testing.T) {
   110  	intrinsic := getIntrinsicGas(types.TxTypeValueTransferMemo)
   111  	senderValidationGas := getMaxValidationKeyGas(t)
   112  
   113  	maxDataGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   114  
   115  	gas := addUint64(t, intrinsic, senderValidationGas)
   116  	gas = addUint64(t, gas, maxDataGas)
   117  }
   118  
   119  func testGasOverflowFeeDelegatedValueTransferWithMemo(t *testing.T) {
   120  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedValueTransferMemo)
   121  	senderValidationGas := getMaxValidationKeyGas(t)
   122  	payerValidationGas := getMaxValidationKeyGas(t)
   123  
   124  	maxDataGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   125  
   126  	gas := addUint64(t, intrinsic, senderValidationGas)
   127  	gas = addUint64(t, gas, payerValidationGas)
   128  	gas = addUint64(t, gas, maxDataGas)
   129  }
   130  
   131  func testGasOverflowFeeDelegatedWithRatioValueTransferWithMemo(t *testing.T) {
   132  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedValueTransferMemoWithRatio)
   133  	senderValidationGas := getMaxValidationKeyGas(t)
   134  	payerValidationGas := getMaxValidationKeyGas(t)
   135  
   136  	maxDataGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   137  
   138  	gas := addUint64(t, intrinsic, senderValidationGas)
   139  	gas = addUint64(t, gas, payerValidationGas)
   140  	gas = addUint64(t, gas, maxDataGas)
   141  }
   142  
   143  func testGasOverflowAccountUpdate(t *testing.T) {
   144  	intrinsic := getIntrinsicGas(types.TxTypeAccountUpdate)
   145  	senderValidationGas := getMaxValidationKeyGas(t)
   146  
   147  	maxCreationGas := getMaxCreationKeyGas(t)
   148  
   149  	gas := addUint64(t, intrinsic, senderValidationGas)
   150  	gas = addUint64(t, gas, maxCreationGas)
   151  }
   152  
   153  func testGasOverflowFeeDelegatedAccountUpdate(t *testing.T) {
   154  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedAccountUpdate)
   155  	senderValidationGas := getMaxValidationKeyGas(t)
   156  	payerValidationGas := getMaxValidationKeyGas(t)
   157  
   158  	maxCreationGas := getMaxCreationKeyGas(t)
   159  
   160  	gas := addUint64(t, intrinsic, senderValidationGas)
   161  	gas = addUint64(t, gas, payerValidationGas)
   162  	gas = addUint64(t, gas, maxCreationGas)
   163  }
   164  
   165  func testGasOverflowFeeDelegatedWithRatioAccountUpdate(t *testing.T) {
   166  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedAccountUpdateWithRatio)
   167  	senderValidationGas := getMaxValidationKeyGas(t)
   168  	payerValidationGas := getMaxValidationKeyGas(t)
   169  
   170  	maxCreationGas := getMaxCreationKeyGas(t)
   171  
   172  	gas := addUint64(t, intrinsic, senderValidationGas)
   173  	gas = addUint64(t, gas, payerValidationGas)
   174  	gas = addUint64(t, gas, maxCreationGas)
   175  }
   176  
   177  func testGasOverflowSmartContractDeploy(t *testing.T) {
   178  	intrinsic := getIntrinsicGas(types.TxTypeSmartContractDeploy)
   179  	senderValidationGas := getMaxValidationKeyGas(t)
   180  
   181  	payloadGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   182  
   183  	humanReadableGas := params.TxGasHumanReadable
   184  
   185  	gas := addUint64(t, intrinsic, senderValidationGas)
   186  	gas = addUint64(t, gas, payloadGas)
   187  	gas = addUint64(t, gas, humanReadableGas)
   188  }
   189  
   190  func testGasOverflowFeeDelegatedSmartContractDeploy(t *testing.T) {
   191  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedSmartContractDeploy)
   192  	senderValidationGas := getMaxValidationKeyGas(t)
   193  	payerValidationGas := getMaxValidationKeyGas(t)
   194  
   195  	payloadGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   196  
   197  	humanReadableGas := params.TxGasHumanReadable
   198  
   199  	gas := addUint64(t, intrinsic, senderValidationGas)
   200  	gas = addUint64(t, gas, payerValidationGas)
   201  	gas = addUint64(t, gas, payloadGas)
   202  	gas = addUint64(t, gas, humanReadableGas)
   203  }
   204  
   205  func testGasOverflowFeeDelegatedWithRatioSmartContractDeploy(t *testing.T) {
   206  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedSmartContractDeployWithRatio)
   207  	senderValidationGas := getMaxValidationKeyGas(t)
   208  	payerValidationGas := getMaxValidationKeyGas(t)
   209  
   210  	payloadGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   211  
   212  	humanReadableGas := params.TxGasHumanReadable
   213  
   214  	gas := addUint64(t, intrinsic, senderValidationGas)
   215  	gas = addUint64(t, gas, payerValidationGas)
   216  	gas = addUint64(t, gas, payloadGas)
   217  	gas = addUint64(t, gas, humanReadableGas)
   218  }
   219  
   220  func testGasOverflowSmartContractExecution(t *testing.T) {
   221  	intrinsic := getIntrinsicGas(types.TxTypeSmartContractExecution)
   222  	senderValidationGas := getMaxValidationKeyGas(t)
   223  
   224  	payloadGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   225  
   226  	gas := addUint64(t, intrinsic, senderValidationGas)
   227  	gas = addUint64(t, gas, payloadGas)
   228  }
   229  
   230  func testGasOverflowFeeDelegatedSmartContractExecution(t *testing.T) {
   231  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedSmartContractExecution)
   232  	senderValidationGas := getMaxValidationKeyGas(t)
   233  	payerValidationGas := getMaxValidationKeyGas(t)
   234  
   235  	payloadGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   236  
   237  	gas := addUint64(t, intrinsic, senderValidationGas)
   238  	gas = addUint64(t, gas, payerValidationGas)
   239  	gas = addUint64(t, gas, payloadGas)
   240  }
   241  
   242  func testGasOverflowFeeDelegatedWithRatioSmartContractExecution(t *testing.T) {
   243  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedSmartContractExecutionWithRatio)
   244  	senderValidationGas := getMaxValidationKeyGas(t)
   245  	payerValidationGas := getMaxValidationKeyGas(t)
   246  
   247  	payloadGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   248  
   249  	gas := addUint64(t, intrinsic, senderValidationGas)
   250  	gas = addUint64(t, gas, payerValidationGas)
   251  	gas = addUint64(t, gas, payloadGas)
   252  }
   253  
   254  func testGasOverflowCancel(t *testing.T) {
   255  	intrinsic := getIntrinsicGas(types.TxTypeCancel)
   256  	senderValidationGas := getMaxValidationKeyGas(t)
   257  
   258  	addUint64(t, intrinsic, senderValidationGas)
   259  }
   260  
   261  func testGasOverflowFeeDelegatedCancel(t *testing.T) {
   262  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedCancel)
   263  	senderValidationGas := getMaxValidationKeyGas(t)
   264  	payerValidationGas := getMaxValidationKeyGas(t)
   265  
   266  	gas := addUint64(t, intrinsic, senderValidationGas)
   267  	gas = addUint64(t, gas, payerValidationGas)
   268  }
   269  
   270  func testGasOverflowFeeDelegatedWithRatioCancel(t *testing.T) {
   271  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedCancelWithRatio)
   272  	senderValidationGas := getMaxValidationKeyGas(t)
   273  	payerValidationGas := getMaxValidationKeyGas(t)
   274  
   275  	gas := addUint64(t, intrinsic, senderValidationGas)
   276  	gas = addUint64(t, gas, payerValidationGas)
   277  }
   278  
   279  func testGasOverflowChainDataAnchoring(t *testing.T) {
   280  	intrinsic := getIntrinsicGas(types.TxTypeChainDataAnchoring)
   281  	senderValidationGas := getMaxValidationKeyGas(t)
   282  
   283  	maxDataGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   284  
   285  	gas := addUint64(t, intrinsic, senderValidationGas)
   286  	gas = addUint64(t, gas, maxDataGas)
   287  }
   288  
   289  func testGasOverflowFeeDelegatedChainDataAnchoring(t *testing.T) {
   290  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedChainDataAnchoring)
   291  	senderValidationGas := getMaxValidationKeyGas(t)
   292  	payerValidationGas := getMaxValidationKeyGas(t)
   293  
   294  	maxDataGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   295  
   296  	gas := addUint64(t, intrinsic, senderValidationGas)
   297  	gas = addUint64(t, gas, payerValidationGas)
   298  	gas = addUint64(t, gas, maxDataGas)
   299  }
   300  
   301  func testGasOverflowFeeDelegatedWithRatioChainDataAnchoring(t *testing.T) {
   302  	intrinsic := getIntrinsicGas(types.TxTypeFeeDelegatedChainDataAnchoringWithRatio)
   303  	senderValidationGas := getMaxValidationKeyGas(t)
   304  	payerValidationGas := getMaxValidationKeyGas(t)
   305  
   306  	maxDataGas := mulUint64(t, blockchain.MaxTxDataSize, params.TxDataGas)
   307  
   308  	gas := addUint64(t, intrinsic, senderValidationGas)
   309  	gas = addUint64(t, gas, payerValidationGas)
   310  	gas = addUint64(t, gas, maxDataGas)
   311  }
   312  
   313  func getMaxValidationKeyGas(t *testing.T) uint64 {
   314  	return mulUint64(t, uint64(accountkey.MaxNumKeysForMultiSig), params.TxValidationGasPerKey)
   315  }
   316  
   317  func getMaxCreationKeyGas(t *testing.T) uint64 {
   318  	txKeyGas := mulUint64(t, uint64(accountkey.MaxNumKeysForMultiSig), params.TxAccountCreationGasPerKey)
   319  	updateKeyGas := mulUint64(t, uint64(accountkey.MaxNumKeysForMultiSig), params.TxAccountCreationGasPerKey)
   320  	feeKeysGas := mulUint64(t, uint64(accountkey.MaxNumKeysForMultiSig), params.TxAccountCreationGasPerKey)
   321  
   322  	creationKey := addUint64(t, txKeyGas, updateKeyGas)
   323  	creationKey = addUint64(t, creationKey, feeKeysGas)
   324  
   325  	return creationKey
   326  }
   327  
   328  func addUint64(t *testing.T, a uint64, b uint64) uint64 {
   329  	c, overflow := math.SafeAdd(a, b)
   330  	if overflow {
   331  		t.Error("gas overflow ", a, "+", b)
   332  	}
   333  	return c
   334  }
   335  
   336  func mulUint64(t *testing.T, a uint64, b uint64) uint64 {
   337  	c, overflow := math.SafeMul(a, b)
   338  	if overflow {
   339  		t.Error("gas overflow ", a, "*", b)
   340  	}
   341  	return c
   342  }