github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/flow/ledger.go (about) 1 package flow 2 3 import ( 4 "encoding/binary" 5 "encoding/hex" 6 "encoding/json" 7 "fmt" 8 "strings" 9 10 "github.com/onflow/flow-go/ledger/common/hash" 11 "github.com/onflow/flow-go/model/fingerprint" 12 ) 13 14 const ( 15 // Service level keys (owner is empty): 16 UUIDKeyPrefix = "uuid" 17 AddressStateKey = "account_address_state" 18 19 // Account level keys 20 AccountKeyPrefix = "a." 21 AccountStatusKey = AccountKeyPrefix + "s" 22 CodeKeyPrefix = "code." 23 ContractNamesKey = "contract_names" 24 PublicKeyKeyPrefix = "public_key_" 25 ) 26 27 func addressToOwner(address Address) string { 28 return string(address.Bytes()) 29 } 30 31 type RegisterID struct { 32 Owner string 33 Key string 34 } 35 36 var AddressStateRegisterID = RegisterID{ 37 Owner: "", 38 Key: AddressStateKey, 39 } 40 41 func UUIDRegisterID(partition byte) RegisterID { 42 // NOTE: partition 0 uses "uuid" as key to maintain backwards compatibility. 43 key := UUIDKeyPrefix 44 if partition != 0 { 45 key = fmt.Sprintf("%s_%d", UUIDKeyPrefix, partition) 46 } 47 48 return RegisterID{ 49 Owner: "", 50 Key: key, 51 } 52 } 53 54 func AccountStatusRegisterID(address Address) RegisterID { 55 return RegisterID{ 56 Owner: addressToOwner(address), 57 Key: AccountStatusKey, 58 } 59 } 60 61 func PublicKeyRegisterID(address Address, index uint64) RegisterID { 62 return RegisterID{ 63 Owner: addressToOwner(address), 64 Key: fmt.Sprintf("public_key_%d", index), 65 } 66 } 67 68 func ContractNamesRegisterID(address Address) RegisterID { 69 return RegisterID{ 70 Owner: addressToOwner(address), 71 Key: ContractNamesKey, 72 } 73 } 74 75 func ContractRegisterID(address Address, contractName string) RegisterID { 76 return RegisterID{ 77 Owner: addressToOwner(address), 78 Key: ContractKey(contractName), 79 } 80 } 81 82 func ContractKey(contractName string) string { 83 return CodeKeyPrefix + contractName 84 } 85 86 func IsContractKey(key string) bool { 87 return strings.HasPrefix(key, CodeKeyPrefix) 88 } 89 90 func KeyContractName(key string) string { 91 if !IsContractKey(key) { 92 return "" 93 } 94 return key[len(CodeKeyPrefix):] 95 } 96 97 func IsContractNamesRegisterID(registerID RegisterID) bool { 98 return registerID.Key == ContractNamesKey 99 } 100 101 func CadenceRegisterID(owner []byte, key []byte) RegisterID { 102 return RegisterID{ 103 Owner: addressToOwner(BytesToAddress(owner)), 104 Key: string(key), 105 } 106 } 107 108 // AddressToRegisterOwner converts 8-byte address to register owner. 109 // If given address is ZeroAddress, register owner is "" (global register). 110 func AddressToRegisterOwner(address Address) string { 111 // Global registers have address zero and an empty owner field 112 if address == EmptyAddress { 113 return "" 114 } 115 116 // All other registers have the account's address 117 return addressToOwner(address) 118 } 119 120 func NewRegisterID(owner Address, key string) RegisterID { 121 return RegisterID{ 122 Owner: AddressToRegisterOwner(owner), 123 Key: key, 124 } 125 } 126 127 // IsInternalState returns true if the register id is controlled by flow-go and 128 // return false otherwise (key controlled by the cadence env). 129 func (id RegisterID) IsInternalState() bool { 130 // check if is a service level key (owner is empty) 131 // cases: 132 // - "", "uuid" (for shard index 0) 133 // - "", "uuid_%d" (for shard index > 0) 134 // - "", "account_address_state" 135 if len(id.Owner) == 0 { 136 return strings.HasPrefix(id.Key, UUIDKeyPrefix) || 137 id.Key == AddressStateKey 138 } 139 140 // check account level keys 141 // cases: 142 // - address, "contract_names" 143 // - address, "code.%s" (contract name) 144 // - address, "public_key_%d" (index) 145 // - address, "a.s" (account status) 146 return strings.HasPrefix(id.Key, PublicKeyKeyPrefix) || 147 id.Key == ContractNamesKey || 148 strings.HasPrefix(id.Key, CodeKeyPrefix) || 149 id.Key == AccountStatusKey 150 } 151 152 const SlabIndexPrefix = '$' 153 154 // IsSlabIndex returns true if the key is a slab index for an account's ordered fields 155 // map. 156 // 157 // In general, each account's regular fields are stored in ordered map known 158 // only to cadence. Cadence encodes this map into bytes and split the bytes 159 // into slab chunks before storing the slabs into the ledger. 160 func (id RegisterID) IsSlabIndex() bool { 161 return IsSlabIndexKey(id.Key) 162 } 163 164 func IsSlabIndexKey(key string) bool { 165 return len(key) == 9 && key[0] == SlabIndexPrefix 166 } 167 168 // String returns formatted string representation of the RegisterID. 169 func (id RegisterID) String() string { 170 formattedKey := "" 171 if id.IsSlabIndex() { 172 i := binary.BigEndian.Uint64([]byte(id.Key[1:])) 173 formattedKey = fmt.Sprintf("%c%d", SlabIndexPrefix, i) 174 } else { 175 formattedKey = fmt.Sprintf("#%x", []byte(id.Key)) 176 } 177 178 return fmt.Sprintf("%x/%s", id.Owner, formattedKey) 179 } 180 181 // Bytes returns a bytes representation of the RegisterID. 182 // 183 // The encoding uses the injective fingerprint module. 184 func (r *RegisterID) Bytes() []byte { 185 return fingerprint.Fingerprint(r) 186 } 187 188 // RegisterValue (value part of Register) 189 type RegisterValue = []byte 190 191 type RegisterEntry struct { 192 Key RegisterID 193 Value RegisterValue 194 } 195 196 // handy container for sorting 197 // TODO(ramtin): add canonical encoding and fingerprint for RegisterEntries 198 type RegisterEntries []RegisterEntry 199 200 func (d RegisterEntries) Len() int { 201 return len(d) 202 } 203 204 func (d RegisterEntries) Less(i, j int) bool { 205 if d[i].Key.Owner != d[j].Key.Owner { 206 return d[i].Key.Owner < d[j].Key.Owner 207 } 208 return d[i].Key.Key < d[j].Key.Key 209 } 210 211 func (d RegisterEntries) Swap(i, j int) { 212 d[i], d[j] = d[j], d[i] 213 } 214 215 func (d RegisterEntries) IDs() []RegisterID { 216 r := make([]RegisterID, len(d)) 217 for i, entry := range d { 218 r[i] = entry.Key 219 } 220 return r 221 } 222 223 func (d RegisterEntries) Values() []RegisterValue { 224 r := make([]RegisterValue, len(d)) 225 for i, entry := range d { 226 r[i] = entry.Value 227 } 228 return r 229 } 230 231 // handy container for sorting 232 type RegisterIDs []RegisterID 233 234 func (d RegisterIDs) Len() int { 235 return len(d) 236 } 237 238 func (d RegisterIDs) Less(i, j int) bool { 239 if d[i].Owner != d[j].Owner { 240 return d[i].Owner < d[j].Owner 241 } 242 return d[i].Key < d[j].Key 243 } 244 245 func (d RegisterIDs) Swap(i, j int) { 246 d[i], d[j] = d[j], d[i] 247 } 248 249 // StorageProof (proof of a read or update to the state, Merkle path of some sort) 250 type StorageProof = []byte 251 252 // StateCommitment holds the root hash of the tree (Snapshot) 253 // TODO: solve the circular dependency and define StateCommitment as ledger.State 254 type StateCommitment hash.Hash 255 256 // DummyStateCommitment is an arbitrary value used in function failure cases, 257 // although it can represent a valid state commitment. 258 var DummyStateCommitment = StateCommitment(hash.DummyHash) 259 260 // ToStateCommitment converts a byte slice into a StateCommitment. 261 // It returns an error if the slice has an invalid length. 262 // The returned error indicates that the given byte slice is not a 263 // valid root hash of an execution state. As the function is 264 // side-effect free, all failures are simply a no-op. 265 func ToStateCommitment(stateBytes []byte) (StateCommitment, error) { 266 var state StateCommitment 267 if len(stateBytes) != len(state) { 268 return DummyStateCommitment, fmt.Errorf("expecting %d bytes but got %d bytes", len(state), len(stateBytes)) 269 } 270 copy(state[:], stateBytes) 271 return state, nil 272 } 273 274 func (s StateCommitment) MarshalJSON() ([]byte, error) { 275 return json.Marshal(hex.EncodeToString(s[:])) 276 } 277 278 func (s *StateCommitment) UnmarshalJSON(data []byte) error { 279 // first, attempt to unmarshal assuming data is a hex string representation 280 err := s.unmarshalJSONHexString(data) 281 if err == nil { 282 return nil 283 } 284 // fallback to unmarshalling as [32]byte 285 return s.unmarshalJSONByteArr(data) 286 } 287 288 func (s *StateCommitment) unmarshalJSONHexString(data []byte) error { 289 var stateCommitmentHex string 290 if err := json.Unmarshal(data, &stateCommitmentHex); err != nil { 291 return err 292 } 293 b, err := hex.DecodeString(stateCommitmentHex) 294 if err != nil { 295 return err 296 } 297 h, err := hash.ToHash(b) 298 if err != nil { 299 return err 300 } 301 *s = StateCommitment(h) 302 return nil 303 } 304 305 func (s *StateCommitment) unmarshalJSONByteArr(data []byte) error { 306 var stateCommitment [32]byte 307 if err := json.Unmarshal(data, &stateCommitment); err != nil { 308 return err 309 } 310 *s = stateCommitment 311 return nil 312 }