Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EVM] Optimize event data #5779

Merged
merged 17 commits into from
Apr 26, 2024
22 changes: 5 additions & 17 deletions fvm/evm/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,18 +195,12 @@ func (h *ContractHandler) run(
}

// step 4 - emit events
err = h.emitEvent(types.NewTransactionExecutedEvent(
bp.Height,
rlpEncodedTx,
blockHash,
res.TxHash,
res,
))
err = h.emitEvent(types.NewTransactionEvent(res, rlpEncodedTx, bp.Height, blockHash))
if err != nil {
return nil, err
}

err = h.emitEvent(types.NewBlockExecutedEvent(bp))
err = h.emitEvent(types.NewBlockEvent(bp))
if err != nil {
return nil, err
}
Expand All @@ -232,7 +226,7 @@ func (h *ContractHandler) meterGasUsage(res *types.Result) error {
}

func (h *ContractHandler) emitEvent(event *types.Event) error {
ev, err := event.Payload.CadenceEvent()
ev, err := event.Payload.ToCadence()
if err != nil {
return err
}
Expand Down Expand Up @@ -333,19 +327,13 @@ func (h *ContractHandler) executeAndHandleCall(
}

err = h.emitEvent(
types.NewTransactionExecutedEvent(
bp.Height,
encoded,
blockHash,
res.TxHash,
res,
),
types.NewTransactionEvent(res, encoded, bp.Height, blockHash),
)
if err != nil {
return nil, err
}

err = h.emitEvent(types.NewBlockExecutedEvent(bp))
err = h.emitEvent(types.NewBlockEvent(bp))
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion fvm/evm/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
)

type ErrorCode uint64
type ErrorCode uint16

