Skip to content

Commit 3b206f8

Browse files
author
Jeff Yanta
committed
Add nonce and nonce pool method tracing
1 parent 1f9a7b4 commit 3b206f8

File tree

5 files changed

+71
-44
lines changed

5 files changed

+71
-44
lines changed

pkg/code/async/sequencer/worker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ func (p *service) handlePending(ctx context.Context, record *fulfillment.Record)
228228
return err
229229
}
230230
defer func() {
231-
selectedNonce.ReleaseIfNotReserved()
231+
selectedNonce.ReleaseIfNotReserved(ctx)
232232
}()
233233

234234
err = p.data.ExecuteInTx(ctx, sql.LevelDefault, func(ctx context.Context) error {

pkg/code/server/transaction/airdrop.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func (s *transactionServer) airdrop(ctx context.Context, intentId string, owner
301301
return nil, err
302302
}
303303
defer func() {
304-
selectedNonce.ReleaseIfNotReserved()
304+
selectedNonce.ReleaseIfNotReserved(ctx)
305305
}()
306306

307307
vixnHash := cvm.GetCompactTransferMessage(&cvm.GetCompactTransferMessageArgs{

pkg/code/server/transaction/intent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ func (s *transactionServer) SubmitIntent(streamer transactionpb.Transaction_Subm
381381
// it's safe to put it back in the available pool. The client will have
382382
// caused a failed RPC call, and we want to avoid malicious or erroneous
383383
// clients from consuming our nonce pool!
384-
selectedNonce.ReleaseIfNotReserved()
384+
selectedNonce.ReleaseIfNotReserved(ctx)
385385
}()
386386
nonceAccount = selectedNonce.Account
387387
nonceBlockchash = selectedNonce.Blockhash

pkg/code/transaction/nonce_pool.go

Lines changed: 66 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,16 @@ import (
1616
"github.com/code-payments/code-server/pkg/code/common"
1717
code_data "github.com/code-payments/code-server/pkg/code/data"
1818
"github.com/code-payments/code-server/pkg/code/data/nonce"
19+
"github.com/code-payments/code-server/pkg/metrics"
1920
"github.com/code-payments/code-server/pkg/pointer"
2021
"github.com/code-payments/code-server/pkg/solana"
2122
)
2223

24+
const (
25+
nonceMetricsStructName = "transaction.Nonce"
26+
localNoncePoolMetricsStructName = "transaction.LocalNoncePool"
27+
)
28+
2329
var (
2430
ErrNoAvailableNonces = errors.New("no available nonces")
2531
ErrNoncePoolClosed = errors.New("nonce pool is closed")
@@ -165,33 +171,43 @@ type Nonce struct {
165171

166172
// MarkReservedWithSignature marks the nonce as reserved with a signature
167173
func (n *Nonce) MarkReservedWithSignature(ctx context.Context, sig string) error {
168-
if len(sig) == 0 {
169-
return errors.New("signature is empty")
170-
}
174+
tracer := metrics.TraceMethodCall(ctx, nonceMetricsStructName, "MarkReservedWithSignature")
175+
defer tracer.End()
171176

172-
if n.record.Signature == sig {
173-
return nil
174-
}
177+
err := func() error {
178+
if len(sig) == 0 {
179+
return errors.New("signature is empty")
180+
}
175181

176-
if n.record.State == nonce.StateReserved || len(n.record.Signature) != 0 {
177-
return errors.New("nonce already reserved with a different signature")
178-
}
182+
if n.record.Signature == sig {
183+
return nil
184+
}
179185

180-
if !n.record.CanReserveWithSignature() {
181-
return errors.New("nonce is not in a valid state to reserve with signature")
182-
}
186+
if n.record.State == nonce.StateReserved || len(n.record.Signature) != 0 {
187+
return errors.New("nonce already reserved with a different signature")
188+
}
183189

184-
n.record.State = nonce.StateReserved
185-
n.record.Signature = sig
186-
n.record.ClaimNodeID = nil
187-
n.record.ClaimExpiresAt = nil
188-
return n.pool.data.SaveNonce(ctx, n.record)
190+
if !n.record.CanReserveWithSignature() {
191+
return errors.New("nonce is not in a valid state to reserve with signature")
192+
}
193+
194+
n.record.State = nonce.StateReserved
195+
n.record.Signature = sig
196+
n.record.ClaimNodeID = nil
197+
n.record.ClaimExpiresAt = nil
198+
return n.pool.data.SaveNonce(ctx, n.record)
199+
}()
200+
tracer.OnError(err)
201+
return err
189202
}
190203

191204
// ReleaseIfNotReserved releases the nonce back to the pool if
192205
// the nonce has not yet been reserved (or more specifically, is
193206
// still owned by the pool).
194-
func (n *Nonce) ReleaseIfNotReserved() {
207+
func (n *Nonce) ReleaseIfNotReserved(ctx context.Context) {
208+
tracer := metrics.TraceMethodCall(ctx, nonceMetricsStructName, "ReleaseIfNotReserved")
209+
defer tracer.End()
210+
195211
if n.record.State != nonce.StateClaimed {
196212
return
197213
}
@@ -295,32 +311,39 @@ func NewLocalNoncePool(
295311
}
296312

297313
func (np *LocalNoncePool) GetNonce(ctx context.Context) (*Nonce, error) {
298-
var n *Nonce
314+
tracer := metrics.TraceMethodCall(ctx, localNoncePoolMetricsStructName, "GetNonce")
315+
defer tracer.End()
299316

300-
np.mu.Lock()
301-
if np.isClosed {
302-
np.mu.Unlock()
303-
return nil, ErrNoncePoolClosed
304-
}
317+
n, err := func() (*Nonce, error) {
318+
var n *Nonce
305319

306-
size := len(np.freeList)
307-
if size > 0 {
308-
n = np.freeList[0]
309-
np.freeList = np.freeList[1:]
310-
}
311-
np.mu.Unlock()
320+
np.mu.Lock()
321+
if np.isClosed {
322+
np.mu.Unlock()
323+
return nil, ErrNoncePoolClosed
324+
}
312325

313-
if size < np.opts.desiredPoolSize/2 {
314-
select {
315-
case np.refreshPoolCh <- struct{}{}:
316-
default:
326+
size := len(np.freeList)
327+
if size > 0 {
328+
n = np.freeList[0]
329+
np.freeList = np.freeList[1:]
317330
}
318-
}
331+
np.mu.Unlock()
319332

320-
if n == nil {
321-
return nil, ErrNoAvailableNonces
322-
}
323-
return n, nil
333+
if size < np.opts.desiredPoolSize/2 {
334+
select {
335+
case np.refreshPoolCh <- struct{}{}:
336+
default:
337+
}
338+
}
339+
340+
if n == nil {
341+
return nil, ErrNoAvailableNonces
342+
}
343+
return n, nil
344+
}()
345+
tracer.OnError(err)
346+
return n, err
324347
}
325348

326349
func (np *LocalNoncePool) Validate(
@@ -346,6 +369,10 @@ func (np *LocalNoncePool) Close() error {
346369
np.mu.Lock()
347370
defer np.mu.Unlock()
348371

372+
if np.isClosed {
373+
return nil
374+
}
375+
349376
np.isClosed = true
350377
np.cancelWorkerCtx()
351378

pkg/code/transaction/nonce_pool_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func testLocalNoncePoolHappyPath(nt *localNoncePoolTest) {
106106
// Releasing back to the pool should allow us to re-use the nonces that
107107
// weren't reserved
108108
for _, v := range observed {
109-
v.ReleaseIfNotReserved()
109+
v.ReleaseIfNotReserved(ctx)
110110
}
111111
clear(observed)
112112

@@ -127,7 +127,7 @@ func testLocalNoncePoolHappyPath(nt *localNoncePoolTest) {
127127
// Releasing back to the pool will allow us to make nonces available to
128128
// claim
129129
for _, v := range observed {
130-
v.ReleaseIfNotReserved()
130+
v.ReleaseIfNotReserved(ctx)
131131
}
132132

133133
require.NoError(nt.t, nt.pool.Close())

0 commit comments

Comments
 (0)