github.com/Night-mk/quorum@v21.1.0+incompatible/core/state/account_extra_data.go (about) 1 // Copyright 2014 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 17 package state 18 19 import ( 20 "fmt" 21 "io" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/private/engine" 25 "github.com/ethereum/go-ethereum/rlp" 26 ) 27 28 // Quorum 29 // AccountExtraData is to contain extra data that supplements existing Account data. 30 // It is also maintained in a trie to support rollback. 31 // Note: 32 // - update copy() method 33 // - update DecodeRLP and EncodeRLP when adding new field 34 type AccountExtraData struct { 35 // for privacy enhancements 36 PrivacyMetadata *PrivacyMetadata 37 // list of public keys managed by the corresponding Tessera. 38 // This is for multitenancy 39 ManagedParties []string 40 } 41 42 func (qmd *AccountExtraData) DecodeRLP(stream *rlp.Stream) error { 43 var dataRLP struct { 44 // from state.PrivacyMetadata, this is required to support 45 // backward compatibility with RLP-encoded state.PrivacyMetadata. 46 // Refer to rlp/doc.go for decoding rules. 47 CreationTxHash *common.EncryptedPayloadHash `rlp:"nil"` 48 // from state.PrivacyMetadata, this is required to support 49 // backward compatibility with RLP-encoded state.PrivacyMetadata. 50 // Refer to rlp/doc.go for decoding rules. 51 PrivacyFlag *engine.PrivacyFlagType `rlp:"nil"` 52 53 Rest []rlp.RawValue `rlp:"tail"` // to maintain forward compatibility 54 } 55 if err := stream.Decode(&dataRLP); err != nil { 56 return err 57 } 58 if dataRLP.CreationTxHash != nil && dataRLP.PrivacyFlag != nil { 59 qmd.PrivacyMetadata = &PrivacyMetadata{ 60 CreationTxHash: *dataRLP.CreationTxHash, 61 PrivacyFlag: *dataRLP.PrivacyFlag, 62 } 63 } 64 if len(dataRLP.Rest) > 0 { 65 var managedParties []string 66 if err := rlp.DecodeBytes(dataRLP.Rest[0], &managedParties); err != nil { 67 return fmt.Errorf("fail to decode managedParties with error %v", err) 68 } 69 // As RLP encodes empty slice or nil slice as an empty string (192) 70 // we won't be able to determine when decoding. So we use pragmatic approach 71 // to default to nil value. Downstream usage would deal with it easier. 72 if len(managedParties) == 0 { 73 qmd.ManagedParties = nil 74 } else { 75 qmd.ManagedParties = managedParties 76 } 77 } 78 return nil 79 } 80 81 func (qmd *AccountExtraData) EncodeRLP(writer io.Writer) error { 82 var ( 83 hash *common.EncryptedPayloadHash 84 flag *engine.PrivacyFlagType 85 ) 86 if qmd.PrivacyMetadata != nil { 87 hash = &qmd.PrivacyMetadata.CreationTxHash 88 flag = &qmd.PrivacyMetadata.PrivacyFlag 89 } 90 return rlp.Encode(writer, struct { 91 CreationTxHash *common.EncryptedPayloadHash `rlp:"nil"` 92 PrivacyFlag *engine.PrivacyFlagType `rlp:"nil"` 93 ManagedParties []string 94 }{ 95 CreationTxHash: hash, 96 PrivacyFlag: flag, 97 ManagedParties: qmd.ManagedParties, 98 }) 99 } 100 101 func (qmd *AccountExtraData) copy() *AccountExtraData { 102 if qmd == nil { 103 return nil 104 } 105 var copyPM *PrivacyMetadata 106 if qmd.PrivacyMetadata != nil { 107 copyPM = &PrivacyMetadata{ 108 CreationTxHash: qmd.PrivacyMetadata.CreationTxHash, 109 PrivacyFlag: qmd.PrivacyMetadata.PrivacyFlag, 110 } 111 } 112 copyManagedParties := make([]string, len(qmd.ManagedParties)) 113 copy(copyManagedParties, qmd.ManagedParties) 114 return &AccountExtraData{ 115 PrivacyMetadata: copyPM, 116 ManagedParties: copyManagedParties, 117 } 118 } 119 120 // attached to every private contract account 121 type PrivacyMetadata struct { 122 CreationTxHash common.EncryptedPayloadHash `json:"creationTxHash"` 123 PrivacyFlag engine.PrivacyFlagType `json:"privacyFlag"` 124 } 125 126 // Quorum 127 // privacyMetadataRLP struct is to make sure 128 // field order is preserved regardless changes in the PrivacyMetadata and its internal 129 // 130 // Edit this struct with care to make sure forward and backward compatibility 131 type privacyMetadataRLP struct { 132 CreationTxHash common.EncryptedPayloadHash 133 PrivacyFlag engine.PrivacyFlagType 134 135 Rest []rlp.RawValue `rlp:"tail"` // to maintain forward compatibility 136 } 137 138 func (p *PrivacyMetadata) DecodeRLP(stream *rlp.Stream) error { 139 var dataRLP privacyMetadataRLP 140 if err := stream.Decode(&dataRLP); err != nil { 141 return err 142 } 143 p.CreationTxHash = dataRLP.CreationTxHash 144 p.PrivacyFlag = dataRLP.PrivacyFlag 145 return nil 146 } 147 148 func (p *PrivacyMetadata) EncodeRLP(writer io.Writer) error { 149 return rlp.Encode(writer, privacyMetadataRLP{ 150 CreationTxHash: p.CreationTxHash, 151 PrivacyFlag: p.PrivacyFlag, 152 }) 153 } 154 155 func NewStatePrivacyMetadata(creationTxHash common.EncryptedPayloadHash, privacyFlag engine.PrivacyFlagType) *PrivacyMetadata { 156 return &PrivacyMetadata{ 157 CreationTxHash: creationTxHash, 158 PrivacyFlag: privacyFlag, 159 } 160 }