call_helper.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package core
  2. import (
  3. "crypto/ecdsa"
  4. "math/big"
  5. "github.com/ethereum/go-ethereum/common"
  6. "github.com/ethereum/go-ethereum/consensus/ethash"
  7. "github.com/ethereum/go-ethereum/core/rawdb"
  8. "github.com/ethereum/go-ethereum/core/state"
  9. "github.com/ethereum/go-ethereum/core/types"
  10. "github.com/ethereum/go-ethereum/core/vm"
  11. "github.com/ethereum/go-ethereum/crypto"
  12. "github.com/ethereum/go-ethereum/ethdb"
  13. "github.com/ethereum/go-ethereum/params"
  14. )
  15. // callHelper makes it easier to do proper calls and use the state transition object.
  16. // It also manages the nonces of the caller and keeps private and public state, which
  17. // can be freely modified outside of the helper.
  18. type callHelper struct {
  19. db ethdb.Database
  20. nonces map[common.Address]uint64
  21. header types.Header
  22. gp *GasPool
  23. PrivateState, PublicState *state.StateDB
  24. }
  25. // TxNonce returns the pending nonce
  26. func (cg *callHelper) TxNonce(addr common.Address) uint64 {
  27. return cg.nonces[addr]
  28. }
  29. // MakeCall makes does a call to the recipient using the given input. It can switch between private and public
  30. // by setting the private boolean flag. It returns an error if the call failed.
  31. func (cg *callHelper) MakeCall(private bool, key *ecdsa.PrivateKey, to common.Address, input []byte) error {
  32. var (
  33. from = crypto.PubkeyToAddress(key.PublicKey)
  34. err error
  35. )
  36. // TODO(joel): these are just stubbed to the same values as in dual_state_test.go
  37. cg.header.Number = new(big.Int)
  38. cg.header.Time = uint64(43)
  39. cg.header.Difficulty = new(big.Int).SetUint64(1000488)
  40. cg.header.GasLimit = 4700000
  41. signer := types.MakeSigner(params.QuorumTestChainConfig, cg.header.Number)
  42. if private {
  43. signer = types.QuorumPrivateTxSigner{}
  44. }
  45. tx, err := types.SignTx(types.NewTransaction(cg.TxNonce(from), to, new(big.Int), 1000000, new(big.Int), input), signer, key)
  46. if err != nil {
  47. return err
  48. }
  49. defer func() { cg.nonces[from]++ }()
  50. msg, err := tx.AsMessage(signer)
  51. if err != nil {
  52. return err
  53. }
  54. publicState, privateState := cg.PublicState, cg.PrivateState
  55. if !private {
  56. privateState = publicState
  57. }
  58. // TODO(joel): can we just pass nil instead of bc?
  59. bc, _ := NewBlockChain(cg.db, nil, params.QuorumTestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
  60. txContext := NewEVMTxContext(msg)
  61. evmContext := NewEVMBlockContext(&cg.header, bc, &from)
  62. vmenv := vm.NewEVM(evmContext, txContext, publicState, privateState, params.QuorumTestChainConfig, vm.Config{})
  63. sender := vm.AccountRef(msg.From())
  64. vmenv.Call(sender, to, msg.Data(), 100000000, new(big.Int))
  65. return err
  66. }
  67. // MakeCallHelper returns a new callHelper
  68. func MakeCallHelper() *callHelper {
  69. memdb := rawdb.NewMemoryDatabase()
  70. db := state.NewDatabase(memdb)
  71. publicState, err := state.New(common.Hash{}, db, nil)
  72. if err != nil {
  73. panic(err)
  74. }
  75. privateState, err := state.New(common.Hash{}, db, nil)
  76. if err != nil {
  77. panic(err)
  78. }
  79. cg := &callHelper{
  80. db: memdb,
  81. nonces: make(map[common.Address]uint64),
  82. gp: new(GasPool).AddGas(5000000),
  83. PublicState: publicState,
  84. PrivateState: privateState,
  85. }
  86. return cg
  87. }