// internal error codes
const ( // code reserved for no error
Expand Down
132 changes: 84 additions & 48 deletions fvm/evm/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,45 @@ const (
)

type EventPayload interface {
// CadenceEvent creates a Cadence event type
CadenceEvent() (cadence.Event, error)
// ToCadence converts the event to Cadence event
ToCadence() (cadence.Event, error)
}

type BlockEventPayload struct {
Height uint64 `cadence:"height"`
Hash string `cadence:"hash"`
Timestamp uint64 `cadence:"timestamp"`
TotalSupply cadence.Int `cadence:"totalSupply"`
ParentBlockHash string `cadence:"parentHash"`
ReceiptRoot string `cadence:"receiptRoot"`
TransactionHashes []cadence.String `cadence:"transactionHashes"`
}

// DecodeBlockEventPayload decodes Cadence event into block event payload.
func DecodeBlockEventPayload(event cadence.Event) (*BlockEventPayload, error) {
var block BlockEventPayload
err := cadence.DecodeFields(event, &block)
return &block, err
}

type TransactionEventPayload struct {
Hash string `cadence:"hash"`
Index uint16 `cadence:"index"`
TransactionType uint8 `cadence:"type"`
Payload string `cadence:"payload"`
Error uint16 `cadence:"error"`
GasConsumed uint64 `cadence:"gasConsumed"`
ContractAddress string `cadence:"contractAddress"`
Logs string `cadence:"logs"`
BlockHeight uint64 `cadence:"blockHeight"`
BlockHash string `cadence:"blockHash"`
}

// DecodeTransactionEventPayload decodes Cadence event into transaction event payload.
func DecodeTransactionEventPayload(event cadence.Event) (*TransactionEventPayload, error) {
var tx TransactionEventPayload
err := cadence.DecodeFields(event, &tx)
return &tx, err
}

type Event struct {
Expand Down Expand Up @@ -98,15 +135,14 @@ func init() {

// todo we might have to break this event into two (tx included /tx executed) if size becomes an issue

type TransactionExecutedPayload struct {
type transactionEvent struct {
Payload []byte // transaction RLP-encoded payload
Result *Result // transaction execution result
BlockHeight uint64
TxEncoded []byte
BlockHash gethCommon.Hash
TxHash gethCommon.Hash
Result *Result
}

func (p *TransactionExecutedPayload) CadenceEvent() (cadence.Event, error) {
func (p *transactionEvent) ToCadence() (cadence.Event, error) {
var encodedLogs []byte
var err error
if len(p.Result.Logs) > 0 {
Expand All @@ -121,50 +157,51 @@ func (p *TransactionExecutedPayload) CadenceEvent() (cadence.Event, error) {
EVMLocation{},
string(EventTypeTransactionExecuted),
[]cadence.Field{
cadence.NewField("blockHeight", cadence.UInt64Type{}),
cadence.NewField("blockHash", cadence.StringType{}),
cadence.NewField("transactionHash", cadence.StringType{}),
cadence.NewField("transaction", cadence.StringType{}),
cadence.NewField("failed", cadence.BoolType{}),
cadence.NewField("vmError", cadence.StringType{}),
cadence.NewField("transactionType", cadence.UInt8Type{}),
cadence.NewField("hash", cadence.StringType{}),
cadence.NewField("index", cadence.UInt16Type{}),
cadence.NewField("type", cadence.UInt8Type{}),
cadence.NewField("payload", cadence.StringType{}),
cadence.NewField("error", cadence.UInt16Type{}),
cadence.NewField("gasConsumed", cadence.UInt64Type{}),
cadence.NewField("deployedContractAddress", cadence.StringType{}),
cadence.NewField("returnedValue", cadence.StringType{}),
cadence.NewField("contractAddress", cadence.StringType{}),
cadence.NewField("logs", cadence.StringType{}),
cadence.NewField("blockHeight", cadence.UInt64Type{}),
cadence.NewField("blockHash", cadence.StringType{}),
},
nil,
),
Fields: []cadence.Value{
cadence.NewUInt64(p.BlockHeight),
cadence.String(p.BlockHash.String()),
cadence.String(p.TxHash.String()),
cadence.String(hex.EncodeToString(p.TxEncoded)),
cadence.Bool(p.Result.Failed()),
cadence.String(p.Result.VMErrorString()),
cadence.String(p.Result.TxHash.String()),
cadence.NewUInt16(p.Result.Index),
cadence.NewUInt8(p.Result.TxType),
cadence.String(hex.EncodeToString(p.Payload)),
cadence.NewUInt16(uint16(p.Result.ResultSummary().ErrorCode)),
cadence.NewUInt64(p.Result.GasConsumed),
cadence.String(p.Result.DeployedContractAddress.String()),
cadence.String(hex.EncodeToString(p.Result.ReturnedValue)),
cadence.String(hex.EncodeToString(encodedLogs)),
cadence.NewUInt64(p.BlockHeight),
cadence.String(p.BlockHash.String()),
},
}, nil
}

func NewTransactionExecutedEvent(
height uint64,
txEncoded []byte,
blockHash gethCommon.Hash,
txHash gethCommon.Hash,
// NewTransactionEvent creates a new transaction event with the given parameters
// - result: the result of the transaction execution
// - payload: the RLP-encoded payload of the transaction
// - blockHeight: the height of the block where the transaction is included
// - blockHash: the hash of the block where the transaction is included
func NewTransactionEvent(
result *Result,
payload []byte,
blockHeight uint64,
blockHash gethCommon.Hash,
) *Event {
return &Event{
Etype: EventTypeTransactionExecuted,
Payload: &TransactionExecutedPayload{
BlockHeight: height,
Payload: &transactionEvent{
BlockHeight: blockHeight,
BlockHash: blockHash,
TxEncoded: txEncoded,
TxHash: txHash,
Payload: payload,
Result: result,
},
}
Expand All @@ -187,28 +224,28 @@ var blockExecutedEventCadenceType = &cadence.EventType{
},
}

type BlockExecutedEventPayload struct {
Block *Block
type blockEvent struct {
*Block
}

func (p *BlockExecutedEventPayload) CadenceEvent() (cadence.Event, error) {
hashes := make([]cadence.Value, len(p.Block.TransactionHashes))
for i, hash := range p.Block.TransactionHashes {
func (p *blockEvent) ToCadence() (cadence.Event, error) {
hashes := make([]cadence.Value, len(p.TransactionHashes))
for i, hash := range p.TransactionHashes {
hashes[i] = cadence.String(hash.String())
}

blockHash, err := p.Block.Hash()
blockHash, err := p.Hash()
if err != nil {
return cadence.Event{}, err
}

fields := []cadence.Value{
cadence.NewUInt64(p.Block.Height),
cadence.NewUInt64(p.Height),
cadence.String(blockHash.String()),
cadence.NewUInt64(p.Block.Timestamp),
cadence.NewIntFromBig(p.Block.TotalSupply),
cadence.String(p.Block.ParentBlockHash.String()),
cadence.String(p.Block.ReceiptRoot.String()),
cadence.NewUInt64(p.Timestamp),
cadence.NewIntFromBig(p.TotalSupply),
cadence.String(p.ParentBlockHash.String()),
cadence.String(p.ReceiptRoot.String()),
cadence.NewArray(hashes).WithType(cadence.NewVariableSizedArrayType(cadence.StringType{})),
}

Expand All @@ -217,11 +254,10 @@ func (p *BlockExecutedEventPayload) CadenceEvent() (cadence.Event, error) {
WithType(blockExecutedEventCadenceType), nil
}

func NewBlockExecutedEvent(block *Block) *Event {
// NewBlockEvent creates a new block event with the given block as payload.
func NewBlockEvent(block *Block) *Event {
return &Event{
Etype: EventTypeBlockExecuted,
Payload: &BlockExecutedEventPayload{
Block: block,
},
Etype: EventTypeBlockExecuted,
Payload: &blockEvent{block},
}
}
Loading