Skip to content

Conversation

@starius
Copy link
Collaborator

@starius starius commented Apr 1, 2025

A group of inputs can be added by passing it in SweepRequest.Inputs field.
All the inputs belong to the same swap and are added to the same batch.

Pull Request Checklist

  • Update release_notes.md if your PR contains major features, breaking changes or bugfixes

@starius starius changed the title [WIP] sweepbatcher: allow adding groups of inputs sweepbatcher: allow adding groups of inputs Apr 1, 2025
@starius starius marked this pull request as ready for review April 1, 2025 04:18
@starius starius requested review from bhandras, hieblmi and sputn1ck April 1, 2025 04:18
@starius starius force-pushed the group branch 2 times, most recently from f46a1d9 to 790b8ed Compare April 1, 2025 15:56
Copy link
Member

@bhandras bhandras left a comment

Choose a reason for hiding this comment

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

Looks really good, just a few nits and comments.

if err != nil {
return fmt.Errorf("failed to estimate tx weight for "+
"sweep %x: %w", sweep.swapHash[:6], err)
"swap %s: %w", swap[:6], err)
Copy link
Member

Choose a reason for hiding this comment

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

nit: i'd not rename "sweep" to "swap" as sweep is more general. Applies to everywhere else too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

}

// Track if there is an existing sweep and a new sweep among the sweeps.
var hasExisting, hasNew bool
Copy link
Member

Choose a reason for hiding this comment

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

nit: instead of hasExisting and hasNew consider using a counter instead. It might make the code a bit more readable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Replaced the flags with counts numExisting, numNew.

// Make sure the whole group is either new or existing. If this is not
// the case, this might be a bug, so print a warning.
if hasExisting && hasNew {
b.Warnf("There are existing and new sweeps among the group")
Copy link
Member

Choose a reason for hiding this comment

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

If using a counter approach we could also add more context to this warn log by logging the count of existing vs len(sweeps).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

}

// Make sure all the sweeps spend different outpoints.
used := make(map[wire.OutPoint]struct{}, len(sweeps))
Copy link
Member

Choose a reason for hiding this comment

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

nit: instead of used we could call it outpoints for readability.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Renamed it to outpointsSet.

// Group specifies multiple inputs in the same request. All the inputs
// belong to the same swap and are added to the same batch. If it is
// specified, OutPoint and Value must not be specified.
Group []Input
Copy link
Member

Choose a reason for hiding this comment

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

Could we just have the group? We don't really need the Output and Value then.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed. Thanks!
Also renamed the field from Group to Inputs.


if len(sweepReq.Group) != 0 {
// Make sure sweepReq.Outpoint, sweepReq.Value were not filled.
if sweepReq.Outpoint != (wire.OutPoint{}) {
Copy link
Member

Choose a reason for hiding this comment

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

... So then we wouldn't need these checks either.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

return sweeps, nil
}

s, err := b.loadSweep(
Copy link
Member

Choose a reason for hiding this comment

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

... And this loadSweep.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member

@bhandras bhandras left a comment

Choose a reason for hiding this comment

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

LGTM 🎉


// Make sure the whole group is either new or existing. If this is not
// the case, this might be a bug, so print a warning.
if numExisting > 0 && numNew > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

nit: we could also just check countExisting != len(sweeps).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We shouldn't return an error, if all the sweeps added are new. If all sweeps are new, countExisting=0 (and numNew=len(sweeps)).

if err != nil {
return false, err
// For an existing group, update the sweeps in the batch.
if numExisting > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

nit: ... and countExisting == len(sweeps)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed!

Copy link
Collaborator

@hieblmi hieblmi left a comment

Choose a reason for hiding this comment

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

Nice improvement. I left a question.

return false, err
}

// Track if there is an existing sweep and a new sweep among the sweeps.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: Track how many new and existing sweeps are among the sweeps.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed. Thanks!

// Add the sweep to the batch's sweeps.
b.Infof("adding sweep %x", sweep.swapHash[:6])
b.sweeps[sweep.outpoint] = *sweep
// Here is the code to add new sweeps to a batch.
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we check here that len(sweeps) is numNew and return an error otherwise.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This logically follows from the way numExisting and numNew were calculated and from the fact that we have checked above that only one of these categories has any sweeps in it.

I added the following double-check just in case:

        } else if numNew != len(sweeps) {
                // Sanity check: all the sweeps must be either existing or new.
                // We have checked this above, let's check here as well.
                return false, fmt.Errorf("bug in numExisting and numNew logic:"+
                        " numExisting=%d, numNew=%d, len(sweeps)=%d, "+
                        "len(b.sweeps)=%d", numExisting, numNew, len(sweeps),
                        len(b.sweeps))

}

if err := b.persistSweep(ctx, *s, false); err != nil {
return true, err
Copy link
Collaborator

Choose a reason for hiding this comment

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

does this count as accepted? Should we return false here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It was accepted in-memory, but failed to be persisted. Loop will shutdown with this error anyway.

Also this matches to the previous behavior:

        return true, b.persistSweep(ctx, *sweep, false)

@starius starius force-pushed the group branch 2 times, most recently from c1cb2bf to 8f050a7 Compare April 2, 2025 19:15
@starius starius requested a review from hieblmi April 2, 2025 19:18
@starius starius force-pushed the group branch 2 times, most recently from 45c24c0 to 283f31c Compare April 2, 2025 19:28
@starius
Copy link
Collaborator Author

starius commented Apr 2, 2025

Added a check to addSweeps that the number of sweeps is not zero.

        // This must be a bug, so log a warning.
        if len(sweeps) == 0 {
                b.Warnf("An attempt to add zero sweeps.")

                return false, nil
        }

Copy link
Collaborator

@hieblmi hieblmi left a comment

Choose a reason for hiding this comment

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

LGTM!

@starius
Copy link
Collaborator Author

starius commented Apr 3, 2025

Rebased

A group of inputs can be added by passing it in SweepRequest.Inputs field.
All the inputs belong to the same swap and are added to the same batch.
@starius starius merged commit 46b4f56 into lightninglabs:master Apr 3, 2025
4 checks passed
@starius starius deleted the group branch April 3, 2025 13:07
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.

3 participants