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  }