github.com/klaytn/klaytn@v1.10.2/accounts/abi/bind/backends/simulated_test.go (about) 1 // Modifications Copyright 2020 The klaytn Authors 2 // Copyright 2019 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from accounts/abi/bind/backends/simulated_test.go(2020/11/24). 19 // Modified and improved for the klaytn development. 20 21 package backends 22 23 import ( 24 "bytes" 25 "context" 26 "math/big" 27 "strings" 28 "testing" 29 "time" 30 31 "github.com/klaytn/klaytn" 32 "github.com/klaytn/klaytn/accounts/abi" 33 "github.com/klaytn/klaytn/accounts/abi/bind" 34 "github.com/klaytn/klaytn/blockchain" 35 "github.com/klaytn/klaytn/blockchain/types" 36 "github.com/klaytn/klaytn/common" 37 "github.com/klaytn/klaytn/crypto" 38 "github.com/klaytn/klaytn/params" 39 ) 40 41 func TestSimulatedBackend(t *testing.T) { 42 key, _ := crypto.GenerateKey() // nolint: gosec 43 auth := bind.NewKeyedTransactor(key) 44 genAlloc := make(blockchain.GenesisAlloc) 45 genAlloc[auth.From] = blockchain.GenesisAccount{Balance: big.NewInt(9223372036854775807)} 46 47 sim := NewSimulatedBackend(genAlloc) 48 defer sim.Close() 49 50 // should return an error if the tx is not found 51 txHash := common.HexToHash("2") 52 _, isPending, err := sim.TransactionByHash(context.Background(), txHash) 53 54 if isPending { 55 t.Fatal("transaction should not be pending") 56 } 57 if err != klaytn.NotFound { 58 t.Fatalf("err should be `klaytn.NotFound` but received %v", err) 59 } 60 61 // generate a transaction and confirm you can retrieve it 62 code := `6060604052600a8060106000396000f360606040526008565b00` 63 var gas uint64 = 3000000 64 tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code)) 65 tx, _ = types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), key) 66 67 err = sim.SendTransaction(context.Background(), tx) 68 if err != nil { 69 t.Fatal("error sending transaction") 70 } 71 72 txHash = tx.Hash() 73 _, isPending, err = sim.TransactionByHash(context.Background(), txHash) 74 if err != nil { 75 t.Fatalf("error getting transaction with hash: %v", txHash.String()) 76 } 77 if !isPending { 78 t.Fatal("transaction should have pending status") 79 } 80 81 sim.Commit() 82 _, isPending, err = sim.TransactionByHash(context.Background(), txHash) 83 if err != nil { 84 t.Fatalf("error getting transaction with hash: %v", txHash.String()) 85 } 86 if isPending { 87 t.Fatal("transaction should not have pending status") 88 } 89 } 90 91 var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 92 93 // the following is based on this contract: 94 // contract T { 95 // event received(address sender, uint amount, bytes memo); 96 // event receivedAddr(address sender); 97 // 98 // function receive(bytes calldata memo) external payable returns (string memory res) { 99 // emit received(msg.sender, msg.value, memo); 100 // emit receivedAddr(msg.sender); 101 // return "hello world"; 102 // } 103 // } 104 const abiJSON = `[ { "constant": false, "inputs": [ { "name": "memo", "type": "bytes" } ], "name": "receive", "outputs": [ { "name": "res", "type": "string" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "memo", "type": "bytes" } ], "name": "received", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" } ], "name": "receivedAddr", "type": "event" } ]` 105 106 const ( 107 abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` 108 deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` 109 ) 110 111 // expected return value contains "hello world" 112 var expectedReturn = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 113 114 func simTestBackend(testAddr common.Address) *SimulatedBackend { 115 return NewSimulatedBackend( 116 blockchain.GenesisAlloc{ 117 testAddr: {Balance: big.NewInt(10000000000)}, 118 }, 119 ) 120 } 121 122 func TestNewSimulatedBackend(t *testing.T) { 123 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 124 expectedBal := big.NewInt(10000000000) 125 sim := simTestBackend(testAddr) 126 defer sim.Close() 127 128 if sim.config != params.AllGxhashProtocolChanges { 129 t.Errorf("expected sim config to equal params.AllGxhashProtocolChanges, got %v", sim.config) 130 } 131 132 if sim.blockchain.Config() != params.AllGxhashProtocolChanges { 133 t.Errorf("expected sim blockchain config to equal params.AllGxhashProtocolChanges, got %v", sim.config) 134 } 135 136 stateDB, _ := sim.blockchain.State() 137 bal := stateDB.GetBalance(testAddr) 138 if bal.Cmp(expectedBal) != 0 { 139 t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) 140 } 141 } 142 143 func TestSimulatedBackend_AdjustTime(t *testing.T) { 144 sim := NewSimulatedBackend( 145 blockchain.GenesisAlloc{}, 146 ) 147 defer sim.Close() 148 149 prevTime := sim.pendingBlock.Time() 150 if err := sim.AdjustTime(time.Second); err != nil { 151 t.Error(err) 152 } 153 newTime := sim.pendingBlock.Time() 154 155 if newTime.Uint64()-prevTime.Uint64() != uint64(time.Second.Seconds()) { 156 t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime) 157 } 158 } 159 160 func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) { 161 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 162 sim := simTestBackend(testAddr) 163 // Create tx and send 164 tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 165 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 166 if err != nil { 167 t.Errorf("could not sign tx: %v", err) 168 } 169 sim.SendTransaction(context.Background(), signedTx) 170 // AdjustTime should fail on non-empty block 171 if err := sim.AdjustTime(time.Second); err == nil { 172 t.Error("Expected adjust time to error on non-empty block") 173 } 174 sim.Commit() 175 176 prevTime := sim.pendingBlock.Time() 177 if err := sim.AdjustTime(time.Minute); err != nil { 178 t.Error(err) 179 } 180 newTime := sim.pendingBlock.Time() 181 if newTime.Uint64()-prevTime.Uint64() != uint64(time.Minute.Seconds()) { 182 t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime) 183 } 184 // Put a transaction after adjusting time 185 tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 186 signedTx2, err := types.SignTx(tx2, types.LatestSignerForChainID(sim.config.ChainID), testKey) 187 if err != nil { 188 t.Errorf("could not sign tx: %v", err) 189 } 190 sim.SendTransaction(context.Background(), signedTx2) 191 sim.Commit() 192 newTime = sim.pendingBlock.Time() 193 if newTime.Uint64()-prevTime.Uint64() >= uint64(time.Minute.Seconds()) { 194 t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime) 195 } 196 } 197 198 func TestSimulatedBackend_BalanceAt(t *testing.T) { 199 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 200 expectedBal := big.NewInt(10000000000) 201 sim := simTestBackend(testAddr) 202 defer sim.Close() 203 bgCtx := context.Background() 204 205 bal, err := sim.BalanceAt(bgCtx, testAddr, nil) 206 if err != nil { 207 t.Error(err) 208 } 209 210 if bal.Cmp(expectedBal) != 0 { 211 t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) 212 } 213 } 214 215 func TestSimulatedBackend_BlockByHash(t *testing.T) { 216 sim := NewSimulatedBackend( 217 blockchain.GenesisAlloc{}, 218 ) 219 defer sim.Close() 220 bgCtx := context.Background() 221 222 block, err := sim.BlockByNumber(bgCtx, nil) 223 if err != nil { 224 t.Errorf("could not get recent block: %v", err) 225 } 226 blockByHash, err := sim.BlockByHash(bgCtx, block.Hash()) 227 if err != nil { 228 t.Errorf("could not get recent block: %v", err) 229 } 230 231 if block.Hash() != blockByHash.Hash() { 232 t.Errorf("did not get expected block") 233 } 234 } 235 236 func TestSimulatedBackend_BlockByNumber(t *testing.T) { 237 sim := NewSimulatedBackend( 238 blockchain.GenesisAlloc{}, 239 ) 240 defer sim.Close() 241 bgCtx := context.Background() 242 243 block, err := sim.BlockByNumber(bgCtx, nil) 244 if err != nil { 245 t.Errorf("could not get recent block: %v", err) 246 } 247 if block.NumberU64() != 0 { 248 t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) 249 } 250 251 // create one block 252 sim.Commit() 253 254 block, err = sim.BlockByNumber(bgCtx, nil) 255 if err != nil { 256 t.Errorf("could not get recent block: %v", err) 257 } 258 if block.NumberU64() != 1 { 259 t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) 260 } 261 262 blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 263 if err != nil { 264 t.Errorf("could not get block by number: %v", err) 265 } 266 if blockByNumber.Hash() != block.Hash() { 267 t.Errorf("did not get the same block with height of 1 as before") 268 } 269 } 270 271 func TestSimulatedBackend_NonceAt(t *testing.T) { 272 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 273 274 sim := simTestBackend(testAddr) 275 defer sim.Close() 276 bgCtx := context.Background() 277 278 nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0)) 279 if err != nil { 280 t.Errorf("could not get nonce for test addr: %v", err) 281 } 282 283 if nonce != uint64(0) { 284 t.Errorf("received incorrect nonce. expected 0, got %v", nonce) 285 } 286 287 // create a signed transaction to send 288 tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 289 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 290 if err != nil { 291 t.Errorf("could not sign tx: %v", err) 292 } 293 294 // send tx to simulated backend 295 err = sim.SendTransaction(bgCtx, signedTx) 296 if err != nil { 297 t.Errorf("could not add tx to pending block: %v", err) 298 } 299 sim.Commit() 300 301 newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) 302 if err != nil { 303 t.Errorf("could not get nonce for test addr: %v", err) 304 } 305 306 if newNonce != nonce+uint64(1) { 307 t.Errorf("received incorrect nonce. expected 1, got %v", nonce) 308 } 309 // create some more blocks 310 sim.Commit() 311 // Check that we can get data for an older block/state 312 newNonce, err = sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) 313 if err != nil { 314 t.Fatalf("could not get nonce for test addr: %v", err) 315 } 316 if newNonce != nonce+uint64(1) { 317 t.Fatalf("received incorrect nonce. expected 1, got %v", nonce) 318 } 319 } 320 321 func TestSimulatedBackend_SendTransaction(t *testing.T) { 322 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 323 324 sim := simTestBackend(testAddr) 325 defer sim.Close() 326 bgCtx := context.Background() 327 328 // create a signed transaction to send 329 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 330 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 331 if err != nil { 332 t.Errorf("could not sign tx: %v", err) 333 } 334 335 // send tx to simulated backend 336 err = sim.SendTransaction(bgCtx, signedTx) 337 if err != nil { 338 t.Errorf("could not add tx to pending block: %v", err) 339 } 340 sim.Commit() 341 342 block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 343 if err != nil { 344 t.Errorf("could not get block at height 1: %v", err) 345 } 346 347 if signedTx.Hash() != block.Transactions()[0].Hash() { 348 t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash()) 349 } 350 } 351 352 func TestSimulatedBackend_TransactionByHash(t *testing.T) { 353 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 354 355 sim := simTestBackend(testAddr) 356 defer sim.Close() 357 bgCtx := context.Background() 358 359 // create a signed transaction to send 360 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 361 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 362 if err != nil { 363 t.Errorf("could not sign tx: %v", err) 364 } 365 366 // send tx to simulated backend 367 err = sim.SendTransaction(bgCtx, signedTx) 368 if err != nil { 369 t.Errorf("could not add tx to pending block: %v", err) 370 } 371 372 // ensure tx is committed pending 373 receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash()) 374 if err != nil { 375 t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) 376 } 377 if !pending { 378 t.Errorf("expected transaction to be in pending state") 379 } 380 if receivedTx.Hash() != signedTx.Hash() { 381 t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) 382 } 383 384 sim.Commit() 385 386 // ensure tx is not and committed pending 387 receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash()) 388 if err != nil { 389 t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) 390 } 391 if pending { 392 t.Errorf("expected transaction to not be in pending state") 393 } 394 if receivedTx.Hash() != signedTx.Hash() { 395 t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) 396 } 397 } 398 399 func TestSimulatedBackend_EstimateGas(t *testing.T) { 400 sim := NewSimulatedBackend( 401 blockchain.GenesisAlloc{}, 402 ) 403 defer sim.Close() 404 bgCtx := context.Background() 405 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 406 407 gas, err := sim.EstimateGas(bgCtx, klaytn.CallMsg{ 408 From: testAddr, 409 To: &testAddr, 410 Value: big.NewInt(1000), 411 Data: []byte{}, 412 }) 413 if err != nil { 414 t.Errorf("could not estimate gas: %v", err) 415 } 416 417 if gas != params.TxGas { 418 t.Errorf("expected 21000 gas cost for a transaction got %v", gas) 419 } 420 } 421 422 func TestSimulatedBackend_HeaderByHash(t *testing.T) { 423 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 424 425 sim := simTestBackend(testAddr) 426 defer sim.Close() 427 bgCtx := context.Background() 428 429 header, err := sim.HeaderByNumber(bgCtx, nil) 430 if err != nil { 431 t.Errorf("could not get recent block: %v", err) 432 } 433 headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash()) 434 if err != nil { 435 t.Errorf("could not get recent block: %v", err) 436 } 437 438 if header.Hash() != headerByHash.Hash() { 439 t.Errorf("did not get expected block") 440 } 441 } 442 443 func TestSimulatedBackend_HeaderByNumber(t *testing.T) { 444 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 445 446 sim := simTestBackend(testAddr) 447 defer sim.Close() 448 bgCtx := context.Background() 449 450 latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil) 451 if err != nil { 452 t.Errorf("could not get header for tip of chain: %v", err) 453 } 454 if latestBlockHeader == nil { 455 t.Errorf("received a nil block header") 456 } 457 if latestBlockHeader.Number.Uint64() != uint64(0) { 458 t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64()) 459 } 460 461 sim.Commit() 462 463 latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil) 464 if err != nil { 465 t.Errorf("could not get header for blockheight of 1: %v", err) 466 } 467 468 blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1)) 469 if err != nil { 470 t.Errorf("could not get header for blockheight of 1: %v", err) 471 } 472 473 if blockHeader.Hash() != latestBlockHeader.Hash() { 474 t.Errorf("block header and latest block header are not the same") 475 } 476 if blockHeader.Number.Int64() != int64(1) { 477 t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64()) 478 } 479 480 block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 481 if err != nil { 482 t.Errorf("could not get block for blockheight of 1: %v", err) 483 } 484 485 if block.Hash() != blockHeader.Hash() { 486 t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash()) 487 } 488 } 489 490 func TestSimulatedBackend_TransactionCount(t *testing.T) { 491 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 492 493 sim := simTestBackend(testAddr) 494 defer sim.Close() 495 bgCtx := context.Background() 496 currentBlock, err := sim.BlockByNumber(bgCtx, nil) 497 if err != nil || currentBlock == nil { 498 t.Error("could not get current block") 499 } 500 501 count, err := sim.TransactionCount(bgCtx, currentBlock.Hash()) 502 if err != nil { 503 t.Error("could not get current block's transaction count") 504 } 505 506 if count != 0 { 507 t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count) 508 } 509 510 // create a signed transaction to send 511 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 512 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 513 if err != nil { 514 t.Errorf("could not sign tx: %v", err) 515 } 516 517 // send tx to simulated backend 518 err = sim.SendTransaction(bgCtx, signedTx) 519 if err != nil { 520 t.Errorf("could not add tx to pending block: %v", err) 521 } 522 523 sim.Commit() 524 525 lastBlock, err := sim.BlockByNumber(bgCtx, nil) 526 if err != nil { 527 t.Errorf("could not get header for tip of chain: %v", err) 528 } 529 530 count, err = sim.TransactionCount(bgCtx, lastBlock.Hash()) 531 if err != nil { 532 t.Error("could not get current block's transaction count") 533 } 534 535 if count != 1 { 536 t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count) 537 } 538 } 539 540 func TestSimulatedBackend_TransactionInBlock(t *testing.T) { 541 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 542 543 sim := simTestBackend(testAddr) 544 defer sim.Close() 545 bgCtx := context.Background() 546 547 transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0)) 548 if err == nil && err != errTransactionDoesNotExist { 549 t.Errorf("expected a transaction does not exist error to be received but received %v", err) 550 } 551 if transaction != nil { 552 t.Errorf("expected transaction to be nil but received %v", transaction) 553 } 554 555 // expect pending nonce to be 0 since account has not been used 556 pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) 557 if err != nil { 558 t.Errorf("did not get the pending nonce: %v", err) 559 } 560 561 if pendingNonce != uint64(0) { 562 t.Errorf("expected pending nonce of 0 got %v", pendingNonce) 563 } 564 565 // create a signed transaction to send 566 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 567 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 568 if err != nil { 569 t.Errorf("could not sign tx: %v", err) 570 } 571 572 // send tx to simulated backend 573 err = sim.SendTransaction(bgCtx, signedTx) 574 if err != nil { 575 t.Errorf("could not add tx to pending block: %v", err) 576 } 577 578 sim.Commit() 579 580 lastBlock, err := sim.BlockByNumber(bgCtx, nil) 581 if err != nil { 582 t.Errorf("could not get header for tip of chain: %v", err) 583 } 584 585 transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1)) 586 if err == nil && err != errTransactionDoesNotExist { 587 t.Errorf("expected a transaction does not exist error to be received but received %v", err) 588 } 589 if transaction != nil { 590 t.Errorf("expected transaction to be nil but received %v", transaction) 591 } 592 593 transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0)) 594 if err != nil { 595 t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err) 596 } 597 598 if signedTx.Hash().String() != transaction.Hash().String() { 599 t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String()) 600 } 601 } 602 603 func TestSimulatedBackend_PendingNonceAt(t *testing.T) { 604 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 605 606 sim := simTestBackend(testAddr) 607 defer sim.Close() 608 bgCtx := context.Background() 609 610 // expect pending nonce to be 0 since account has not been used 611 pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) 612 if err != nil { 613 t.Errorf("did not get the pending nonce: %v", err) 614 } 615 616 if pendingNonce != uint64(0) { 617 t.Errorf("expected pending nonce of 0 got %v", pendingNonce) 618 } 619 620 // create a signed transaction to send 621 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 622 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 623 if err != nil { 624 t.Errorf("could not sign tx: %v", err) 625 } 626 627 // send tx to simulated backend 628 err = sim.SendTransaction(bgCtx, signedTx) 629 if err != nil { 630 t.Errorf("could not add tx to pending block: %v", err) 631 } 632 633 // expect pending nonce to be 1 since account has submitted one transaction 634 pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) 635 if err != nil { 636 t.Errorf("did not get the pending nonce: %v", err) 637 } 638 639 if pendingNonce != uint64(1) { 640 t.Errorf("expected pending nonce of 1 got %v", pendingNonce) 641 } 642 643 // make a new transaction with a nonce of 1 644 tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 645 signedTx, err = types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 646 if err != nil { 647 t.Errorf("could not sign tx: %v", err) 648 } 649 err = sim.SendTransaction(bgCtx, signedTx) 650 if err != nil { 651 t.Errorf("could not send tx: %v", err) 652 } 653 654 // expect pending nonce to be 2 since account now has two transactions 655 pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) 656 if err != nil { 657 t.Errorf("did not get the pending nonce: %v", err) 658 } 659 660 if pendingNonce != uint64(2) { 661 t.Errorf("expected pending nonce of 2 got %v", pendingNonce) 662 } 663 } 664 665 func TestSimulatedBackend_TransactionReceipt(t *testing.T) { 666 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 667 668 sim := simTestBackend(testAddr) 669 defer sim.Close() 670 bgCtx := context.Background() 671 672 // create a signed transaction to send 673 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 674 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 675 if err != nil { 676 t.Errorf("could not sign tx: %v", err) 677 } 678 679 // send tx to simulated backend 680 err = sim.SendTransaction(bgCtx, signedTx) 681 if err != nil { 682 t.Errorf("could not add tx to pending block: %v", err) 683 } 684 sim.Commit() 685 686 receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash()) 687 if err != nil { 688 t.Errorf("could not get transaction receipt: %v", err) 689 } 690 691 if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() { 692 t.Errorf("received receipt is not correct: %v", receipt) 693 } 694 } 695 696 func TestSimulatedBackend_SuggestGasPrice(t *testing.T) { 697 sim := NewSimulatedBackend( 698 blockchain.GenesisAlloc{}, 699 ) 700 defer sim.Close() 701 bgCtx := context.Background() 702 gasPrice, err := sim.SuggestGasPrice(bgCtx) 703 if err != nil { 704 t.Errorf("could not get gas price: %v", err) 705 } 706 if gasPrice.Uint64() != uint64(0) { 707 t.Errorf("gas price was not expected value of 0. actual: %v", gasPrice.Uint64()) 708 } 709 } 710 711 func TestSimulatedBackend_PendingCodeAt(t *testing.T) { 712 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 713 sim := simTestBackend(testAddr) 714 defer sim.Close() 715 bgCtx := context.Background() 716 code, err := sim.CodeAt(bgCtx, testAddr, nil) 717 if err != nil { 718 t.Errorf("could not get code at test addr: %v", err) 719 } 720 if len(code) != 0 { 721 t.Errorf("got code for account that does not have contract code") 722 } 723 724 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 725 if err != nil { 726 t.Errorf("could not get code at test addr: %v", err) 727 } 728 auth := bind.NewKeyedTransactor(testKey) 729 contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) 730 if err != nil { 731 t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) 732 } 733 734 code, err = sim.PendingCodeAt(bgCtx, contractAddr) 735 if err != nil { 736 t.Errorf("could not get code at test addr: %v", err) 737 } 738 if len(code) == 0 { 739 t.Errorf("did not get code for account that has contract code") 740 } 741 // ensure code received equals code deployed 742 if !bytes.Equal(code, common.FromHex(deployedCode)) { 743 t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) 744 } 745 } 746 747 func TestSimulatedBackend_CodeAt(t *testing.T) { 748 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 749 sim := simTestBackend(testAddr) 750 defer sim.Close() 751 bgCtx := context.Background() 752 code, err := sim.CodeAt(bgCtx, testAddr, nil) 753 if err != nil { 754 t.Errorf("could not get code at test addr: %v", err) 755 } 756 if len(code) != 0 { 757 t.Errorf("got code for account that does not have contract code") 758 } 759 760 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 761 if err != nil { 762 t.Errorf("could not get code at test addr: %v", err) 763 } 764 auth := bind.NewKeyedTransactor(testKey) 765 contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) 766 if err != nil { 767 t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) 768 } 769 770 sim.Commit() 771 code, err = sim.CodeAt(bgCtx, contractAddr, nil) 772 if err != nil { 773 t.Errorf("could not get code at test addr: %v", err) 774 } 775 if len(code) == 0 { 776 t.Errorf("did not get code for account that has contract code") 777 } 778 // ensure code received equals code deployed 779 if !bytes.Equal(code, common.FromHex(deployedCode)) { 780 t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) 781 } 782 } 783 784 // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: 785 // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} 786 func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { 787 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 788 sim := simTestBackend(testAddr) 789 defer sim.Close() 790 bgCtx := context.Background() 791 792 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 793 if err != nil { 794 t.Errorf("could not get code at test addr: %v", err) 795 } 796 contractAuth := bind.NewKeyedTransactor(testKey) 797 addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim) 798 if err != nil { 799 t.Errorf("could not deploy contract: %v", err) 800 } 801 802 input, err := parsed.Pack("receive", []byte("X")) 803 if err != nil { 804 t.Errorf("could not pack receive function on contract: %v", err) 805 } 806 807 // make sure you can call the contract in pending state 808 res, err := sim.PendingCallContract(bgCtx, klaytn.CallMsg{ 809 From: testAddr, 810 To: &addr, 811 Data: input, 812 }) 813 if err != nil { 814 t.Errorf("could not call receive method on contract: %v", err) 815 } 816 if len(res) == 0 { 817 t.Errorf("result of contract call was empty: %v", res) 818 } 819 820 // while comparing against the byte array is more exact, also compare against the human readable string for readability 821 if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { 822 t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) 823 } 824 825 sim.Commit() 826 827 // make sure you can call the contract 828 res, err = sim.CallContract(bgCtx, klaytn.CallMsg{ 829 From: testAddr, 830 To: &addr, 831 Data: input, 832 }, nil) 833 if err != nil { 834 t.Errorf("could not call receive method on contract: %v", err) 835 } 836 if len(res) == 0 { 837 t.Errorf("result of contract call was empty: %v", res) 838 } 839 840 if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { 841 t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) 842 } 843 }