-
Notifications
You must be signed in to change notification settings - Fork 170
/
event.go
125 lines (105 loc) · 3.28 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
// (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,
}
}
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
// 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
}