state_setter.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package privacyExtension
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "github.com/ethereum/go-ethereum/common"
  6. "github.com/ethereum/go-ethereum/core/mps"
  7. "github.com/ethereum/go-ethereum/core/state"
  8. "github.com/ethereum/go-ethereum/core/types"
  9. extension "github.com/ethereum/go-ethereum/extension/extensionContracts"
  10. "github.com/ethereum/go-ethereum/log"
  11. "github.com/ethereum/go-ethereum/private"
  12. )
  13. var DefaultExtensionHandler *ExtensionHandler
  14. type ExtensionHandler struct {
  15. ptm private.PrivateTransactionManager
  16. psmr mps.PrivateStateMetadataResolver
  17. isMultitenant bool
  18. }
  19. func Init() {
  20. DefaultExtensionHandler = NewExtensionHandler(private.P)
  21. }
  22. func NewExtensionHandler(transactionManager private.PrivateTransactionManager) *ExtensionHandler {
  23. return &ExtensionHandler{ptm: transactionManager}
  24. }
  25. func (handler *ExtensionHandler) SupportMultitenancy(b bool) {
  26. handler.isMultitenant = b
  27. }
  28. func (handler *ExtensionHandler) SetPSMR(psmr mps.PrivateStateMetadataResolver) {
  29. handler.psmr = psmr
  30. }
  31. func (handler *ExtensionHandler) CheckExtensionAndSetPrivateState(txLogs []*types.Log, privateState *state.StateDB, psi types.PrivateStateIdentifier) {
  32. extraMetaDataUpdated := false
  33. for _, txLog := range txLogs {
  34. if !logContainsExtensionTopic(txLog) {
  35. continue
  36. }
  37. //this is a direct state share
  38. address, hash, uuid, err := extension.UnpackStateSharedLog(txLog.Data)
  39. if err != nil {
  40. continue
  41. }
  42. // check if state exists for the extension address. If yes then skip
  43. // processing
  44. if privateState.GetCode(address) != nil {
  45. if extraMetaDataUpdated {
  46. continue
  47. }
  48. // check the privacy flag of the contract. if its other than
  49. // 0 then need to update the privacy metadata for the contract
  50. //TODO: validate the old and new parties to ensure that all old parties are there
  51. setPrivacyMetadata(privateState, address, hash)
  52. if handler.isMultitenant {
  53. setManagedParties(handler.ptm, privateState, address, hash)
  54. }
  55. extraMetaDataUpdated = true
  56. } else {
  57. managedParties, accounts, privacyMetaData, found := handler.FetchStateData(txLog.Address, hash, uuid, psi)
  58. if !found {
  59. continue
  60. }
  61. if !handler.isMultitenant {
  62. managedParties = nil
  63. }
  64. if !validateAccountsExist([]common.Address{address}, accounts) {
  65. log.Error("Account mismatch", "expected", address, "found", accounts)
  66. continue
  67. }
  68. snapshotId := privateState.Snapshot()
  69. if success := setState(privateState, accounts, privacyMetaData, managedParties); !success {
  70. privateState.RevertToSnapshot(snapshotId)
  71. }
  72. }
  73. }
  74. }
  75. func (handler *ExtensionHandler) FetchStateData(address common.Address, hash string, uuid string, psi types.PrivateStateIdentifier) ([]string, map[string]extension.AccountWithMetadata, *state.PrivacyMetadata, bool) {
  76. if uuidIsSentByUs := handler.UuidIsOwn(address, uuid, psi); !uuidIsSentByUs {
  77. return nil, nil, nil, false
  78. }
  79. managedParties, stateData, privacyMetaData, ok := handler.FetchDataFromPTM(hash)
  80. if !ok {
  81. //there is nothing to do here, the state wasn't shared with us
  82. log.Error("Extension: No state shared with us")
  83. return nil, nil, nil, false
  84. }
  85. var accounts map[string]extension.AccountWithMetadata
  86. if err := json.Unmarshal(stateData, &accounts); err != nil {
  87. log.Error("Extension: Could not unmarshal data")
  88. return nil, nil, nil, false
  89. }
  90. return managedParties, accounts, privacyMetaData, true
  91. }
  92. // Checks
  93. func (handler *ExtensionHandler) FetchDataFromPTM(hash string) ([]string, []byte, *state.PrivacyMetadata, bool) {
  94. ptmHash, _ := common.Base64ToEncryptedPayloadHash(hash)
  95. _, managedParties, stateData, extraMetaData, err := handler.ptm.Receive(ptmHash)
  96. if stateData == nil {
  97. log.Error("No state data found in PTM", "ptm hash", hash)
  98. return nil, nil, nil, false
  99. }
  100. if err != nil {
  101. log.Error("Error receiving state data from PTM", "ptm hash", hash, "err", err.Error())
  102. return nil, nil, nil, false
  103. }
  104. privacyMetaData := state.NewStatePrivacyMetadata(ptmHash, extraMetaData.PrivacyFlag)
  105. return managedParties, stateData, privacyMetaData, true
  106. }
  107. func (handler *ExtensionHandler) UuidIsOwn(address common.Address, uuid string, psi types.PrivateStateIdentifier) bool {
  108. if uuid == "" {
  109. //we never called accept
  110. log.Warn("Extension: State shared by accept never called")
  111. return false
  112. }
  113. encryptedTxHash := common.BytesToEncryptedPayloadHash(common.FromHex(uuid))
  114. isSender, err := handler.ptm.IsSender(encryptedTxHash)
  115. if err != nil {
  116. log.Debug("Extension: could not determine if we are sender", "err", err.Error())
  117. return false
  118. }
  119. if !isSender {
  120. return false
  121. }
  122. senderPublicKey, _, encryptedPayload, _, err := handler.ptm.Receive(encryptedTxHash)
  123. if err != nil {
  124. log.Debug("Extension: payload not found", "err", err)
  125. return false
  126. }
  127. //check the given PSI is same as PSI of sender key
  128. senderPsm, err := handler.psmr.ResolveForManagedParty(senderPublicKey)
  129. if err != nil {
  130. log.Debug("Extension: unable to determine sender public key PSI", "err", err)
  131. return false
  132. }
  133. if senderPsm.ID != psi {
  134. // sender was another tenant on this node
  135. //not an error case, so no need to log an error
  136. return false
  137. }
  138. var payload common.DecryptRequest
  139. if err := json.Unmarshal(encryptedPayload, &payload); err != nil {
  140. log.Debug("Extension: payload unmarshal failed", "err", err)
  141. }
  142. contractDetails, _, err := handler.ptm.DecryptPayload(payload)
  143. if err != nil {
  144. log.Debug("Extension: payload decrypt failed", "err", err)
  145. }
  146. if !bytes.Equal(contractDetails, address.Bytes()) {
  147. log.Error("Extension: wrong address in retrieved UUID")
  148. return false
  149. }
  150. return true
  151. }