sweep: rename pendingInputs to inputs on sweeper

There's no need use the prefix `pending` as the inputs in the sweeper
can only be pending, so it's renamed, also to avoid the confusion with
the type `pendingInputs`.
This commit is contained in:
yyforyongyu 2024-03-18 03:00:58 +08:00
parent 0063770cb7
commit 9e7d4b7e0b
No known key found for this signature in database
GPG key ID: 9BCD95C4FF296868
2 changed files with 56 additions and 57 deletions

View file

@ -307,9 +307,9 @@ type UtxoSweeper struct {
// callers who wish to bump the fee rate of a given input. // callers who wish to bump the fee rate of a given input.
updateReqs chan *updateReq updateReqs chan *updateReq
// pendingInputs is the total set of inputs the UtxoSweeper has been // inputs is the total set of inputs the UtxoSweeper has been requested
// requested to sweep. // to sweep.
pendingInputs pendingInputs inputs pendingInputs
currentOutputScript []byte currentOutputScript []byte
@ -408,7 +408,7 @@ func New(cfg *UtxoSweeperConfig) *UtxoSweeper {
updateReqs: make(chan *updateReq), updateReqs: make(chan *updateReq),
pendingSweepsReqs: make(chan *pendingSweepsReq), pendingSweepsReqs: make(chan *pendingSweepsReq),
quit: make(chan struct{}), quit: make(chan struct{}),
pendingInputs: make(pendingInputs), inputs: make(pendingInputs),
bumpResultChan: make(chan *BumpResult, 100), bumpResultChan: make(chan *BumpResult, 100),
} }
} }
@ -724,7 +724,7 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch) {
// them from being part of future sweep transactions that would fail. In // them from being part of future sweep transactions that would fail. In
// addition sweep transactions of those inputs will be removed from the wallet. // addition sweep transactions of those inputs will be removed from the wallet.
func (s *UtxoSweeper) removeExclusiveGroup(group uint64) { func (s *UtxoSweeper) removeExclusiveGroup(group uint64) {
for outpoint, input := range s.pendingInputs { for outpoint, input := range s.inputs {
outpoint := outpoint outpoint := outpoint
// Skip inputs that aren't exclusive. // Skip inputs that aren't exclusive.
@ -860,7 +860,7 @@ func (s *UtxoSweeper) sweep(set InputSet) error {
func (s *UtxoSweeper) markInputsPendingPublish(set InputSet) { func (s *UtxoSweeper) markInputsPendingPublish(set InputSet) {
// Reschedule sweep. // Reschedule sweep.
for _, input := range set.Inputs() { for _, input := range set.Inputs() {
pi, ok := s.pendingInputs[*input.OutPoint()] pi, ok := s.inputs[*input.OutPoint()]
if !ok { if !ok {
// It could be that this input is an additional wallet // It could be that this input is an additional wallet
// input that was attached. In that case there also // input that was attached. In that case there also
@ -909,7 +909,7 @@ func (s *UtxoSweeper) markInputsPublished(tr *TxRecord,
// Reschedule sweep. // Reschedule sweep.
for _, input := range inputs { for _, input := range inputs {
pi, ok := s.pendingInputs[input.PreviousOutPoint] pi, ok := s.inputs[input.PreviousOutPoint]
if !ok { if !ok {
// It could be that this input is an additional wallet // It could be that this input is an additional wallet
// input that was attached. In that case there also // input that was attached. In that case there also
@ -941,7 +941,7 @@ func (s *UtxoSweeper) markInputsPublished(tr *TxRecord,
func (s *UtxoSweeper) markInputsPublishFailed(outpoints []wire.OutPoint) { func (s *UtxoSweeper) markInputsPublishFailed(outpoints []wire.OutPoint) {
// Reschedule sweep. // Reschedule sweep.
for _, op := range outpoints { for _, op := range outpoints {
pi, ok := s.pendingInputs[op] pi, ok := s.inputs[op]
if !ok { if !ok {
// It could be that this input is an additional wallet // It could be that this input is an additional wallet
// input that was attached. In that case there also // input that was attached. In that case there also
@ -1039,8 +1039,8 @@ func (s *UtxoSweeper) PendingInputs() (map[wire.OutPoint]*PendingInput, error) {
func (s *UtxoSweeper) handlePendingSweepsReq( func (s *UtxoSweeper) handlePendingSweepsReq(
req *pendingSweepsReq) map[wire.OutPoint]*PendingInput { req *pendingSweepsReq) map[wire.OutPoint]*PendingInput {
pendingInputs := make(map[wire.OutPoint]*PendingInput, len(s.pendingInputs)) pendingInputs := make(map[wire.OutPoint]*PendingInput, len(s.inputs))
for _, pendingInput := range s.pendingInputs { for _, pendingInput := range s.inputs {
// Only the exported fields are set, as we expect the response // Only the exported fields are set, as we expect the response
// to only be consumed externally. // to only be consumed externally.
op := *pendingInput.OutPoint() op := *pendingInput.OutPoint()
@ -1117,7 +1117,7 @@ func (s *UtxoSweeper) handleUpdateReq(req *updateReq) (
// batched with others which also have a similar fee rate, creating a // batched with others which also have a similar fee rate, creating a
// higher fee rate transaction that replaces the original input's // higher fee rate transaction that replaces the original input's
// sweeping transaction. // sweeping transaction.
pendingInput, ok := s.pendingInputs[req.input] pendingInput, ok := s.inputs[req.input]
if !ok { if !ok {
return nil, lnwallet.ErrNotMine return nil, lnwallet.ErrNotMine
} }
@ -1212,7 +1212,7 @@ func (s *UtxoSweeper) mempoolLookup(op wire.OutPoint) fn.Option[wire.MsgTx] {
// scheduling sweeping for it. // scheduling sweeping for it.
func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) { func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) {
outpoint := *input.input.OutPoint() outpoint := *input.input.OutPoint()
pi, pending := s.pendingInputs[outpoint] pi, pending := s.inputs[outpoint]
if pending { if pending {
log.Debugf("Already has pending input %v received", outpoint) log.Debugf("Already has pending input %v received", outpoint)
@ -1237,9 +1237,8 @@ func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) {
rbf: rbfInfo, rbf: rbfInfo,
} }
s.pendingInputs[outpoint] = pi s.inputs[outpoint] = pi
log.Tracef("input %v, state=%v, added to pendingInputs", outpoint, log.Tracef("input %v, state=%v, added to inputs", outpoint, pi.state)
pi.state)
// Start watching for spend of this input, either by us or the remote // Start watching for spend of this input, either by us or the remote
// party. // party.
@ -1416,7 +1415,7 @@ func (s *UtxoSweeper) markInputsSwept(tx *wire.MsgTx, isOurTx bool) {
// unknown if we canceled the registration, deleted from // unknown if we canceled the registration, deleted from
// pendingInputs but the ntfn was in-flight already. Or this // pendingInputs but the ntfn was in-flight already. Or this
// could be not one of our inputs. // could be not one of our inputs.
input, ok := s.pendingInputs[outpoint] input, ok := s.inputs[outpoint]
if !ok { if !ok {
// It's very likely that a spending tx contains inputs // It's very likely that a spending tx contains inputs
// that we don't know. // that we don't know.
@ -1487,7 +1486,7 @@ func (s *UtxoSweeper) updateSweeperInputs() pendingInputs {
// locks are needed to access the map. However, it'd be safer if we // locks are needed to access the map. However, it'd be safer if we
// turn this pendingInputs into a SyncMap in case we wanna add // turn this pendingInputs into a SyncMap in case we wanna add
// concurrent access to the map in the future. // concurrent access to the map in the future.
for op, input := range s.pendingInputs { for op, input := range s.inputs {
// If the input has reached a final state, that it's either // If the input has reached a final state, that it's either
// been swept, or failed, or excluded, we will remove it from // been swept, or failed, or excluded, we will remove it from
// our sweeper. // our sweeper.
@ -1495,7 +1494,7 @@ func (s *UtxoSweeper) updateSweeperInputs() pendingInputs {
log.Debugf("Removing input(State=%v) %v from sweeper", log.Debugf("Removing input(State=%v) %v from sweeper",
input.state, op) input.state, op)
delete(s.pendingInputs, op) delete(s.inputs, op)
continue continue
} }

View file

@ -2146,7 +2146,7 @@ func TestMarkInputsPendingPublish(t *testing.T) {
inputInit.On("OutPoint").Return(&wire.OutPoint{Index: 1}) inputInit.On("OutPoint").Return(&wire.OutPoint{Index: 1})
s.pendingInputs[*inputInit.OutPoint()] = &pendingInput{ s.inputs[*inputInit.OutPoint()] = &pendingInput{
state: Init, state: Init,
} }
@ -2156,7 +2156,7 @@ func TestMarkInputsPendingPublish(t *testing.T) {
inputPendingPublish.On("OutPoint").Return(&wire.OutPoint{Index: 2}) inputPendingPublish.On("OutPoint").Return(&wire.OutPoint{Index: 2})
s.pendingInputs[*inputPendingPublish.OutPoint()] = &pendingInput{ s.inputs[*inputPendingPublish.OutPoint()] = &pendingInput{
state: PendingPublish, state: PendingPublish,
} }
@ -2166,7 +2166,7 @@ func TestMarkInputsPendingPublish(t *testing.T) {
inputTerminated.On("OutPoint").Return(&wire.OutPoint{Index: 3}) inputTerminated.On("OutPoint").Return(&wire.OutPoint{Index: 3})
s.pendingInputs[*inputTerminated.OutPoint()] = &pendingInput{ s.inputs[*inputTerminated.OutPoint()] = &pendingInput{
state: Excluded, state: Excluded,
} }
@ -2179,19 +2179,19 @@ func TestMarkInputsPendingPublish(t *testing.T) {
s.markInputsPendingPublish(set) s.markInputsPendingPublish(set)
// We expect unchanged number of pending inputs. // We expect unchanged number of pending inputs.
require.Len(s.pendingInputs, 3) require.Len(s.inputs, 3)
// We expect the init input's state to become pending publish. // We expect the init input's state to become pending publish.
require.Equal(PendingPublish, require.Equal(PendingPublish,
s.pendingInputs[*inputInit.OutPoint()].state) s.inputs[*inputInit.OutPoint()].state)
// We expect the pending-publish to stay unchanged. // We expect the pending-publish to stay unchanged.
require.Equal(PendingPublish, require.Equal(PendingPublish,
s.pendingInputs[*inputPendingPublish.OutPoint()].state) s.inputs[*inputPendingPublish.OutPoint()].state)
// We expect the terminated to stay unchanged. // We expect the terminated to stay unchanged.
require.Equal(Excluded, require.Equal(Excluded,
s.pendingInputs[*inputTerminated.OutPoint()].state) s.inputs[*inputTerminated.OutPoint()].state)
} }
// TestMarkInputsPublished checks that given a list of inputs with different // TestMarkInputsPublished checks that given a list of inputs with different
@ -2216,7 +2216,7 @@ func TestMarkInputsPublished(t *testing.T) {
// Create three testing inputs. // Create three testing inputs.
// //
// inputNotExist specifies an input that's not found in the sweeper's // inputNotExist specifies an input that's not found in the sweeper's
// `pendingInputs` map. // `inputs` map.
inputNotExist := &wire.TxIn{ inputNotExist := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 1}, PreviousOutPoint: wire.OutPoint{Index: 1},
} }
@ -2227,7 +2227,7 @@ func TestMarkInputsPublished(t *testing.T) {
inputInit := &wire.TxIn{ inputInit := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 2}, PreviousOutPoint: wire.OutPoint{Index: 2},
} }
s.pendingInputs[inputInit.PreviousOutPoint] = &pendingInput{ s.inputs[inputInit.PreviousOutPoint] = &pendingInput{
state: Init, state: Init,
} }
@ -2235,7 +2235,7 @@ func TestMarkInputsPublished(t *testing.T) {
inputPendingPublish := &wire.TxIn{ inputPendingPublish := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 3}, PreviousOutPoint: wire.OutPoint{Index: 3},
} }
s.pendingInputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{ s.inputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{
state: PendingPublish, state: PendingPublish,
} }
@ -2263,15 +2263,15 @@ func TestMarkInputsPublished(t *testing.T) {
require.NoError(err) require.NoError(err)
// We expect unchanged number of pending inputs. // We expect unchanged number of pending inputs.
require.Len(s.pendingInputs, 2) require.Len(s.inputs, 2)
// We expect the init input's state to stay unchanged. // We expect the init input's state to stay unchanged.
require.Equal(Init, require.Equal(Init,
s.pendingInputs[inputInit.PreviousOutPoint].state) s.inputs[inputInit.PreviousOutPoint].state)
// We expect the pending-publish input's is now marked as published. // We expect the pending-publish input's is now marked as published.
require.Equal(Published, require.Equal(Published,
s.pendingInputs[inputPendingPublish.PreviousOutPoint].state) s.inputs[inputPendingPublish.PreviousOutPoint].state)
// Assert mocked statements are executed as expected. // Assert mocked statements are executed as expected.
mockStore.AssertExpectations(t) mockStore.AssertExpectations(t)
@ -2296,7 +2296,7 @@ func TestMarkInputsPublishFailed(t *testing.T) {
// Create three testing inputs. // Create three testing inputs.
// //
// inputNotExist specifies an input that's not found in the sweeper's // inputNotExist specifies an input that's not found in the sweeper's
// `pendingInputs` map. // `inputs` map.
inputNotExist := &wire.TxIn{ inputNotExist := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 1}, PreviousOutPoint: wire.OutPoint{Index: 1},
} }
@ -2307,7 +2307,7 @@ func TestMarkInputsPublishFailed(t *testing.T) {
inputInit := &wire.TxIn{ inputInit := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 2}, PreviousOutPoint: wire.OutPoint{Index: 2},
} }
s.pendingInputs[inputInit.PreviousOutPoint] = &pendingInput{ s.inputs[inputInit.PreviousOutPoint] = &pendingInput{
state: Init, state: Init,
} }
@ -2315,7 +2315,7 @@ func TestMarkInputsPublishFailed(t *testing.T) {
inputPendingPublish := &wire.TxIn{ inputPendingPublish := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 3}, PreviousOutPoint: wire.OutPoint{Index: 3},
} }
s.pendingInputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{ s.inputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{
state: PendingPublish, state: PendingPublish,
} }
@ -2329,16 +2329,16 @@ func TestMarkInputsPublishFailed(t *testing.T) {
}) })
// We expect unchanged number of pending inputs. // We expect unchanged number of pending inputs.
require.Len(s.pendingInputs, 2) require.Len(s.inputs, 2)
// We expect the init input's state to stay unchanged. // We expect the init input's state to stay unchanged.
require.Equal(Init, require.Equal(Init,
s.pendingInputs[inputInit.PreviousOutPoint].state) s.inputs[inputInit.PreviousOutPoint].state)
// We expect the pending-publish input's is now marked as publish // We expect the pending-publish input's is now marked as publish
// failed. // failed.
require.Equal(PublishFailed, require.Equal(PublishFailed,
s.pendingInputs[inputPendingPublish.PreviousOutPoint].state) s.inputs[inputPendingPublish.PreviousOutPoint].state)
// Assert mocked statements are executed as expected. // Assert mocked statements are executed as expected.
mockStore.AssertExpectations(t) mockStore.AssertExpectations(t)
@ -2364,7 +2364,7 @@ func TestMarkInputsSwept(t *testing.T) {
// Create three testing inputs. // Create three testing inputs.
// //
// inputNotExist specifies an input that's not found in the sweeper's // inputNotExist specifies an input that's not found in the sweeper's
// `pendingInputs` map. // `inputs` map.
inputNotExist := &wire.TxIn{ inputNotExist := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 1}, PreviousOutPoint: wire.OutPoint{Index: 1},
} }
@ -2373,7 +2373,7 @@ func TestMarkInputsSwept(t *testing.T) {
inputInit := &wire.TxIn{ inputInit := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 2}, PreviousOutPoint: wire.OutPoint{Index: 2},
} }
s.pendingInputs[inputInit.PreviousOutPoint] = &pendingInput{ s.inputs[inputInit.PreviousOutPoint] = &pendingInput{
state: Init, state: Init,
Input: mockInput, Input: mockInput,
} }
@ -2382,7 +2382,7 @@ func TestMarkInputsSwept(t *testing.T) {
inputPendingPublish := &wire.TxIn{ inputPendingPublish := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 3}, PreviousOutPoint: wire.OutPoint{Index: 3},
} }
s.pendingInputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{ s.inputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{
state: PendingPublish, state: PendingPublish,
Input: mockInput, Input: mockInput,
} }
@ -2391,7 +2391,7 @@ func TestMarkInputsSwept(t *testing.T) {
inputTerminated := &wire.TxIn{ inputTerminated := &wire.TxIn{
PreviousOutPoint: wire.OutPoint{Index: 4}, PreviousOutPoint: wire.OutPoint{Index: 4},
} }
s.pendingInputs[inputTerminated.PreviousOutPoint] = &pendingInput{ s.inputs[inputTerminated.PreviousOutPoint] = &pendingInput{
state: Excluded, state: Excluded,
Input: mockInput, Input: mockInput,
} }
@ -2408,19 +2408,19 @@ func TestMarkInputsSwept(t *testing.T) {
s.markInputsSwept(tx, true) s.markInputsSwept(tx, true)
// We expect unchanged number of pending inputs. // We expect unchanged number of pending inputs.
require.Len(s.pendingInputs, 3) require.Len(s.inputs, 3)
// We expect the init input's state to become swept. // We expect the init input's state to become swept.
require.Equal(Swept, require.Equal(Swept,
s.pendingInputs[inputInit.PreviousOutPoint].state) s.inputs[inputInit.PreviousOutPoint].state)
// We expect the pending-publish becomes swept. // We expect the pending-publish becomes swept.
require.Equal(Swept, require.Equal(Swept,
s.pendingInputs[inputPendingPublish.PreviousOutPoint].state) s.inputs[inputPendingPublish.PreviousOutPoint].state)
// We expect the terminated to stay unchanged. // We expect the terminated to stay unchanged.
require.Equal(Excluded, require.Equal(Excluded,
s.pendingInputs[inputTerminated.PreviousOutPoint].state) s.inputs[inputTerminated.PreviousOutPoint].state)
} }
// TestMempoolLookup checks that the method `mempoolLookup` works as expected. // TestMempoolLookup checks that the method `mempoolLookup` works as expected.
@ -2489,7 +2489,7 @@ func TestUpdateSweeperInputs(t *testing.T) {
// Add the inputs to the sweeper. After the update, we should see the // Add the inputs to the sweeper. After the update, we should see the
// terminated inputs being removed. // terminated inputs being removed.
s.pendingInputs = map[wire.OutPoint]*pendingInput{ s.inputs = map[wire.OutPoint]*pendingInput{
{Index: 0}: input0, {Index: 0}: input0,
{Index: 1}: input1, {Index: 1}: input1,
{Index: 2}: input2, {Index: 2}: input2,
@ -2522,7 +2522,7 @@ func TestUpdateSweeperInputs(t *testing.T) {
require.Equal(expectedReturn, inputs) require.Equal(expectedReturn, inputs)
// Assert the sweeper inputs are as expected. // Assert the sweeper inputs are as expected.
require.Equal(expectedInputs, s.pendingInputs) require.Equal(expectedInputs, s.inputs)
} }
// TestDecideStateAndRBFInfo checks that the expected state and RBFInfo are // TestDecideStateAndRBFInfo checks that the expected state and RBFInfo are
@ -2729,7 +2729,7 @@ func TestHandleBumpEventTxFailed(t *testing.T) {
defer input3.AssertExpectations(t) defer input3.AssertExpectations(t)
// Construct the initial state for the sweeper. // Construct the initial state for the sweeper.
s.pendingInputs = pendingInputs{ s.inputs = pendingInputs{
op1: &pendingInput{Input: input1, state: PendingPublish}, op1: &pendingInput{Input: input1, state: PendingPublish},
op2: &pendingInput{Input: input2, state: PendingPublish}, op2: &pendingInput{Input: input2, state: PendingPublish},
op3: &pendingInput{Input: input3, state: PendingPublish}, op3: &pendingInput{Input: input3, state: PendingPublish},
@ -2756,14 +2756,14 @@ func TestHandleBumpEventTxFailed(t *testing.T) {
require.ErrorIs(t, err, errDummy) require.ErrorIs(t, err, errDummy)
// Assert the states of the first two inputs are updated. // Assert the states of the first two inputs are updated.
require.Equal(t, PublishFailed, s.pendingInputs[op1].state) require.Equal(t, PublishFailed, s.inputs[op1].state)
require.Equal(t, PublishFailed, s.pendingInputs[op2].state) require.Equal(t, PublishFailed, s.inputs[op2].state)
// Assert the state of the third input is not updated. // Assert the state of the third input is not updated.
require.Equal(t, PendingPublish, s.pendingInputs[op3].state) require.Equal(t, PendingPublish, s.inputs[op3].state)
// Assert the non-existing input is not added to the pending inputs. // Assert the non-existing input is not added to the pending inputs.
require.NotContains(t, s.pendingInputs, opNotExist) require.NotContains(t, s.inputs, opNotExist)
} }
// TestHandleBumpEventTxReplaced checks that the sweeper correctly handles the // TestHandleBumpEventTxReplaced checks that the sweeper correctly handles the
@ -2788,7 +2788,7 @@ func TestHandleBumpEventTxReplaced(t *testing.T) {
defer inp.AssertExpectations(t) defer inp.AssertExpectations(t)
// Construct the initial state for the sweeper. // Construct the initial state for the sweeper.
s.pendingInputs = pendingInputs{ s.inputs = pendingInputs{
op: &pendingInput{Input: inp, state: PendingPublish}, op: &pendingInput{Input: inp, state: PendingPublish},
} }
@ -2853,7 +2853,7 @@ func TestHandleBumpEventTxReplaced(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Assert the state of the input is updated. // Assert the state of the input is updated.
require.Equal(t, Published, s.pendingInputs[op].state) require.Equal(t, Published, s.inputs[op].state)
} }
// TestHandleBumpEventTxPublished checks that the sweeper correctly handles the // TestHandleBumpEventTxPublished checks that the sweeper correctly handles the
@ -2878,7 +2878,7 @@ func TestHandleBumpEventTxPublished(t *testing.T) {
defer inp.AssertExpectations(t) defer inp.AssertExpectations(t)
// Construct the initial state for the sweeper. // Construct the initial state for the sweeper.
s.pendingInputs = pendingInputs{ s.inputs = pendingInputs{
op: &pendingInput{Input: inp, state: PendingPublish}, op: &pendingInput{Input: inp, state: PendingPublish},
} }
@ -2907,7 +2907,7 @@ func TestHandleBumpEventTxPublished(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Assert the state of the input is updated. // Assert the state of the input is updated.
require.Equal(t, Published, s.pendingInputs[op].state) require.Equal(t, Published, s.inputs[op].state)
} }
// TestMonitorFeeBumpResult checks that the fee bump monitor loop correctly // TestMonitorFeeBumpResult checks that the fee bump monitor loop correctly
@ -2930,7 +2930,7 @@ func TestMonitorFeeBumpResult(t *testing.T) {
defer inp.AssertExpectations(t) defer inp.AssertExpectations(t)
// Construct the initial state for the sweeper. // Construct the initial state for the sweeper.
s.pendingInputs = pendingInputs{ s.inputs = pendingInputs{
op: &pendingInput{Input: inp, state: PendingPublish}, op: &pendingInput{Input: inp, state: PendingPublish},
} }