github.com/onflow/flow-go@v0.33.17/fvm/evm/types/events.go (about)

     1  package types
     2  
     3  import (
     4  	"encoding/hex"
     5  
     6  	gethCommon "github.com/ethereum/go-ethereum/common"
     7  	"github.com/ethereum/go-ethereum/rlp"
     8  	"github.com/onflow/cadence"
     9  	"github.com/onflow/cadence/runtime/stdlib"
    10  
    11  	"github.com/onflow/flow-go/model/flow"
    12  )
    13  
    14  const (
    15  	EventTypeBlockExecuted       flow.EventType = "evm.BlockExecuted"
    16  	EventTypeTransactionExecuted flow.EventType = "evm.TransactionExecuted"
    17  )
    18  
    19  type EventPayload interface {
    20  	// CadenceEvent creates a Cadence event type
    21  	CadenceEvent() (cadence.Event, error)
    22  }
    23  
    24  type Event struct {
    25  	Etype   flow.EventType
    26  	Payload EventPayload
    27  }
    28  
    29  // we might break this event into two (tx included /tx executed) if size becomes an issue
    30  type TransactionExecutedPayload struct {
    31  	BlockHeight uint64
    32  	TxEncoded   []byte
    33  	TxHash      gethCommon.Hash
    34  	Result      *Result
    35  }
    36  
    37  var transactionExecutedEventCadenceType = &cadence.EventType{
    38  	Location:            stdlib.FlowLocation{},
    39  	QualifiedIdentifier: string(EventTypeTransactionExecuted),
    40  	Fields: []cadence.Field{
    41  		cadence.NewField("blockHeight", cadence.UInt64Type{}),
    42  		cadence.NewField("transactionHash", cadence.StringType{}),
    43  		cadence.NewField("transaction", cadence.StringType{}),
    44  		cadence.NewField("failed", cadence.BoolType{}),
    45  		cadence.NewField("transactionType", cadence.UInt8Type{}),
    46  		cadence.NewField("gasConsumed", cadence.UInt64Type{}),
    47  		cadence.NewField("deployedContractAddress", cadence.StringType{}),
    48  		cadence.NewField("returnedValue", cadence.StringType{}),
    49  		cadence.NewField("logs", cadence.StringType{}),
    50  	},
    51  }
    52  
    53  // todo add decoder for events from cadence to evm payload
    54  
    55  func (p *TransactionExecutedPayload) CadenceEvent() (cadence.Event, error) {
    56  	var encodedLogs []byte
    57  	var err error
    58  	if len(p.Result.Logs) > 0 {
    59  		encodedLogs, err = rlp.EncodeToBytes(p.Result.Logs)
    60  		if err != nil {
    61  			return cadence.Event{}, err
    62  		}
    63  	}
    64  
    65  	fields := []cadence.Value{
    66  		cadence.NewUInt64(p.BlockHeight),
    67  		cadence.String(p.TxHash.String()),
    68  		cadence.String(hex.EncodeToString(p.TxEncoded)),
    69  		cadence.NewBool(p.Result.Failed),
    70  		cadence.NewUInt8(p.Result.TxType),
    71  		cadence.NewUInt64(p.Result.GasConsumed),
    72  		cadence.String(hex.EncodeToString(p.Result.DeployedContractAddress.Bytes())),
    73  		cadence.String(hex.EncodeToString(p.Result.ReturnedValue)),
    74  		cadence.String(hex.EncodeToString(encodedLogs)),
    75  	}
    76  
    77  	return cadence.
    78  		NewEvent(fields).
    79  		WithType(transactionExecutedEventCadenceType), nil
    80  }
    81  
    82  func NewTransactionExecutedEvent(
    83  	height uint64,
    84  	txEncoded []byte,
    85  	txHash gethCommon.Hash,
    86  	result *Result,
    87  ) *Event {
    88  	return &Event{
    89  		Etype: EventTypeTransactionExecuted,
    90  		Payload: &TransactionExecutedPayload{
    91  			BlockHeight: height,
    92  			TxEncoded:   txEncoded,
    93  			TxHash:      txHash,
    94  			Result:      result,
    95  		},
    96  	}
    97  }
    98  
    99  var blockExecutedEventCadenceType = &cadence.EventType{
   100  	Location:            stdlib.FlowLocation{}, // todo create evm custom location
   101  	QualifiedIdentifier: string(EventTypeBlockExecuted),
   102  	Fields: []cadence.Field{
   103  		cadence.NewField("height", cadence.UInt64Type{}),
   104  		cadence.NewField("totalSupply", cadence.UInt64Type{}),
   105  		cadence.NewField("parentHash", cadence.StringType{}),
   106  		cadence.NewField("receiptRoot", cadence.StringType{}),
   107  		cadence.NewField(
   108  			"transactionHashes",
   109  			cadence.NewVariableSizedArrayType(cadence.StringType{}),
   110  		),
   111  	},
   112  }
   113  
   114  type BlockExecutedEventPayload struct {
   115  	Block *Block
   116  }
   117  
   118  func (p *BlockExecutedEventPayload) CadenceEvent() (cadence.Event, error) {
   119  	hashes := make([]cadence.Value, len(p.Block.TransactionHashes))
   120  	for i, hash := range p.Block.TransactionHashes {
   121  		hashes[i] = cadence.String(hash.String())
   122  	}
   123  
   124  	fields := []cadence.Value{
   125  		cadence.NewUInt64(p.Block.Height),
   126  		cadence.NewUInt64(p.Block.TotalSupply),
   127  		cadence.String(p.Block.ReceiptRoot.String()),
   128  		cadence.String(p.Block.ParentBlockHash.String()),
   129  		cadence.NewArray(hashes).WithType(cadence.NewVariableSizedArrayType(cadence.StringType{})),
   130  	}
   131  
   132  	return cadence.
   133  		NewEvent(fields).
   134  		WithType(blockExecutedEventCadenceType), nil
   135  }
   136  
   137  func NewBlockExecutedEvent(block *Block) *Event {
   138  	return &Event{
   139  		Etype: EventTypeBlockExecuted,
   140  		Payload: &BlockExecutedEventPayload{
   141  			Block: block,
   142  		},
   143  	}
   144  }