Skip to content

Commit 1319da0

Browse files
committed
[release-v1.8] vsp: Recalculate live/expiry height
Previously the live & expiry heights were only being set once upon feePayment initialization, which meant that an unmined ticket added to the VSP client would have heights set to zero forever. With this change, if either of the values are found to be zero, we check if the ticket has been mined yet and the heights are recalculated to their correct values if so. Backport of 8722867
1 parent 7c551ce commit 1319da0

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

internal/vsp/feepayment.go

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,49 @@ func parseTicket(ticket *wire.MsgTx, params *chaincfg.Params) (
134134
return
135135
}
136136

137+
// calcHeights checks if the ticket has been mined, and if so, sets the live
138+
// height and expiry height fields. Should be called with mutex already held.
139+
func (fp *feePayment) calcHeights() {
140+
_, minedHeight, err := fp.client.wallet.TxBlock(fp.ctx, &fp.ticketHash)
141+
if err != nil {
142+
// This is not expected to ever error, as the ticket has already been
143+
// fetched from the wallet at least one before this point is reached.
144+
log.Errorf("Failed to query block which mines ticket: %v", err)
145+
return
146+
}
147+
148+
if minedHeight < 2 {
149+
return
150+
}
151+
152+
params := fp.client.wallet.ChainParams()
153+
154+
// Note the off-by-one; this is correct. Tickets become live one block after
155+
// the params would indicate.
156+
fp.ticketLive = minedHeight + int32(params.TicketMaturity) + 1
157+
fp.ticketExpires = fp.ticketLive + int32(params.TicketExpiry)
158+
}
159+
160+
// expiryHeight returns the height at which the ticket expires. Returns zero if
161+
// the block is not yet mined. Should be called with mutex already held.
162+
func (fp *feePayment) expiryHeight() int32 {
163+
if fp.ticketExpires == 0 {
164+
fp.calcHeights()
165+
}
166+
167+
return fp.ticketExpires
168+
}
169+
170+
// liveHeight returns the height at which the ticket becomes live. Returns zero
171+
// if the block is not yet mined. Should be called with mutex already held.
172+
func (fp *feePayment) liveHeight() int32 {
173+
if fp.ticketLive == 0 {
174+
fp.calcHeights()
175+
}
176+
177+
return fp.ticketLive
178+
}
179+
137180
func (fp *feePayment) ticketSpent() bool {
138181
ctx := fp.ctx
139182
ticketOut := wire.OutPoint{Hash: fp.ticketHash, Index: 0, Tree: 1}
@@ -147,7 +190,7 @@ func (fp *feePayment) ticketExpired() bool {
147190
_, tipHeight := w.MainChainTip(ctx)
148191

149192
fp.mu.Lock()
150-
expires := fp.ticketExpires
193+
expires := fp.expiryHeight()
151194
fp.mu.Unlock()
152195

153196
return expires > 0 && tipHeight >= expires
@@ -229,20 +272,6 @@ func (c *Client) feePayment(ctx context.Context, ticketHash *chainhash.Hash, pai
229272
return nil
230273
}
231274

232-
_, ticketHeight, err := w.TxBlock(ctx, ticketHash)
233-
if err != nil {
234-
// This is not expected to ever error, as the ticket was fetched
235-
// from the wallet in the above call.
236-
log.Errorf("failed to query block which mines ticket: %v", err)
237-
return nil
238-
}
239-
if ticketHeight >= 2 {
240-
// Note the off-by-one; this is correct. Tickets become live
241-
// one block after the params would indicate.
242-
fp.ticketLive = ticketHeight + int32(params.TicketMaturity) + 1
243-
fp.ticketExpires = fp.ticketLive + int32(params.TicketExpiry)
244-
}
245-
246275
fp.votingAddr, fp.commitmentAddr, err = parseTicket(ticket, params)
247276
if err != nil {
248277
log.Errorf("%v is not a ticket: %v", ticketHash, err)
@@ -324,8 +353,8 @@ func (fp *feePayment) next() time.Duration {
324353
_, tipHeight := w.MainChainTip(fp.ctx)
325354

326355
fp.mu.Lock()
327-
ticketLive := fp.ticketLive
328-
ticketExpires := fp.ticketExpires
356+
ticketLive := fp.liveHeight()
357+
ticketExpires := fp.expiryHeight()
329358
fp.mu.Unlock()
330359

331360
var jitter time.Duration

0 commit comments

Comments
 (0)