private_state_manager.go 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package core
  2. import (
  3. "encoding/base64"
  4. "fmt"
  5. "github.com/ethereum/go-ethereum/core/mps"
  6. "github.com/ethereum/go-ethereum/core/privatecache"
  7. "github.com/ethereum/go-ethereum/core/types"
  8. "github.com/ethereum/go-ethereum/ethdb"
  9. "github.com/ethereum/go-ethereum/private"
  10. "github.com/ethereum/go-ethereum/private/engine"
  11. )
  12. // newPrivateStateManager instantiates an instance of mps.PrivateStateManager based on
  13. // the given isMPS flag.
  14. //
  15. // If isMPS is true, it also does the validation to make sure
  16. // the target private.PrivateTransactionManager supports MPS
  17. func newPrivateStateManager(db ethdb.Database, privateCacheProvider privatecache.Provider, isMPS bool) (mps.PrivateStateManager, error) {
  18. if isMPS {
  19. // validation
  20. if !private.P.HasFeature(engine.MultiplePrivateStates) {
  21. return nil, fmt.Errorf("cannot instantiate MultiplePrivateStateManager while the transaction manager does not support multiple private states")
  22. }
  23. groups, err := private.P.Groups()
  24. if err != nil {
  25. return nil, err
  26. }
  27. residentGroupByKey := make(map[string]*mps.PrivateStateMetadata)
  28. privacyGroupById := make(map[types.PrivateStateIdentifier]*mps.PrivateStateMetadata)
  29. for _, group := range groups {
  30. if group.Type == engine.PrivacyGroupResident {
  31. // Resident group IDs come in base64 encoded, so revert to original ID
  32. decoded, err := base64.StdEncoding.DecodeString(group.PrivacyGroupId)
  33. if err != nil {
  34. return nil, err
  35. }
  36. group.PrivacyGroupId = string(decoded)
  37. }
  38. psi := types.ToPrivateStateIdentifier(group.PrivacyGroupId)
  39. existing, found := privacyGroupById[psi]
  40. if found {
  41. return nil, fmt.Errorf("privacy groups id clash id=%s existing.Name=%s duplicate.Name=%s", existing.ID, existing.Name, group.Name)
  42. }
  43. privacyGroupById[psi] = privacyGroupToPrivateStateMetadata(group)
  44. if group.Type == engine.PrivacyGroupResident {
  45. for _, address := range group.Members {
  46. existing, found := residentGroupByKey[address]
  47. if found {
  48. return nil, fmt.Errorf("same address is part of two different groups: address=%s existing.Name=%s duplicate.Name=%s", address, existing.Name, group.Name)
  49. }
  50. residentGroupByKey[address] = privacyGroupToPrivateStateMetadata(group)
  51. }
  52. }
  53. }
  54. return newMultiplePrivateStateManager(db, privateCacheProvider, residentGroupByKey, privacyGroupById)
  55. } else {
  56. return newDefaultPrivateStateManager(db, privateCacheProvider), nil
  57. }
  58. }
  59. func privacyGroupToPrivateStateMetadata(group engine.PrivacyGroup) *mps.PrivateStateMetadata {
  60. return mps.NewPrivateStateMetadata(
  61. types.ToPrivateStateIdentifier(group.PrivacyGroupId),
  62. group.Name,
  63. group.Description,
  64. strTypeToPrivateStateType(group.Type),
  65. group.Members,
  66. )
  67. }
  68. func strTypeToPrivateStateType(strType string) mps.PrivateStateType {
  69. switch strType {
  70. case engine.PrivacyGroupLegacy:
  71. return mps.Legacy
  72. case engine.PrivacyGroupPantheon:
  73. return mps.Pantheon
  74. default:
  75. return mps.Resident
  76. }
  77. }