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