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

Big refactor to clean up the WatchSlots logic #34

Merged
merged 8 commits into from
Oct 6, 2024
Merged

Conversation

johnstonematt
Copy link
Contributor

@johnstonematt johnstonematt commented Oct 3, 2024

Main Refactor

I replaced the monolithic WatchSlots() with the SolanaCollector.WatchSlots(), which I personally believe is much better for reasons such as:

  • Clear indication of state and tracking parameters
  • More, smaller functions

In general, the logic in the previous one was just insanely hard to follow, and I am 99% certain there were double counting errors on epoch boundaries.

One of the main things I focused on in SolanaCollector.WatchSlots() was to clearly mark the logic that is executed on epoch boundary, to make it easy to implement things like inflationary and Jito reward tracking, which happens at epoch bounds.

Other changes:

  • I refactored the rpc.Client to make the functions more like a direct overlay of the RPC API, without any additional logic.
  • Updated the Commitment levels, as the ones used have been deprecated for a while.

Still to come:

With the logic split up more granularly now, more tests can be done.

@johnstonematt johnstonematt changed the base branch from master to github-actions October 3, 2024 15:51
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would advise just reading this file plainly as is, as the whole thing was rewritten and so the diff is not very helpful IMO

Base automatically changed from github-actions to master October 4, 2024 05:47
Comment on lines 8 to 12
func assertf(condition bool, format string, args ...any) {
if !condition {
panic(fmt.Errorf(format, args...))
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of a bare panic with the string, instead use klog.Fatalf(format, args...).

fwiw, generally speaking, for non-safety critical things, I consider panics in code to be code smell. If possible, just lazily loop and try again when feasible instead of hard crashing.

func (c *SlotWatcher) checkValidSlotRange(from, to int64) error {
if from < c.firstSlot || to > c.lastSlot {
return fmt.Errorf(
"start-end slots (%v -> %v) is not contained within current epoch %v range (%v -> %v)",
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
"start-end slots (%v -> %v) is not contained within current epoch %v range (%v -> %v)",
"start-end slots (%v -> %v) are not contained within current epoch %v range (%v -> %v)",


// make sure the bounds are contained within the epoch we are currently watching:
if err := c.checkValidSlotRange(startSlot, endSlot); err != nil {
panic(err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is a panic really necessary in this case? Can we not just gracefully skip this or reset things some how? Also, perhaps instead of a panic (which dumps all goroutines + stack traces to stdout, we just do something more like klog.Fatal(err.String()) or maybe klog.Fatalf("slot range is out of bounds of the current epoch: %v", err)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason I panic here is because if it happens then it's a logic issue in the code, not just some random event.

// For pretty-printed JSON, use json.MarshalIndent
prettyJSON, err := json.MarshalIndent(obj, "", " ")
if err != nil {
fmt.Println("Error marshalling to pretty JSON:", err, ". obj: ", obj)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be using something like this? klog.Info("error marshalling to pretty JSON: %s. obj: %v", err, obj)

Bare fmt.Print.. in code that is long running is generally a bug.

// CommitmentFinalized level offers the highest level of certainty for a transaction on the Solana blockchain.
// A transaction is considered “Finalized” when it is included in a block that has been confirmed by a
// supermajority of the stake, and at least 31 additional confirmed blocks have been built on top of it.
CommitmentFinalized Commitment = "finalized"
Copy link
Contributor

Choose a reason for hiding this comment

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

For the usage of the exporter, do we actually need to use finalized blocks? This is ~15 seconds behind the latest roughly. For monitoring, max is probably good enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The "max" commitment is deprecated, current levels are only "finalized", "confirmed" and "processed", and "max" maps to "finalized", as per this commit

if lastSlot != nil {
// make sure first and last slot are in order:
if *firstSlot > *lastSlot {
panic(fmt.Errorf("last slot %v is greater than first slot %v", *lastSlot, *firstSlot))
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we just return this as an error instead of panicking? Less panicking is good.

@johnstonematt johnstonematt merged commit f955410 into master Oct 6, 2024
2 checks passed
@johnstonematt johnstonematt deleted the watch-slots branch October 6, 2024 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants