github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/flow/event.go (about) 1 package flow 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/onflow/flow-go/model/encoding/json" 8 "github.com/onflow/flow-go/model/fingerprint" 9 "github.com/onflow/flow-go/storage/merkle" 10 ) 11 12 // List of built-in event types. 13 const ( 14 EventAccountCreated EventType = "flow.AccountCreated" 15 EventAccountUpdated EventType = "flow.AccountUpdated" 16 ) 17 18 type EventType string 19 20 type Event struct { 21 // Type is the qualified event type. 22 Type EventType 23 // TransactionID is the ID of the transaction this event was emitted from. 24 TransactionID Identifier 25 // TransactionIndex defines the index of the transaction this event was emitted from within the block. 26 // The first transaction has index 0, the second has index 1, and so on. 27 TransactionIndex uint32 28 // EventIndex defines the ordering of events in a transaction. 29 // The first event emitted has index 0, the second has index 1, and so on. 30 EventIndex uint32 31 // Payload contains the encoded event data. 32 Payload []byte 33 } 34 35 // String returns the string representation of this event. 36 func (e Event) String() string { 37 return fmt.Sprintf("%s: %s", e.Type, e.ID()) 38 } 39 40 // ID returns a canonical identifier that is guaranteed to be unique. 41 func (e Event) ID() Identifier { 42 return MakeID(wrapEventID(e)) 43 } 44 45 func (e Event) Checksum() Identifier { 46 return MakeID(e) 47 } 48 49 // Encode returns the canonical encoding of this event, containing only the fields necessary to uniquely identify it. 50 func (e Event) Encode() []byte { 51 w := wrapEventID(e) 52 return json.NewMarshaler().MustMarshal(w) 53 } 54 55 func (e Event) Fingerprint() []byte { 56 return fingerprint.Fingerprint(wrapEvent(e)) 57 } 58 59 // Defines only the fields needed to uniquely identify an event. 60 type eventIDWrapper struct { 61 TxID []byte 62 Index uint32 63 } 64 65 type eventWrapper struct { 66 TxID []byte 67 Index uint32 68 Type string 69 TransactionIndex uint32 70 Payload []byte 71 } 72 73 func wrapEventID(e Event) eventIDWrapper { 74 return eventIDWrapper{ 75 TxID: e.TransactionID[:], 76 Index: e.EventIndex, 77 } 78 } 79 80 // byteSize returns the number of bytes needed to store the wrapped version of the event. 81 // returned int is an approximate measure, ignoring the number of bytes needed as headers. 82 func (e Event) byteSize() int { 83 return IdentifierLen + // txID 84 4 + // Index 85 len(e.Type) + // Type 86 4 + // TransactionIndex 87 len(e.Payload) // Payload 88 } 89 90 func wrapEvent(e Event) eventWrapper { 91 return eventWrapper{ 92 TxID: e.TransactionID[:], 93 Index: e.EventIndex, 94 Type: string(e.Type), 95 TransactionIndex: e.TransactionIndex, 96 Payload: e.Payload[:], 97 } 98 } 99 100 // BlockEvents contains events emitted in a single block. 101 type BlockEvents struct { 102 BlockID Identifier 103 BlockHeight uint64 104 BlockTimestamp time.Time 105 Events []Event 106 } 107 108 type EventsList []Event 109 110 // byteSize returns an approximate number of bytes needed to store the wrapped version of the event. 111 func (el EventsList) ByteSize() int { 112 size := 0 113 for _, event := range el { 114 size += event.byteSize() 115 } 116 return size 117 } 118 119 // EventsMerkleRootHash calculates the root hash of events inserted into a 120 // merkle trie with the hash of event as the key and encoded event as value 121 func EventsMerkleRootHash(el EventsList) (Identifier, error) { 122 tree, err := merkle.NewTree(IdentifierLen) 123 if err != nil { 124 return ZeroID, fmt.Errorf("instantiating payload trie for key length of %d bytes failed: %w", IdentifierLen, err) 125 } 126 127 for _, event := range el { 128 // event fingerprint is the rlp encoding of the wrapperevent 129 // eventID is the standard sha3 hash of the event fingerprint 130 fingerPrint := event.Fingerprint() 131 // computing enityID from the fingerprint 132 eventID := MakeIDFromFingerPrint(fingerPrint) 133 _, err = tree.Put(eventID[:], fingerPrint) 134 if err != nil { 135 return ZeroID, err 136 } 137 } 138 139 var root Identifier 140 copy(root[:], tree.Hash()) 141 return root, nil 142 }