Skip to content

Commit f10fca5

Browse files
author
Jeff Yanta
committed
Setup local nonce pool in sequencer service
1 parent e486ce0 commit f10fca5

File tree

5 files changed

+39
-15
lines changed

5 files changed

+39
-15
lines changed

pkg/code/async/sequencer/fulfillment_handler.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type FulfillmentHandler interface {
4646
// to the blockchain. This is an optimization for the nonce pool. Implementations
4747
// should not modify the provided fulfillment record or selected nonce, but rather
4848
// use relevant fields to make the corresponding transaction.
49-
MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.SelectedNonce) (*solana.Transaction, error)
49+
MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.Nonce) (*solana.Transaction, error)
5050

5151
// OnSuccess is a callback function executed on a finalized transaction.
5252
OnSuccess(ctx context.Context, fulfillmentRecord *fulfillment.Record, txnRecord *transaction.Record) error
@@ -123,7 +123,7 @@ func (h *InitializeLockedTimelockAccountFulfillmentHandler) SupportsOnDemandTran
123123
return true
124124
}
125125

126-
func (h *InitializeLockedTimelockAccountFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.SelectedNonce) (*solana.Transaction, error) {
126+
func (h *InitializeLockedTimelockAccountFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.Nonce) (*solana.Transaction, error) {
127127
if fulfillmentRecord.FulfillmentType != fulfillment.InitializeLockedTimelockAccount {
128128
return nil, errors.New("invalid fulfillment type")
129129
}
@@ -268,7 +268,7 @@ func (h *NoPrivacyTransferWithAuthorityFulfillmentHandler) SupportsOnDemandTrans
268268
return true
269269
}
270270

271-
func (h *NoPrivacyTransferWithAuthorityFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.SelectedNonce) (*solana.Transaction, error) {
271+
func (h *NoPrivacyTransferWithAuthorityFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.Nonce) (*solana.Transaction, error) {
272272
virtualSignatureBytes, err := base58.Decode(*fulfillmentRecord.VirtualSignature)
273273
if err != nil {
274274
return nil, err
@@ -444,7 +444,7 @@ func (h *NoPrivacyWithdrawFulfillmentHandler) SupportsOnDemandTransactions() boo
444444
return true
445445
}
446446

447-
func (h *NoPrivacyWithdrawFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.SelectedNonce) (*solana.Transaction, error) {
447+
func (h *NoPrivacyWithdrawFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.Nonce) (*solana.Transaction, error) {
448448
virtualSignatureBytes, err := base58.Decode(*fulfillmentRecord.VirtualSignature)
449449
if err != nil {
450450
return nil, err
@@ -634,7 +634,7 @@ func (h *CloseEmptyTimelockAccountFulfillmentHandler) SupportsOnDemandTransactio
634634
return true
635635
}
636636

637-
func (h *CloseEmptyTimelockAccountFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.SelectedNonce) (*solana.Transaction, error) {
637+
func (h *CloseEmptyTimelockAccountFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.Nonce) (*solana.Transaction, error) {
638638
if fulfillmentRecord.FulfillmentType != fulfillment.CloseEmptyTimelockAccount {
639639
return nil, errors.New("invalid fulfillment type")
640640
}

pkg/code/async/sequencer/service.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"github.com/code-payments/code-server/pkg/code/data/action"
1515
"github.com/code-payments/code-server/pkg/code/data/fulfillment"
1616
"github.com/code-payments/code-server/pkg/code/data/intent"
17+
"github.com/code-payments/code-server/pkg/code/data/nonce"
18+
"github.com/code-payments/code-server/pkg/code/transaction"
1719
)
1820

1921
var (
@@ -28,22 +30,35 @@ type service struct {
2830
data code_data.Provider
2931
scheduler Scheduler
3032
vmIndexerClient indexerpb.IndexerClient
33+
noncePool *transaction.LocalNoncePool
3134
fulfillmentHandlersByType map[fulfillment.Type]FulfillmentHandler
3235
actionHandlersByType map[action.Type]ActionHandler
3336
intentHandlersByType map[intent.Type]IntentHandler
3437
}
3538

36-
func New(data code_data.Provider, scheduler Scheduler, vmIndexerClient indexerpb.IndexerClient, configProvider ConfigProvider) async.Service {
39+
func New(data code_data.Provider, scheduler Scheduler, vmIndexerClient indexerpb.IndexerClient, noncePool *transaction.LocalNoncePool, configProvider ConfigProvider) (async.Service, error) {
40+
noncePoolEnv, noncePoolEnvInstance, noncePoolType := noncePool.GetConfiguration()
41+
if noncePoolEnv != nonce.EnvironmentSolana {
42+
return nil, errors.Errorf("nonce pool environment must be %s", nonce.EnvironmentSolana)
43+
}
44+
if noncePoolEnvInstance != nonce.EnvironmentInstanceSolanaMainnet {
45+
return nil, errors.Errorf("nonce pool environment instance must be %s", nonce.EnvironmentInstanceSolanaMainnet)
46+
}
47+
if noncePoolType != nonce.PurposeOnDemandTransaction {
48+
return nil, errors.Errorf("nonce pool type must be %s", nonce.PurposeOnDemandTransaction)
49+
}
50+
3751
return &service{
3852
log: logrus.StandardLogger().WithField("service", "sequencer"),
3953
conf: configProvider(),
4054
data: data,
4155
scheduler: scheduler,
4256
vmIndexerClient: vmIndexerClient,
57+
noncePool: noncePool, // todo: validate configuration
4358
fulfillmentHandlersByType: getFulfillmentHandlers(data, vmIndexerClient),
4459
actionHandlersByType: getActionHandlers(data),
4560
intentHandlersByType: getIntentHandlers(data),
46-
}
61+
}, nil
4762
}
4863

4964
func (p *service) Start(ctx context.Context, interval time.Duration) error {

pkg/code/async/sequencer/testutil.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import (
44
"context"
55
"errors"
66

7-
"github.com/code-payments/code-server/pkg/solana"
8-
"github.com/code-payments/code-server/pkg/solana/memo"
97
"github.com/code-payments/code-server/pkg/code/common"
108
"github.com/code-payments/code-server/pkg/code/data/fulfillment"
119
"github.com/code-payments/code-server/pkg/code/data/transaction"
1210
transaction_util "github.com/code-payments/code-server/pkg/code/transaction"
11+
"github.com/code-payments/code-server/pkg/solana"
12+
"github.com/code-payments/code-server/pkg/solana/memo"
1313
)
1414

1515
type mockScheduler struct {
@@ -42,7 +42,7 @@ func (h *mockFulfillmentHandler) SupportsOnDemandTransactions() bool {
4242
return h.supportsOnDemandTxnCreation
4343
}
4444

45-
func (h *mockFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.SelectedNonce) (*solana.Transaction, error) {
45+
func (h *mockFulfillmentHandler) MakeOnDemandTransaction(ctx context.Context, fulfillmentRecord *fulfillment.Record, selectedNonce *transaction_util.Nonce) (*solana.Transaction, error) {
4646
if !h.supportsOnDemandTxnCreation {
4747
return nil, errors.New("not supported")
4848
}

pkg/code/async/sequencer/worker.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ import (
1212

1313
"github.com/code-payments/code-server/pkg/code/common"
1414
"github.com/code-payments/code-server/pkg/code/data/fulfillment"
15-
"github.com/code-payments/code-server/pkg/code/data/nonce"
1615
"github.com/code-payments/code-server/pkg/code/data/transaction"
17-
transaction_util "github.com/code-payments/code-server/pkg/code/transaction"
1816
"github.com/code-payments/code-server/pkg/database/query"
1917
"github.com/code-payments/code-server/pkg/metrics"
2018
"github.com/code-payments/code-server/pkg/pointer"
@@ -225,13 +223,12 @@ func (p *service) handlePending(ctx context.Context, record *fulfillment.Record)
225223
return errors.New("unexpected scheduled fulfillment without transaction data")
226224
}
227225

228-
selectedNonce, err := transaction_util.SelectAvailableNonce(ctx, p.data, nonce.EnvironmentSolana, nonce.EnvironmentInstanceSolanaMainnet, nonce.PurposeOnDemandTransaction)
226+
selectedNonce, err := p.noncePool.GetNonce(ctx)
229227
if err != nil {
230228
return err
231229
}
232230
defer func() {
233231
selectedNonce.ReleaseIfNotReserved()
234-
selectedNonce.Unlock()
235232
}()
236233

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

pkg/code/async/sequencer/worker_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ func TestFulfillmentWorker_StatePending_OnDemandTransactionCreation_HappyPath(t
105105
env.fulfillmentHandler.supportsOnDemandTxnCreation = true
106106

107107
nonceRecord := env.generateAvailableNonce(t)
108+
time.Sleep(time.Second) // todo: Better way of waiting for nonce to be claimed
108109

109110
fulfillmentRecord := env.createAnyFulfillmentInState(t, fulfillment.StatePending)
110111
fulfillmentRecord.Signature = nil
@@ -226,12 +227,23 @@ func setupWorkerEnv(t *testing.T) *workerTestEnv {
226227
db := code_data.NewTestDataProvider()
227228

228229
scheduler := &mockScheduler{}
230+
noncePool, err := transaction_util.NewLocalNoncePool(
231+
db,
232+
nil,
233+
nonce.EnvironmentSolana,
234+
nonce.EnvironmentInstanceSolanaMainnet,
235+
nonce.PurposeOnDemandTransaction,
236+
transaction_util.WithNoncePoolRefreshPoolInterval(time.Second),
237+
)
238+
require.NoError(t, err)
229239
fulfillmentHandler := &mockFulfillmentHandler{}
230240
actionHandler := &mockActionHandler{}
231241
intentHandler := &mockIntentHandler{}
232242

233243
// todo: setup a test vm indexer
234-
worker := New(db, scheduler, nil, withManualTestOverrides(&testOverrides{})).(*service)
244+
workerInterface, err := New(db, scheduler, nil, noncePool, withManualTestOverrides(&testOverrides{}))
245+
require.NoError(t, err)
246+
worker := workerInterface.(*service)
235247
for key := range worker.fulfillmentHandlersByType {
236248
worker.fulfillmentHandlersByType[key] = fulfillmentHandler
237249
}

0 commit comments

Comments
 (0)