cnct: instantiate quit channels inside resolvers

Removes a bug-prone construction that existed previously where the quit
channel was replaced just-in-time.
This commit is contained in:
Joost Jager committed 2019-11-07 13:10:35 +01:00
1 parent 75ecbfd321
commit ff63a680a1
11 files changed
+107 -88

No files matched your search

+2 -3
View File
@@ -440,7 +440,7 @@ func (b *boltArbitratorLog) CommitState(s ArbitratorState) error {
// //
// NOTE: Part of the ContractResolver interface. // NOTE: Part of the ContractResolver interface.
func (b *boltArbitratorLog) FetchUnresolvedContracts() ([]ContractResolver, error) { func (b *boltArbitratorLog) FetchUnresolvedContracts() ([]ContractResolver, error) {
resKit := ResolverKit{ resolverCfg := ResolverConfig{
ChannelArbitratorConfig: b.cfg, ChannelArbitratorConfig: b.cfg,
Checkpoint: b.checkpointContract, Checkpoint: b.checkpointContract,
} }
@@ -516,8 +516,7 @@ func (b *boltArbitratorLog) FetchUnresolvedContracts() ([]ContractResolver, erro
return fmt.Errorf("unknown resolver type: %v", resType) return fmt.Errorf("unknown resolver type: %v", resType)
} }
resKit.quit = make(chan struct{}) res.AttachConfig(resolverCfg)
res.AttachResolverKit(resKit)
contracts = append(contracts, res) contracts = append(contracts, res)
return nil return nil
}) })
+30 -30
View File
@@ -1685,7 +1685,7 @@ func (c *ChannelArbitrator) prepContractResolutions(
// We'll create the resolver kit that we'll be cloning for each // We'll create the resolver kit that we'll be cloning for each
// resolver so they each can do their duty. // resolver so they each can do their duty.
resKit := ResolverKit{ resolverCfg := ResolverConfig{
ChannelArbitratorConfig: c.cfg, ChannelArbitratorConfig: c.cfg,
Checkpoint: func(res ContractResolver) error { Checkpoint: func(res ContractResolver) error {
return c.log.InsertUnresolvedContracts(res) return c.log.InsertUnresolvedContracts(res)
@@ -1733,13 +1733,13 @@ func (c *ChannelArbitrator) prepContractResolutions(
continue continue
} }
resKit.quit = make(chan struct{}) resKit := newContractResolverKit(resolverCfg)
resolver := &htlcSuccessResolver{ resolver := &htlcSuccessResolver{
htlcResolution: resolution, htlcResolution: resolution,
broadcastHeight: height, broadcastHeight: height,
payHash: htlc.RHash, payHash: htlc.RHash,
htlcAmt: htlc.Amt, htlcAmt: htlc.Amt,
ResolverKit: resKit, contractResolverKit: *resKit,
} }
htlcResolvers = append(htlcResolvers, resolver) htlcResolvers = append(htlcResolvers, resolver)
} }
@@ -1761,13 +1761,13 @@ func (c *ChannelArbitrator) prepContractResolutions(
continue continue
} }
resKit.quit = make(chan struct{}) resKit := newContractResolverKit(resolverCfg)
resolver := &htlcTimeoutResolver{ resolver := &htlcTimeoutResolver{
htlcResolution: resolution, htlcResolution: resolution,
broadcastHeight: height, broadcastHeight: height,
htlcIndex: htlc.HtlcIndex, htlcIndex: htlc.HtlcIndex,
htlcAmt: htlc.Amt, htlcAmt: htlc.Amt,
ResolverKit: resKit, contractResolverKit: *resKit,
} }
htlcResolvers = append(htlcResolvers, resolver) htlcResolvers = append(htlcResolvers, resolver)
} }
@@ -1798,16 +1798,16 @@ func (c *ChannelArbitrator) prepContractResolutions(
ChanID: c.cfg.ShortChanID, ChanID: c.cfg.ShortChanID,
} }
resKit.quit = make(chan struct{}) resKit := newContractResolverKit(resolverCfg)
resolver := &htlcIncomingContestResolver{ resolver := &htlcIncomingContestResolver{
htlcExpiry: htlc.RefundTimeout, htlcExpiry: htlc.RefundTimeout,
circuitKey: circuitKey, circuitKey: circuitKey,
htlcSuccessResolver: htlcSuccessResolver{ htlcSuccessResolver: htlcSuccessResolver{
htlcResolution: resolution, htlcResolution: resolution,
broadcastHeight: height, broadcastHeight: height,
payHash: htlc.RHash, payHash: htlc.RHash,
htlcAmt: htlc.Amt, htlcAmt: htlc.Amt,
ResolverKit: resKit, contractResolverKit: *resKit,
}, },
} }
htlcResolvers = append(htlcResolvers, resolver) htlcResolvers = append(htlcResolvers, resolver)
@@ -1831,14 +1831,14 @@ func (c *ChannelArbitrator) prepContractResolutions(
continue continue
} }
resKit.quit = make(chan struct{}) resKit := newContractResolverKit(resolverCfg)
resolver := &htlcOutgoingContestResolver{ resolver := &htlcOutgoingContestResolver{
htlcTimeoutResolver: htlcTimeoutResolver{ htlcTimeoutResolver: htlcTimeoutResolver{
htlcResolution: resolution, htlcResolution: resolution,
broadcastHeight: height, broadcastHeight: height,
htlcIndex: htlc.HtlcIndex, htlcIndex: htlc.HtlcIndex,
htlcAmt: htlc.Amt, htlcAmt: htlc.Amt,
ResolverKit: resKit, contractResolverKit: *resKit,
}, },
} }
htlcResolvers = append(htlcResolvers, resolver) htlcResolvers = append(htlcResolvers, resolver)
@@ -1850,12 +1850,12 @@ func (c *ChannelArbitrator) prepContractResolutions(
// a resolver to sweep our commitment output (but only if it wasn't // a resolver to sweep our commitment output (but only if it wasn't
// trimmed). // trimmed).
if contractResolutions.CommitResolution != nil { if contractResolutions.CommitResolution != nil {
resKit.quit = make(chan struct{}) resKit := newContractResolverKit(resolverCfg)
resolver := &commitSweepResolver{ resolver := &commitSweepResolver{
commitResolution: *contractResolutions.CommitResolution, commitResolution: *contractResolutions.CommitResolution,
broadcastHeight: height, broadcastHeight: height,
chanPoint: c.cfg.ChanPoint, chanPoint: c.cfg.ChanPoint,
ResolverKit: resKit, contractResolverKit: *resKit,
} }
htlcResolvers = append(htlcResolvers, resolver) htlcResolvers = append(htlcResolvers, resolver)
+5 -5
View File
@@ -36,7 +36,7 @@ type commitSweepResolver struct {
// chanPoint is the channel point of the original contract. // chanPoint is the channel point of the original contract.
chanPoint wire.OutPoint chanPoint wire.OutPoint
ResolverKit contractResolverKit
} }
// ResolverKey returns an identifier which should be globally unique for this // ResolverKey returns an identifier which should be globally unique for this
@@ -293,13 +293,13 @@ func (c *commitSweepResolver) Decode(r io.Reader) error {
return nil return nil
} }
// AttachResolverKit should be called once a resolved is successfully decoded // AttachConfig should be called once a resolved is successfully decoded from
// from its stored format. This struct delivers a generic tool kit that // its stored format. This struct delivers the configuration items that
// resolvers need to complete their duty. // resolvers need to complete their duty.
// //
// NOTE: Part of the ContractResolver interface. // NOTE: Part of the ContractResolver interface.
func (c *commitSweepResolver) AttachResolverKit(r ResolverKit) { func (c *commitSweepResolver) AttachConfig(r ResolverConfig) {
c.ResolverKit = r c.contractResolverKit = *newContractResolverKit(r)
} }
// A compile time assertion to ensure commitSweepResolver meets the // A compile time assertion to ensure commitSweepResolver meets the
+22 -8
View File
@@ -46,10 +46,10 @@ type ContractResolver interface {
// passed Writer. // passed Writer.
Encode(w io.Writer) error Encode(w io.Writer) error
// AttachResolverKit should be called once a resolved is successfully // AttachConfig should be called once a resolved is successfully decoded
// decoded from its stored format. This struct delivers a generic tool // from its stored format. This struct delivers the configuration items
// kit that resolvers need to complete their duty. // that resolvers need to complete their duty.
AttachResolverKit(ResolverKit) AttachConfig(ResolverConfig)
// Stop signals the resolver to cancel any current resolution // Stop signals the resolver to cancel any current resolution
// processes, and suspend. // processes, and suspend.
@@ -64,10 +64,9 @@ type reportingContractResolver interface {
report() *ContractReport report() *ContractReport
} }
// ResolverKit is meant to be used as a mix-in struct to be embedded within a // ResolverConfig contains the externally supplied configuration items that are
// given ContractResolver implementation. It contains all the items that a // required by a ContractResolver implementation.
// resolver requires to carry out its duties. type ResolverConfig struct {
type ResolverKit struct {
// ChannelArbitratorConfig contains all the interfaces and closures // ChannelArbitratorConfig contains all the interfaces and closures
// required for the resolver to interact with outside sub-systems. // required for the resolver to interact with outside sub-systems.
ChannelArbitratorConfig ChannelArbitratorConfig
@@ -76,10 +75,25 @@ type ResolverKit struct {
// should write the state of the resolver to persistent storage, and // should write the state of the resolver to persistent storage, and
// return a non-nil error upon success. // return a non-nil error upon success.
Checkpoint func(ContractResolver) error Checkpoint func(ContractResolver) error
}
// contractResolverKit is meant to be used as a mix-in struct to be embedded within a
// given ContractResolver implementation. It contains all the common items that
// a resolver requires to carry out its duties.
type contractResolverKit struct {
ResolverConfig
quit chan struct{} quit chan struct{}
} }
// newContractResolverKit instantiates the mix-in struct.
func newContractResolverKit(cfg ResolverConfig) *contractResolverKit {
return &contractResolverKit{
ResolverConfig: cfg,
quit: make(chan struct{}),
}
}
var ( var (
// errResolverShuttingDown is returned when the resolver stops // errResolverShuttingDown is returned when the resolver stops
// progressing because it received the quit signal. // progressing because it received the quit signal.
@@ -310,13 +310,13 @@ func (h *htlcIncomingContestResolver) Decode(r io.Reader) error {
return h.htlcSuccessResolver.Decode(r) return h.htlcSuccessResolver.Decode(r)
} }
// AttachResolverKit should be called once a resolved is successfully decoded // AttachConfig should be called once a resolved is successfully decoded from
// from its stored format. This struct delivers a generic tool kit that // its stored format. This struct delivers the configuration items that
// resolvers need to complete their duty. // resolvers need to complete their duty.
// //
// NOTE: Part of the ContractResolver interface. // NOTE: Part of the ContractResolver interface.
func (h *htlcIncomingContestResolver) AttachResolverKit(r ResolverKit) { func (h *htlcIncomingContestResolver) AttachConfig(r ResolverConfig) {
h.ResolverKit = r h.htlcSuccessResolver.AttachConfig(r)
} }
// A compile time assertion to ensure htlcIncomingContestResolver meets the // A compile time assertion to ensure htlcIncomingContestResolver meets the
+10 -9
View File
@@ -199,17 +199,18 @@ func newIncomingResolverTestContext(t *testing.T) *incomingResolverTestContext {
}, },
} }
cfg := ResolverConfig{
ChannelArbitratorConfig: chainCfg,
Checkpoint: func(_ ContractResolver) error {
checkPointChan <- struct{}{}
return nil
},
}
resolver := &htlcIncomingContestResolver{ resolver := &htlcIncomingContestResolver{
htlcSuccessResolver: htlcSuccessResolver{ htlcSuccessResolver: htlcSuccessResolver{
ResolverKit: ResolverKit{ contractResolverKit: *newContractResolverKit(cfg),
ChannelArbitratorConfig: chainCfg, htlcResolution: lnwallet.IncomingHtlcResolution{},
Checkpoint: func(_ ContractResolver) error { payHash: testResHash,
checkPointChan <- struct{}{}
return nil
},
},
htlcResolution: lnwallet.IncomingHtlcResolution{},
payHash: testResHash,
}, },
htlcExpiry: testHtlcExpiry, htlcExpiry: testHtlcExpiry,
} }
@@ -189,13 +189,13 @@ func (h *htlcOutgoingContestResolver) Decode(r io.Reader) error {
return h.htlcTimeoutResolver.Decode(r) return h.htlcTimeoutResolver.Decode(r)
} }
// AttachResolverKit should be called once a resolved is successfully decoded // AttachConfig should be called once a resolved is successfully decoded from
// from its stored format. This struct delivers a generic tool kit that // its stored format. This struct delivers the configuration items that
// resolvers need to complete their duty. // resolvers need to complete their duty.
// //
// NOTE: Part of the ContractResolver interface. // NOTE: Part of the ContractResolver interface.
func (h *htlcOutgoingContestResolver) AttachResolverKit(r ResolverKit) { func (h *htlcOutgoingContestResolver) AttachConfig(r ResolverConfig) {
h.ResolverKit = r h.htlcTimeoutResolver.AttachConfig(r)
} }
// A compile time assertion to ensure htlcOutgoingContestResolver meets the // A compile time assertion to ensure htlcOutgoingContestResolver meets the
@@ -122,16 +122,18 @@ func newOutgoingResolverTestContext(t *testing.T) *outgoingResolverTestContext {
}, },
} }
cfg := ResolverConfig{
ChannelArbitratorConfig: chainCfg,
Checkpoint: func(_ ContractResolver) error {
checkPointChan <- struct{}{}
return nil
},
}
resolver := &htlcOutgoingContestResolver{ resolver := &htlcOutgoingContestResolver{
htlcTimeoutResolver: htlcTimeoutResolver{ htlcTimeoutResolver: htlcTimeoutResolver{
ResolverKit: ResolverKit{ contractResolverKit: *newContractResolverKit(cfg),
ChannelArbitratorConfig: chainCfg, htlcResolution: outgoingRes,
Checkpoint: func(_ ContractResolver) error {
checkPointChan <- struct{}{}
return nil
},
},
htlcResolution: outgoingRes,
}, },
} }
+5 -5
View File
@@ -52,7 +52,7 @@ type htlcSuccessResolver struct {
// account any fees that may have to be paid if it goes on chain. // account any fees that may have to be paid if it goes on chain.
htlcAmt lnwire.MilliSatoshi htlcAmt lnwire.MilliSatoshi
ResolverKit contractResolverKit
} }
// ResolverKey returns an identifier which should be globally unique for this // ResolverKey returns an identifier which should be globally unique for this
@@ -318,13 +318,13 @@ func (h *htlcSuccessResolver) Decode(r io.Reader) error {
return nil return nil
} }
// AttachResolverKit should be called once a resolved is successfully decoded // AttachConfig should be called once a resolved is successfully decoded from
// from its stored format. This struct delivers a generic tool kit that // its stored format. This struct delivers the configuration items that
// resolvers need to complete their duty. // resolvers need to complete their duty.
// //
// NOTE: Part of the ContractResolver interface. // NOTE: Part of the ContractResolver interface.
func (h *htlcSuccessResolver) AttachResolverKit(r ResolverKit) { func (h *htlcSuccessResolver) AttachConfig(r ResolverConfig) {
h.ResolverKit = r h.contractResolverKit = *newContractResolverKit(r)
} }
// A compile time assertion to ensure htlcSuccessResolver meets the // A compile time assertion to ensure htlcSuccessResolver meets the
+5 -5
View File
@@ -48,7 +48,7 @@ type htlcTimeoutResolver struct {
// account any fees that may have to be paid if it goes on chain. // account any fees that may have to be paid if it goes on chain.
htlcAmt lnwire.MilliSatoshi htlcAmt lnwire.MilliSatoshi
ResolverKit contractResolverKit
} }
// ResolverKey returns an identifier which should be globally unique for this // ResolverKey returns an identifier which should be globally unique for this
@@ -436,13 +436,13 @@ func (h *htlcTimeoutResolver) Decode(r io.Reader) error {
return nil return nil
} }
// AttachResolverKit should be called once a resolved is successfully decoded // AttachConfig should be called once a resolved is successfully decoded from
// from its stored format. This struct delivers a generic tool kit that // its stored format. This struct delivers the configuration items that
// resolvers need to complete their duty. // resolvers need to complete their duty.
// //
// NOTE: Part of the ContractResolver interface. // NOTE: Part of the ContractResolver interface.
func (h *htlcTimeoutResolver) AttachResolverKit(r ResolverKit) { func (h *htlcTimeoutResolver) AttachConfig(r ResolverConfig) {
h.ResolverKit = r h.contractResolverKit = *newContractResolverKit(r)
} }
// A compile time assertion to ensure htlcTimeoutResolver meets the // A compile time assertion to ensure htlcTimeoutResolver meets the
+10 -7
View File
@@ -237,15 +237,18 @@ func TestHtlcTimeoutResolver(t *testing.T) {
}, },
} }
resolver := &htlcTimeoutResolver{ cfg := ResolverConfig{
ResolverKit: ResolverKit{ ChannelArbitratorConfig: chainCfg,
ChannelArbitratorConfig: chainCfg, Checkpoint: func(_ ContractResolver) error {
Checkpoint: func(_ ContractResolver) error { checkPointChan <- struct{}{}
checkPointChan <- struct{}{} return nil
return nil
},
}, },
} }
resolver := &htlcTimeoutResolver{
contractResolverKit: *newContractResolverKit(
cfg,
),
}
resolver.htlcResolution.SweepSignDesc = *fakeSignDesc resolver.htlcResolution.SweepSignDesc = *fakeSignDesc
// If the test case needs the remote commitment to be // If the test case needs the remote commitment to be