github.com/klaytn/klaytn@v1.10.2/tests/tx_fee_ratio_range_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 "crypto/ecdsa" 21 "fmt" 22 "math/big" 23 "testing" 24 "time" 25 26 "github.com/klaytn/klaytn/blockchain" 27 "github.com/klaytn/klaytn/blockchain/types" 28 "github.com/klaytn/klaytn/blockchain/types/accountkey" 29 "github.com/klaytn/klaytn/common" 30 "github.com/klaytn/klaytn/common/profile" 31 "github.com/klaytn/klaytn/crypto" 32 "github.com/klaytn/klaytn/kerrors" 33 "github.com/klaytn/klaytn/log" 34 "github.com/klaytn/klaytn/params" 35 "github.com/stretchr/testify/assert" 36 ) 37 38 // TestTxFeeRatioRange checks the range of the fee ratio. 39 func TestTxFeeRatioRange(t *testing.T) { 40 testCases := []struct { 41 feeRatio types.FeeRatio 42 expected error 43 }{ 44 {0, kerrors.ErrFeeRatioOutOfRange}, 45 {1, nil}, 46 {99, nil}, 47 {100, kerrors.ErrFeeRatioOutOfRange}, 48 } 49 50 for _, test := range testCases { 51 name := fmt.Sprintf("%d", test.feeRatio) 52 t.Run(name, func(t *testing.T) { 53 testTxFeeRatioRange(t, test.feeRatio, test.expected) 54 }) 55 } 56 } 57 58 func testTxFeeRatioRange(t *testing.T, feeRatio types.FeeRatio, expected error) { 59 log.EnableLogForTest(log.LvlCrit, log.LvlTrace) 60 prof := profile.NewProfiler() 61 62 // Initialize blockchain 63 start := time.Now() 64 bcdata, err := NewBCData(6, 4) 65 if err != nil { 66 t.Fatal(err) 67 } 68 prof.Profile("main_init_blockchain", time.Now().Sub(start)) 69 defer bcdata.Shutdown() 70 71 // Initialize address-balance map for verification 72 start = time.Now() 73 accountMap := NewAccountMap() 74 if err := accountMap.Initialize(bcdata); err != nil { 75 t.Fatal(err) 76 } 77 prof.Profile("main_init_accountMap", time.Now().Sub(start)) 78 79 // reservoir account 80 reservoir := &TestAccountType{ 81 Addr: *bcdata.addrs[0], 82 Keys: []*ecdsa.PrivateKey{bcdata.privKeys[0]}, 83 Nonce: uint64(0), 84 } 85 86 reservoir2 := &TestAccountType{ 87 Addr: *bcdata.addrs[1], 88 Keys: []*ecdsa.PrivateKey{bcdata.privKeys[1]}, 89 Nonce: uint64(0), 90 } 91 92 reservoir3 := &TestAccountType{ 93 Addr: *bcdata.addrs[2], 94 Keys: []*ecdsa.PrivateKey{bcdata.privKeys[2]}, 95 Nonce: uint64(0), 96 } 97 98 contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989") 99 assert.Equal(t, nil, err) 100 101 code := common.FromHex("0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029") 102 103 signer := types.MakeSigner(bcdata.bc.Config(), bcdata.bc.CurrentHeader().Number) 104 105 gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice) 106 107 // 0. Initial setting: deploy a smart contract to execute later 108 { 109 var txs types.Transactions 110 111 amount := new(big.Int).SetUint64(0) 112 113 values := map[types.TxValueKeyType]interface{}{ 114 types.TxValueKeyNonce: reservoir.Nonce, 115 types.TxValueKeyFrom: reservoir.Addr, 116 types.TxValueKeyTo: (*common.Address)(nil), 117 types.TxValueKeyAmount: amount, 118 types.TxValueKeyGasLimit: gasLimit, 119 types.TxValueKeyGasPrice: gasPrice, 120 types.TxValueKeyHumanReadable: false, 121 types.TxValueKeyData: code, 122 types.TxValueKeyCodeFormat: params.CodeFormatEVM, 123 } 124 tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values) 125 assert.Equal(t, nil, err) 126 127 err = tx.SignWithKeys(signer, reservoir.Keys) 128 assert.Equal(t, nil, err) 129 130 txs = append(txs, tx) 131 132 if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil { 133 t.Fatal(err) 134 } 135 136 contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce) 137 138 reservoir.Nonce += 1 139 } 140 141 // make TxPool to test validation in 'TxPool add' process 142 txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc) 143 144 // 1. TxTypeFeeDelegatedValueTransferWithRatio 145 { 146 amount := new(big.Int).SetUint64(10000) 147 values := map[types.TxValueKeyType]interface{}{ 148 types.TxValueKeyNonce: reservoir.Nonce, 149 types.TxValueKeyFrom: reservoir.Addr, 150 types.TxValueKeyTo: reservoir3.Addr, 151 types.TxValueKeyAmount: amount, 152 types.TxValueKeyGasLimit: gasLimit, 153 types.TxValueKeyGasPrice: gasPrice, 154 types.TxValueKeyFeePayer: reservoir2.Addr, 155 types.TxValueKeyFeeRatioOfFeePayer: feeRatio, 156 } 157 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransferWithRatio, values) 158 assert.Equal(t, nil, err) 159 160 err = tx.SignWithKeys(signer, reservoir.Keys) 161 assert.Equal(t, nil, err) 162 163 err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys) 164 assert.Equal(t, nil, err) 165 166 err = txpool.AddRemote(tx) 167 assert.Equal(t, expected, err) 168 169 reservoir.Nonce += 1 170 } 171 172 // 2. TxTypeFeeDelegatedValueTransferMemoWithRatio 173 { 174 amount := new(big.Int).SetUint64(10000) 175 values := map[types.TxValueKeyType]interface{}{ 176 types.TxValueKeyNonce: reservoir.Nonce, 177 types.TxValueKeyFrom: reservoir.Addr, 178 types.TxValueKeyTo: reservoir3.Addr, 179 types.TxValueKeyAmount: amount, 180 types.TxValueKeyGasLimit: gasLimit, 181 types.TxValueKeyGasPrice: gasPrice, 182 types.TxValueKeyData: []byte("hello"), 183 types.TxValueKeyFeePayer: reservoir2.Addr, 184 types.TxValueKeyFeeRatioOfFeePayer: feeRatio, 185 } 186 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransferMemoWithRatio, values) 187 assert.Equal(t, nil, err) 188 189 err = tx.SignWithKeys(signer, reservoir.Keys) 190 assert.Equal(t, nil, err) 191 192 err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys) 193 assert.Equal(t, nil, err) 194 195 err = txpool.AddRemote(tx) 196 assert.Equal(t, expected, err) 197 198 reservoir.Nonce += 1 199 } 200 201 // 3. TxTypeFeeDelegatedAccountUpdateWithRatio 202 { 203 values := map[types.TxValueKeyType]interface{}{ 204 types.TxValueKeyNonce: reservoir.Nonce, 205 types.TxValueKeyFrom: reservoir.Addr, 206 types.TxValueKeyGasLimit: gasLimit, 207 types.TxValueKeyGasPrice: gasPrice, 208 types.TxValueKeyAccountKey: accountkey.NewAccountKeyPublicWithValue(&reservoir.Keys[0].PublicKey), 209 types.TxValueKeyFeePayer: reservoir2.Addr, 210 types.TxValueKeyFeeRatioOfFeePayer: feeRatio, 211 } 212 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedAccountUpdateWithRatio, values) 213 assert.Equal(t, nil, err) 214 215 err = tx.SignWithKeys(signer, reservoir.Keys) 216 assert.Equal(t, nil, err) 217 218 err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys) 219 assert.Equal(t, nil, err) 220 221 err = txpool.AddRemote(tx) 222 assert.Equal(t, expected, err) 223 224 reservoir.Nonce += 1 225 } 226 227 // 4, TxTypeFeeDelegatedSmartContractDeployWithRatio 228 { 229 amount := new(big.Int).SetUint64(10000) 230 values := map[types.TxValueKeyType]interface{}{ 231 types.TxValueKeyNonce: reservoir.Nonce, 232 types.TxValueKeyFrom: reservoir.Addr, 233 types.TxValueKeyTo: (*common.Address)(nil), 234 types.TxValueKeyAmount: amount, 235 types.TxValueKeyGasLimit: gasLimit, 236 types.TxValueKeyGasPrice: gasPrice, 237 types.TxValueKeyHumanReadable: false, 238 types.TxValueKeyData: []byte{0x80}, 239 types.TxValueKeyFeePayer: reservoir2.Addr, 240 types.TxValueKeyFeeRatioOfFeePayer: feeRatio, 241 types.TxValueKeyCodeFormat: params.CodeFormatEVM, 242 } 243 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractDeployWithRatio, values) 244 assert.Equal(t, nil, err) 245 246 err = tx.SignWithKeys(signer, reservoir.Keys) 247 assert.Equal(t, nil, err) 248 249 err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys) 250 assert.Equal(t, nil, err) 251 252 err = txpool.AddRemote(tx) 253 assert.Equal(t, expected, err) 254 255 reservoir.Nonce += 1 256 } 257 258 // 5. TxTypeFeeDelegatedSmartContractExecutionWithRatio 259 { 260 amount := new(big.Int).SetUint64(10000) 261 values := map[types.TxValueKeyType]interface{}{ 262 types.TxValueKeyNonce: reservoir.Nonce, 263 types.TxValueKeyFrom: reservoir.Addr, 264 types.TxValueKeyTo: contract.Addr, 265 types.TxValueKeyAmount: amount, 266 types.TxValueKeyGasLimit: gasLimit, 267 types.TxValueKeyGasPrice: gasPrice, 268 types.TxValueKeyData: []byte{0x80}, 269 types.TxValueKeyFeePayer: reservoir2.Addr, 270 types.TxValueKeyFeeRatioOfFeePayer: feeRatio, 271 } 272 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractExecutionWithRatio, values) 273 assert.Equal(t, nil, err) 274 275 err = tx.SignWithKeys(signer, reservoir.Keys) 276 assert.Equal(t, nil, err) 277 278 err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys) 279 assert.Equal(t, nil, err) 280 281 err = txpool.AddRemote(tx) 282 assert.Equal(t, expected, err) 283 284 reservoir.Nonce += 1 285 } 286 287 // 6. TxTypeFeeDelegatedCancelWithRatio 288 { 289 values := map[types.TxValueKeyType]interface{}{ 290 types.TxValueKeyNonce: reservoir.Nonce, 291 types.TxValueKeyFrom: reservoir.Addr, 292 types.TxValueKeyGasLimit: gasLimit, 293 types.TxValueKeyGasPrice: gasPrice, 294 types.TxValueKeyFeePayer: reservoir2.Addr, 295 types.TxValueKeyFeeRatioOfFeePayer: feeRatio, 296 } 297 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedCancelWithRatio, values) 298 assert.Equal(t, nil, err) 299 300 err = tx.SignWithKeys(signer, reservoir.Keys) 301 assert.Equal(t, nil, err) 302 303 err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys) 304 assert.Equal(t, nil, err) 305 306 err = txpool.AddRemote(tx) 307 assert.Equal(t, expected, err) 308 309 reservoir.Nonce += 1 310 } 311 }