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