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