github.com/koko1123/flow-go-1@v0.29.6/model/flow/ledger.go (about) 1 package flow 2 3 import ( 4 "encoding/hex" 5 "encoding/json" 6 "fmt" 7 8 "github.com/koko1123/flow-go-1/ledger/common/hash" 9 "github.com/koko1123/flow-go-1/model/fingerprint" 10 ) 11 12 type RegisterID struct { 13 Owner string 14 Key string 15 } 16 17 // String returns formatted string representation of the RegisterID. 18 // TODO(rbtz): remove after the merge of https://github.com/onflow/flow-emulator/pull/235 19 // Deprecated: used only by emultor. 20 func (r *RegisterID) String() string { 21 return fmt.Sprintf("%x/%x", r.Owner, r.Key) 22 } 23 24 // Bytes returns a bytes representation of the RegisterID. 25 // 26 // The encoding uses the injective fingerprint module. 27 func (r *RegisterID) Bytes() []byte { 28 return fingerprint.Fingerprint(r) 29 } 30 31 func NewRegisterID(owner, key string) RegisterID { 32 return RegisterID{ 33 Owner: owner, 34 Key: key, 35 } 36 } 37 38 // RegisterValue (value part of Register) 39 type RegisterValue = []byte 40 41 type RegisterEntry struct { 42 Key RegisterID 43 Value RegisterValue 44 } 45 46 // handy container for sorting 47 type RegisterEntries []RegisterEntry 48 49 func (d RegisterEntries) Len() int { 50 return len(d) 51 } 52 53 func (d RegisterEntries) Less(i, j int) bool { 54 if d[i].Key.Owner != d[j].Key.Owner { 55 return d[i].Key.Owner < d[j].Key.Owner 56 } 57 return d[i].Key.Key < d[j].Key.Key 58 } 59 60 func (d RegisterEntries) Swap(i, j int) { 61 d[i], d[j] = d[j], d[i] 62 } 63 64 func (d RegisterEntries) IDs() []RegisterID { 65 r := make([]RegisterID, len(d)) 66 for i, entry := range d { 67 r[i] = entry.Key 68 } 69 return r 70 } 71 72 func (d RegisterEntries) Values() []RegisterValue { 73 r := make([]RegisterValue, len(d)) 74 for i, entry := range d { 75 r[i] = entry.Value 76 } 77 return r 78 } 79 80 // StorageProof (proof of a read or update to the state, Merkle path of some sort) 81 type StorageProof = []byte 82 83 // StateCommitment holds the root hash of the tree (Snapshot) 84 // TODO: solve the circular dependency and define StateCommitment as ledger.State 85 type StateCommitment hash.Hash 86 87 // DummyStateCommitment is an arbitrary value used in function failure cases, 88 // although it can represent a valid state commitment. 89 var DummyStateCommitment = StateCommitment(hash.DummyHash) 90 91 // ToStateCommitment converts a byte slice into a StateCommitment. 92 // It returns an error if the slice has an invalid length. 93 // The returned error indicates that the given byte slice is not a 94 // valid root hash of an execution state. As the function is 95 // side-effect free, all failures are simply a no-op. 96 func ToStateCommitment(stateBytes []byte) (StateCommitment, error) { 97 var state StateCommitment 98 if len(stateBytes) != len(state) { 99 return DummyStateCommitment, fmt.Errorf("expecting %d bytes but got %d bytes", len(state), len(stateBytes)) 100 } 101 copy(state[:], stateBytes) 102 return state, nil 103 } 104 105 func (s StateCommitment) MarshalJSON() ([]byte, error) { 106 return json.Marshal(hex.EncodeToString(s[:])) 107 } 108 109 func (s *StateCommitment) UnmarshalJSON(data []byte) error { 110 // first, attempt to unmarshal assuming data is a hex string representation 111 err := s.unmarshalJSONHexString(data) 112 if err == nil { 113 return nil 114 } 115 // fallback to unmarshalling as [32]byte 116 return s.unmarshalJSONByteArr(data) 117 } 118 119 func (s *StateCommitment) unmarshalJSONHexString(data []byte) error { 120 var stateCommitmentHex string 121 if err := json.Unmarshal(data, &stateCommitmentHex); err != nil { 122 return err 123 } 124 b, err := hex.DecodeString(stateCommitmentHex) 125 if err != nil { 126 return err 127 } 128 h, err := hash.ToHash(b) 129 if err != nil { 130 return err 131 } 132 *s = StateCommitment(h) 133 return nil 134 } 135 136 func (s *StateCommitment) unmarshalJSONByteArr(data []byte) error { 137 var stateCommitment [32]byte 138 if err := json.Unmarshal(data, &stateCommitment); err != nil { 139 return err 140 } 141 *s = stateCommitment 142 return nil 143 }