account.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2019 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package snapshot
  17. import (
  18. "bytes"
  19. "math/big"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/rlp"
  22. )
  23. // Account is a modified version of a state.Account, where the root is replaced
  24. // with a byte slice. This format can be used to represent full-consensus format
  25. // or slim-snapshot format which replaces the empty root and code hash as nil
  26. // byte slice.
  27. type Account struct {
  28. Nonce uint64
  29. Balance *big.Int
  30. Root []byte
  31. CodeHash []byte
  32. }
  33. // SlimAccount converts a state.Account content into a slim snapshot account
  34. func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []byte) Account {
  35. slim := Account{
  36. Nonce: nonce,
  37. Balance: balance,
  38. }
  39. if root != emptyRoot {
  40. slim.Root = root[:]
  41. }
  42. if !bytes.Equal(codehash, emptyCode[:]) {
  43. slim.CodeHash = codehash
  44. }
  45. return slim
  46. }
  47. // SlimAccountRLP converts a state.Account content into a slim snapshot
  48. // version RLP encoded.
  49. func SlimAccountRLP(nonce uint64, balance *big.Int, root common.Hash, codehash []byte) []byte {
  50. data, err := rlp.EncodeToBytes(SlimAccount(nonce, balance, root, codehash))
  51. if err != nil {
  52. panic(err)
  53. }
  54. return data
  55. }
  56. // FullAccount decodes the data on the 'slim RLP' format and return
  57. // the consensus format account.
  58. func FullAccount(data []byte) (Account, error) {
  59. var account Account
  60. if err := rlp.DecodeBytes(data, &account); err != nil {
  61. return Account{}, err
  62. }
  63. if len(account.Root) == 0 {
  64. account.Root = emptyRoot[:]
  65. }
  66. if len(account.CodeHash) == 0 {
  67. account.CodeHash = emptyCode[:]
  68. }
  69. return account, nil
  70. }
  71. // FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format.
  72. func FullAccountRLP(data []byte) ([]byte, error) {
  73. account, err := FullAccount(data)
  74. if err != nil {
  75. return nil, err
  76. }
  77. return rlp.EncodeToBytes(account)
  78. }