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
eval: Add block hooks to eval tracer #5303
eval: Add block hooks to eval tracer #5303
Conversation
@@ -152,6 +152,7 @@ int 1`, | |||
mocktracer.AfterOpcode(false), | |||
mocktracer.AfterProgram(logic.ModeSig, false), | |||
// Txn evaluation | |||
mocktracer.BeforeBlock(block.Block().Round()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This order was surprising to me, but because LogicSig verification happens before the Txns in the block get evaluated the BeforeBlock
call will happen after LogicSig verification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty reasonable to me - is the plan to compare some sort of deltas between the two before/after block headers or simply to extract certain information from it, e.g. round num?
The reason I want it currently is to get the round num, but I thought it would be useful to have the whole header just in case we need other data from it as well. You can take a look at #5297 to see how the Tracer I'm writing needs something like this. It's still in draft though so there's a bunch of unfinished stuff in there. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just took a quick pass, and I think the PR might be interesting on simulation aspect (if I read the PR correctly), but might be hard (or unreasonable) to do. I was thinking:
If we are overloading some runtime config in EvalContext
for certain opcodes during simulating multiple txn-groups, then the current implementation is to overload the configs inside cx *EvalContext
during BeforeTxnGroup
.
I think it might be better to just overload config once in BeforeBlock
, assuming the multiple txn-groups are falling into same block, and EvalContext
can be maintained through more than one txn-groups.
But that might be not the purpose of this PR, and EvalContext
is not avail on block level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a safe PR, but I don't see the big picture yet for its impact. I left a couple of commentary nits and a question.
Round basics.Round | ||
} | ||
|
||
// BeforeBlock creates a new Event with the type BeforeBlockEvent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// BeforeBlock creates a new Event with the type BeforeBlockEvent | |
// BeforeBlock creates a new Event with the type BeforeBlockEvent for a particular round |
ignorable nit
@@ -833,13 +834,14 @@ func (l *Ledger) VerifiedTransactionCache() verify.VerifiedTransactionCache { | |||
// provides a cap on the size of a single generated block size, when a non-zero value is passed. | |||
// If a value of zero or less is passed to maxTxnBytesPerBlock, the consensus MaxTxnBytesPerBlock would | |||
// be used instead. | |||
func (l *Ledger) StartEvaluator(hdr bookkeeping.BlockHeader, paysetHint, maxTxnBytesPerBlock int) (*eval.BlockEvaluator, error) { | |||
func (l *Ledger) StartEvaluator(hdr bookkeeping.BlockHeader, paysetHint, maxTxnBytesPerBlock int, tracer logic.EvalTracer) (*eval.BlockEvaluator, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add an explanation of the optional tracer
param as well?
tracer := &mocktracer.Tracer{} | ||
eval, err := l.StartEvaluator(newBlock.BlockHeader, 0, 0, tracer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this test being modified purely because there is now a prefered way to attach a tracer? I'm trying to understand what new behavior is being tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's both the new way of attaching the tracer, but also the new Before/After Block hooks. Here I've modified how the tracer is attached, and below you can see I've added the mocktracer.AfterBlock(eval.block.Round()),
event to assert that the tracer was called as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good. I just have minor comments
I didn't intend for the block evaluator to carry state across txns/groups like that, but I guess you could do it if you wanted. The EvalContext doesn't have anything to do with the ledger's idea of starting and finishing block evaluation though. It's just involved in contract evaluation. |
Right now it's just to extract the round from them--I've included the whole header to have a more generalized interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor question below but looks good
Summary
Adds
BeforeBlock
andAfterBlock
hooks to theEvalTracer
interface.This should be a no-op for most of the things which Simulate is trying to do, but gives the Tracer a sense of which Block a given set invocations covers. That's important since the
EvalContext
andEvalParams
from what I can tell don't have a deterministic way of looking at which round they're evaluating for without direct access to theBlockEvaluator
itself.Test Plan
Updated existing test to ensure calls are properly made during eval lifecycle.