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

EvalTracer: Txn group deltas Tracer #5297

Merged
merged 41 commits into from
Apr 27, 2023

Conversation

Eric-Warehime
Copy link
Contributor

@Eric-Warehime Eric-Warehime commented Apr 11, 2023

Summary

PR for adding a txn-group deltas tracer.

Also adds ledgercore.StateDelta to the AfterTxnGroup hook in the EvalTracer. Functionality is gated by a new config variable.

#5272

Test Plan

Unit tests included.

ledger/eval/eval.go Outdated Show resolved Hide resolved
jasonpaulos
jasonpaulos previously approved these changes Apr 24, 2023
Copy link
Contributor

@jasonpaulos jasonpaulos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks for addressing my earlier comments. I just have a minor question

ledger/eval/txntracer.go Outdated Show resolved Hide resolved
@@ -161,7 +162,7 @@ func (d *Tracer) BeforeTxnGroup(ep *logic.EvalParams) {
}

// AfterTxnGroup mocks the logic.EvalTracer.AfterTxnGroup method
func (d *Tracer) AfterTxnGroup(ep *logic.EvalParams, evalError error) {
func (d *Tracer) AfterTxnGroup(ep *logic.EvalParams, update *ledgercore.StateDelta, evalError error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Inconsistent naming. No strong preference for update, delta or deltas.

Suggested change
func (d *Tracer) AfterTxnGroup(ep *logic.EvalParams, update *ledgercore.StateDelta, evalError error) {
func (d *Tracer) AfterTxnGroup(ep *logic.EvalParams, deltas *ledgercore.StateDelta, evalError error) {

@@ -129,7 +130,11 @@ type EvalTracer interface {
// AfterTxnGroup is called after a transaction group has been executed. This includes both
// top-level and inner transaction groups. The argument ep is the EvalParams object for the
// group; if the group is an inner group, this is the EvalParams object for the inner group.
AfterTxnGroup(ep *EvalParams, evalError error)
//
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//

Comment on lines +40 to +41
// no-op methods we don't care about
logic.NullEvalTracer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious what others think about this. There are weird side effects of using inheritance in go like this (i.e. it doesn't actually use polymorphism, calls from the embedded interface don't call the parent overrides). These don't apply to NullEvalTracer, but I'm generally hesitant about showing off the pattern.

The alternative is empty function definitions, which doesn't seem that bad.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it does use "inheritance" in ways that don't seem idiomatic. This is how it's being done in other (all other?) tracers that I've seen so far in the codebase. https://github.com/algorand/go-algorand/blob/master/ledger/simulation/tracer.go#L30

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We considered a few different options before settling on the current NullEvalTracer idea. Originally we actually broke up the EvalTracer interface into many small ones, since we anticipated most tracers would only want to implement only a few related methods. Having to add a bunch of empty methods for things you don't care about seemed annoying, and it also slowed down development since there were frequent changes to methods.

It's definitely a bit weird though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the background. You might look into multiple optional interfaces and a cast check. We've been using that pattern for optional functions in Conduit. It's a little more work but a really nice interface to implement.

Here's one example. Plugins can optionally implement the Complete interface for a callback after a round is finished https://github.com/algorand/conduit/blob/585a568f091d333a79b27e872ef781206d90859d/conduit/pipeline/pipeline.go#L73

}

// GetDeltasForRound supplies all StateDelta objects for txn groups in a given rnd
func (tracer *TxnGroupDeltaTracer) GetDeltasForRound(rnd basics.Round) ([]ledgercore.StateDelta, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably needs a mutex in the next PR

require.NoError(t, err)
newBlock := bookkeeping.MakeBlock(blkHeader)
tracer := MakeTxnGroupDeltaTracer(4)
eval, err := l.StartEvaluator(newBlock.BlockHeader, 0, 0, tracer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants