Skip to content

Commit

Permalink
Added TxTracer to DeliverTxEntry which is the first step to suppo…
Browse files Browse the repository at this point in the history
…rt tracing when using OCC

This brings in an interface that can be set on `DeliverTxEntry` and hooks into the `scheduler` so it call's the necessary tracer callbacks when required.

Refer to `types/tx_tracer.go` for extra details about the patch.
  • Loading branch information
maoueh committed Mar 27, 2024
1 parent ed1bd73 commit 8e22d1d
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
20 changes: 20 additions & 0 deletions tasks/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type deliverTxTask struct {
AbsoluteIndex int
Response *types.ResponseDeliverTx
VersionStores map[sdk.StoreKey]*multiversion.VersionIndexedStore
TxTracer sdk.TxTracer
}

// AppendDependencies appends the given indexes to the task's dependencies
Expand Down Expand Up @@ -83,6 +84,10 @@ func (dt *deliverTxTask) Reset() {
dt.Abort = nil
dt.AbortCh = nil
dt.VersionStores = nil

if dt.TxTracer != nil {
dt.TxTracer.Reset()
}
}

func (dt *deliverTxTask) Increment() {
Expand Down Expand Up @@ -187,7 +192,9 @@ func toTasks(reqs []*sdk.DeliverTxEntry) ([]*deliverTxTask, map[int]*deliverTxTa
AbsoluteIndex: r.AbsoluteIndex,
Status: statusPending,
Dependencies: map[int]struct{}{},
TxTracer: r.TxTracer,
}

tasksMap[r.AbsoluteIndex] = task
allTasks = append(allTasks, task)
}
Expand All @@ -198,6 +205,10 @@ func (s *scheduler) collectResponses(tasks []*deliverTxTask) []types.ResponseDel
res := make([]types.ResponseDeliverTx, 0, len(tasks))
for _, t := range tasks {
res = append(res, *t.Response)

if t.TxTracer != nil {
t.TxTracer.Commit()
}
}
return res
}
Expand Down Expand Up @@ -508,6 +519,15 @@ func (s *scheduler) prepareTask(task *deliverTxTask) {
ctx = ctx.WithMultiStore(ms)
}

if task.TxTracer != nil {
ctx = task.TxTracer.InjectInContext(ctx)

// Temporary workaround to the fact that sometimes `task.Reset()` is not called
// but a transaction is still re-executed which can cause problem with the TxTracer
// that hasn't reset its state.
task.TxTracer.Reset()
}

task.AbortCh = abortCh
task.Ctx = ctx
}
Expand Down
3 changes: 2 additions & 1 deletion types/tx_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
)

// DeliverTxEntry represents an individual transaction's request within a batch.
// This can be extended to include tx-level tracing or metadata
// This can be extended to include tx-level metadata
type DeliverTxEntry struct {
Request abci.RequestDeliverTx
SdkTx Tx
Checksum [32]byte
AbsoluteIndex int
EstimatedWritesets MappedWritesets
TxTracer TxTracer
}

// EstimatedWritesets represents an estimated writeset for a transaction mapped by storekey to the writeset estimate.
Expand Down
44 changes: 44 additions & 0 deletions types/tx_tracer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package types

// TxTracer is an interface for tracing transactions generic
// enough to be used by any transaction processing engine be it
// CoWasm or EVM.
//
// The TxTracer responsibility is to inject itself in the context
// that will be used to process the transaction. How the context
// will be used afterward is up to the transaction processing engine.
//
// Today, only EVM transaction processing engine do something with the
// TxTracer (it inject itself into the EVM execution context for
// go-ethereum level tracing).
//
// The TxTracer receives signals from the scheduler when the tracer
// should be reset because the transaction is being re-executed and
// when the transaction is committed.
type TxTracer interface {
// InjectInContext injects the transaction specific tracer in the context
// that will be used to process the transaction.
//
// For now only the EVM transaction processing engine uses the tracer
// so it only make sense to inject an EVM tracer. Future updates might
// add the possibility to inject a tracer for other transaction kind.
//
// Which tracer implementation to provied and how will be retrieved later on
// from the context is dependent on the transaction processing engine.
InjectInContext(ctx Context) Context

// Reset is called when the transaction is being re-executed and the tracer
// should be reset. A transaction executed by the OCC parallel engine might
// be re-executed multiple times before being committed, each time `Reset`
// will be called.
//
// When Reset is received, it means everything that was traced before should
// be discarded.
Reset()

// Commit is called when the transaction is committed. This is the last signal
// the tracer will receive for a given transaction. After this call, the tracer
// should do whatever it needs to forward the tracing information to the
// appropriate place/collector.
Commit()
}

0 comments on commit 8e22d1d

Please sign in to comment.