state_override.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package ethapi
  2. import (
  3. "fmt"
  4. "github.com/ethereum/go-ethereum/common"
  5. "github.com/ethereum/go-ethereum/common/hexutil"
  6. "github.com/ethereum/go-ethereum/core/state"
  7. "math/big"
  8. )
  9. // OverrideAccount indicates the overriding fields of account during the execution
  10. // of a message call.
  11. // Note, state and stateDiff can't be specified at the same time. If state is
  12. // set, message execution will only use the data in the given state. Otherwise
  13. // if statDiff is set, all diff will be applied first and then execute the call
  14. // message.
  15. type OverrideAccount struct {
  16. Nonce *hexutil.Uint64 `json:"nonce"`
  17. Code *hexutil.Bytes `json:"code"`
  18. Balance **hexutil.Big `json:"balance"`
  19. State *map[common.Hash]common.Hash `json:"state"`
  20. StateDiff *map[common.Hash]common.Hash `json:"stateDiff"`
  21. }
  22. // StateOverride is the collection of overridden accounts.
  23. type StateOverride map[common.Address]OverrideAccount
  24. // Apply overrides the fields of specified accounts into the given state.
  25. func (diff *StateOverride) Apply(state *state.StateDB) error {
  26. if diff == nil {
  27. return nil
  28. }
  29. for addr, account := range *diff {
  30. // Override account nonce.
  31. if account.Nonce != nil {
  32. state.SetNonce(addr, uint64(*account.Nonce))
  33. }
  34. // Override account(contract) code.
  35. if account.Code != nil {
  36. state.SetCode(addr, *account.Code)
  37. }
  38. // Override account balance.
  39. if account.Balance != nil {
  40. state.SetBalance(addr, (*big.Int)(*account.Balance))
  41. }
  42. if account.State != nil && account.StateDiff != nil {
  43. return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex())
  44. }
  45. // Replace entire state if caller requires.
  46. if account.State != nil {
  47. state.SetStorage(addr, *account.State)
  48. }
  49. // Apply state diff into specified accounts.
  50. if account.StateDiff != nil {
  51. for key, value := range *account.StateDiff {
  52. state.SetState(addr, key, value)
  53. }
  54. }
  55. }
  56. return nil
  57. }