contractcourt: offer second-level outputs at CSV-1

This commit moves the offering of second-level outputs one block
earlier. The sweeper will check the required locktime and wait until it
matures. This is needed so the second-level outputs can be aggregated
properly.
This commit is contained in:
yyforyongyu committed 2024-04-19 21:33:35 +08:00
1 parent c644deb49f
commit acde08c65a
4 files changed
+77 -12

No files matched your search

+16 -2
View File
@@ -652,7 +652,7 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch) {
// failed, or excluded from the sweeper and return inputs that
// are either new or has been published but failed back, which
// will be retried again here.
inputs := s.updateSweeperInputs()
s.updateSweeperInputs()
select {
// A new inputs is offered to the sweeper. We check to see if
@@ -670,7 +670,7 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch) {
// If this input is forced, we perform an sweep
// immediately.
if input.params.Force {
inputs = s.updateSweeperInputs()
inputs := s.updateSweeperInputs()
s.sweepPendingInputs(inputs)
}
@@ -716,6 +716,9 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch) {
// Update the sweeper to the best height.
s.currentHeight = epoch.Height
// Update the inputs with the latest height.
inputs := s.updateSweeperInputs()
log.Debugf("Received new block: height=%v, attempt "+
"sweeping %d inputs", epoch.Height, len(inputs))
@@ -1497,6 +1500,17 @@ func (s *UtxoSweeper) updateSweeperInputs() InputsMap {
continue
}
// If the input has a CSV that's not yet reached, we will skip
// this input and wait for the expiry.
locktime = input.BlocksToMaturity() + input.HeightHint()
if s.currentHeight < int32(locktime)-1 {
log.Infof("Skipping input %v due to CSV expiry=%v not "+
"reached, current height is %v", op, locktime,
s.currentHeight)
continue
}
// If this input is new or has been failed to be published,
// we'd retry it. The assumption here is that when an error is
// returned from `PublishTransaction`, it means the tx has
+16
View File
@@ -2479,6 +2479,8 @@ func TestUpdateSweeperInputs(t *testing.T) {
defer inp1.AssertExpectations(t)
inp2 := &input.MockInput{}
defer inp2.AssertExpectations(t)
inp3 := &input.MockInput{}
defer inp3.AssertExpectations(t)
// Create a list of inputs using all the states.
//
@@ -2486,6 +2488,8 @@ func TestUpdateSweeperInputs(t *testing.T) {
// returned.
inp1.On("RequiredLockTime").Return(
uint32(s.currentHeight), false).Once()
inp1.On("BlocksToMaturity").Return(uint32(0)).Once()
inp1.On("HeightHint").Return(uint32(s.currentHeight)).Once()
input0 := &SweeperInput{state: Init, Input: inp1}
// These inputs won't hit RequiredLockTime so we won't mock.
@@ -2496,6 +2500,8 @@ func TestUpdateSweeperInputs(t *testing.T) {
// returned.
inp1.On("RequiredLockTime").Return(
uint32(s.currentHeight), false).Once()
inp1.On("BlocksToMaturity").Return(uint32(0)).Once()
inp1.On("HeightHint").Return(uint32(s.currentHeight)).Once()
input3 := &SweeperInput{state: PublishFailed, Input: inp1}
// These inputs won't hit RequiredLockTime so we won't mock.
@@ -2509,6 +2515,14 @@ func TestUpdateSweeperInputs(t *testing.T) {
uint32(s.currentHeight+1), true).Once()
input7 := &SweeperInput{state: Init, Input: inp2}
// Mock the input to have a CSV expiry in the future so it will NOT be
// returned.
inp3.On("RequiredLockTime").Return(
uint32(s.currentHeight), false).Once()
inp3.On("BlocksToMaturity").Return(uint32(2)).Once()
inp3.On("HeightHint").Return(uint32(s.currentHeight)).Once()
input8 := &SweeperInput{state: Init, Input: inp3}
// Add the inputs to the sweeper. After the update, we should see the
// terminated inputs being removed.
s.inputs = map[wire.OutPoint]*SweeperInput{
@@ -2520,6 +2534,7 @@ func TestUpdateSweeperInputs(t *testing.T) {
{Index: 5}: input5,
{Index: 6}: input6,
{Index: 7}: input7,
{Index: 8}: input8,
}
// We expect the inputs with `Swept`, `Excluded`, and `Failed` to be
@@ -2530,6 +2545,7 @@ func TestUpdateSweeperInputs(t *testing.T) {
{Index: 2}: input2,
{Index: 3}: input3,
{Index: 7}: input7,
{Index: 8}: input8,
}
// We expect only the inputs with `Init` and `PublishFailed` to be