default_psr.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package mps
  2. import (
  3. "fmt"
  4. "github.com/ethereum/go-ethereum/common"
  5. "github.com/ethereum/go-ethereum/core/privatecache"
  6. "github.com/ethereum/go-ethereum/core/rawdb"
  7. "github.com/ethereum/go-ethereum/core/state"
  8. "github.com/ethereum/go-ethereum/core/types"
  9. "github.com/ethereum/go-ethereum/ethdb"
  10. "github.com/ethereum/go-ethereum/log"
  11. )
  12. // DefaultPrivateStateRepository acts as the single private state in the original
  13. // Quorum design.
  14. type DefaultPrivateStateRepository struct {
  15. db ethdb.Database
  16. // cache of stateDB
  17. stateCache state.Database
  18. privateCacheProvider privatecache.Provider
  19. // stateDB gives access to the underlying state
  20. stateDB *state.StateDB
  21. root common.Hash
  22. }
  23. func NewDefaultPrivateStateRepository(db ethdb.Database, cache state.Database, privateCacheProvider privatecache.Provider, previousBlockHash common.Hash) (*DefaultPrivateStateRepository, error) {
  24. root := rawdb.GetPrivateStateRoot(db, previousBlockHash)
  25. statedb, err := state.New(root, cache, nil)
  26. if err != nil {
  27. return nil, err
  28. }
  29. return &DefaultPrivateStateRepository{
  30. db: db,
  31. stateCache: cache,
  32. privateCacheProvider: privateCacheProvider,
  33. stateDB: statedb,
  34. root: root,
  35. }, nil
  36. }
  37. func (dpsr *DefaultPrivateStateRepository) DefaultState() (*state.StateDB, error) {
  38. if dpsr == nil {
  39. return nil, fmt.Errorf("nil instance")
  40. }
  41. return dpsr.stateDB, nil
  42. }
  43. func (dpsr *DefaultPrivateStateRepository) DefaultStateMetadata() *PrivateStateMetadata {
  44. return DefaultPrivateStateMetadata
  45. }
  46. func (dpsr *DefaultPrivateStateRepository) IsMPS() bool {
  47. return false
  48. }
  49. func (dpsr *DefaultPrivateStateRepository) PrivateStateRoot(psi types.PrivateStateIdentifier) (common.Hash, error) {
  50. return dpsr.root, nil
  51. }
  52. func (dpsr *DefaultPrivateStateRepository) StatePSI(psi types.PrivateStateIdentifier) (*state.StateDB, error) {
  53. if psi != types.DefaultPrivateStateIdentifier {
  54. return nil, fmt.Errorf("only the 'private' psi is supported by the default private state manager")
  55. }
  56. return dpsr.stateDB, nil
  57. }
  58. func (dpsr *DefaultPrivateStateRepository) Reset() error {
  59. return dpsr.stateDB.Reset(dpsr.root)
  60. }
  61. // CommitAndWrite commits the private state and writes to disk
  62. func (dpsr *DefaultPrivateStateRepository) CommitAndWrite(isEIP158 bool, block *types.Block) error {
  63. privateRoot, err := dpsr.stateDB.Commit(isEIP158)
  64. if err != nil {
  65. return err
  66. }
  67. if err := rawdb.WritePrivateStateRoot(dpsr.db, block.Root(), privateRoot); err != nil {
  68. log.Error("Failed writing private state root", "err", err)
  69. return err
  70. }
  71. dpsr.privateCacheProvider.Commit(dpsr.stateCache, privateRoot)
  72. dpsr.privateCacheProvider.Reference(privateRoot, block.Root())
  73. return nil
  74. }
  75. // Commit commits the private state only
  76. func (dpsr *DefaultPrivateStateRepository) Commit(isEIP158 bool, block *types.Block) error {
  77. var err error
  78. dpsr.root, err = dpsr.stateDB.Commit(isEIP158)
  79. return err
  80. }
  81. func (dpsr *DefaultPrivateStateRepository) Copy() PrivateStateRepository {
  82. return &DefaultPrivateStateRepository{
  83. db: dpsr.db,
  84. stateCache: dpsr.stateCache,
  85. privateCacheProvider: dpsr.privateCacheProvider,
  86. stateDB: dpsr.stateDB.Copy(),
  87. root: dpsr.root,
  88. }
  89. }
  90. // Given a slice of public receipts and an overlapping (smaller) slice of
  91. // private receipts, return a new slice where the default for each location is
  92. // the public receipt but we take the private receipt in each place we have
  93. // one.
  94. func (dpsr *DefaultPrivateStateRepository) MergeReceipts(pub, priv types.Receipts) types.Receipts {
  95. m := make(map[common.Hash]*types.Receipt)
  96. for _, receipt := range pub {
  97. m[receipt.TxHash] = receipt
  98. }
  99. for _, receipt := range priv {
  100. m[receipt.TxHash] = receipt
  101. }
  102. ret := make(types.Receipts, 0, len(pub))
  103. for _, pubReceipt := range pub {
  104. ret = append(ret, m[pubReceipt.TxHash])
  105. }
  106. return ret
  107. }