Skip to content

Commit e78eb89

Browse files
Add benchmarks for fabtoken
- Added Issue and Transfer service benchmarks - Added Validator benchmarks - Fixed nlreturn linting issues in benchmark files Signed-off-by: Shashank <yshashank959@gmail.com>
1 parent a75e3ad commit e78eb89

3 files changed

Lines changed: 444 additions & 0 deletions

File tree

token/core/fabtoken/v1/issue_test.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/hyperledger-labs/fabric-token-sdk/token/driver"
1414
"github.com/hyperledger-labs/fabric-token-sdk/token/driver/mock"
15+
benchmark2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/benchmark"
1516
"github.com/hyperledger-labs/fabric-token-sdk/token/token"
1617
"github.com/stretchr/testify/assert"
1718
"github.com/stretchr/testify/require"
@@ -187,3 +188,117 @@ func TestDeserializeIssueAction(t *testing.T) {
187188
require.Error(t, err)
188189
})
189190
}
191+
192+
// BenchmarkIssueServiceIssue benchmarks the Issue method of the IssueService.
193+
func BenchmarkIssueServiceIssue(b *testing.B) {
194+
_, _, cases, err := benchmark2.GenerateCasesWithDefaults()
195+
require.NoError(b, err)
196+
197+
for _, tc := range cases {
198+
b.Run(tc.Name, func(b *testing.B) {
199+
env, err := newBenchmarkIssueEnv(b.N, tc.BenchmarkCase)
200+
require.NoError(b, err)
201+
202+
b.ResetTimer()
203+
i := 0
204+
for b.Loop() {
205+
e := env.Envs[i%len(env.Envs)]
206+
action, _, err := e.is.Issue(
207+
b.Context(),
208+
e.issuer,
209+
e.tokenType,
210+
e.values,
211+
e.owners,
212+
nil,
213+
)
214+
require.NoError(b, err)
215+
require.NotNil(b, action)
216+
i++
217+
}
218+
})
219+
}
220+
}
221+
222+
// TestParallelBenchmarkIssueServiceIssue runs the issue benchmark in parallel.
223+
func TestParallelBenchmarkIssueServiceIssue(t *testing.T) {
224+
_, _, cases, err := benchmark2.GenerateCasesWithDefaults()
225+
require.NoError(t, err)
226+
227+
test := benchmark2.NewTest[*benchmarkIssueEnv](cases)
228+
test.RunBenchmark(t,
229+
func(c *benchmark2.Case) (*benchmarkIssueEnv, error) {
230+
return newBenchmarkIssueEnv(1, c)
231+
},
232+
func(ctx context.Context, env *benchmarkIssueEnv) error {
233+
action, _, err := env.Envs[0].is.Issue(
234+
ctx,
235+
env.Envs[0].issuer,
236+
env.Envs[0].tokenType,
237+
env.Envs[0].values,
238+
env.Envs[0].owners,
239+
nil,
240+
)
241+
if err != nil {
242+
return err
243+
}
244+
_, err = action.Serialize()
245+
246+
return err
247+
},
248+
)
249+
}
250+
251+
type issueEnv struct {
252+
is *IssueService
253+
issuer driver.Identity
254+
tokenType token.Type
255+
values []uint64
256+
owners [][]byte
257+
}
258+
259+
func newIssueEnv(benchmarkCase *benchmark2.Case) (*issueEnv, error) {
260+
ppm := &mock.PublicParamsManager{}
261+
pp := &mock.PublicParameters{}
262+
pp.PrecisionReturns(64)
263+
ppm.PublicParametersReturns(pp)
264+
265+
ws := &mock.WalletService{}
266+
des := &mock.Deserializer{}
267+
is := NewIssueService(ppm, ws, des)
268+
269+
issuer := driver.Identity("issuer")
270+
tokenType := token.Type("ABC")
271+
values := make([]uint64, benchmarkCase.NumOutputs)
272+
owners := make([][]byte, benchmarkCase.NumOutputs)
273+
for i := range values {
274+
values[i] = uint64(i)*10 + 10
275+
owners[i] = []byte("owner")
276+
}
277+
278+
des.GetAuditInfoReturns([]byte("audit"), nil)
279+
280+
return &issueEnv{
281+
is: is,
282+
issuer: issuer,
283+
tokenType: tokenType,
284+
values: values,
285+
owners: owners,
286+
}, nil
287+
}
288+
289+
type benchmarkIssueEnv struct {
290+
Envs []*issueEnv
291+
}
292+
293+
func newBenchmarkIssueEnv(n int, benchmarkCase *benchmark2.Case) (*benchmarkIssueEnv, error) {
294+
envs := make([]*issueEnv, n)
295+
for i := range n {
296+
env, err := newIssueEnv(benchmarkCase)
297+
if err != nil {
298+
return nil, err
299+
}
300+
envs[i] = env
301+
}
302+
303+
return &benchmarkIssueEnv{Envs: envs}, nil
304+
}

token/core/fabtoken/v1/transfer_test.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package v1_test
88

99
import (
1010
"context"
11+
"strconv"
1112
"testing"
1213

1314
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
@@ -16,6 +17,7 @@ import (
1617
"github.com/hyperledger-labs/fabric-token-sdk/token/core/fabtoken/v1/setup"
1718
"github.com/hyperledger-labs/fabric-token-sdk/token/driver"
1819
"github.com/hyperledger-labs/fabric-token-sdk/token/driver/mock"
20+
benchmark2 "github.com/hyperledger-labs/fabric-token-sdk/token/services/benchmark"
1921
"github.com/hyperledger-labs/fabric-token-sdk/token/services/logging"
2022
"github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx"
2123
"github.com/hyperledger-labs/fabric-token-sdk/token/token"
@@ -309,3 +311,132 @@ func TestTransferService(t *testing.T) {
309311
require.Error(t, err)
310312
})
311313
}
314+
315+
// BenchmarkTransferServiceTransfer benchmarks the Transfer method of the TransferService.
316+
func BenchmarkTransferServiceTransfer(b *testing.B) {
317+
_, _, cases, err := benchmark2.GenerateCasesWithDefaults()
318+
require.NoError(b, err)
319+
320+
for _, tc := range cases {
321+
b.Run(tc.Name, func(b *testing.B) {
322+
env, err := newBenchmarkTransferEnv(b.N, tc.BenchmarkCase)
323+
require.NoError(b, err)
324+
325+
b.ResetTimer()
326+
i := 0
327+
for b.Loop() {
328+
e := env.Envs[i%len(env.Envs)]
329+
action, _, err := e.ts.Transfer(
330+
b.Context(),
331+
"an_anchor",
332+
nil,
333+
e.ids,
334+
e.outputs,
335+
nil,
336+
)
337+
require.NoError(b, err)
338+
require.NotNil(b, action)
339+
i++
340+
}
341+
})
342+
}
343+
}
344+
345+
// TestParallelBenchmarkTransferServiceTransfer runs the transfer benchmark in parallel.
346+
func TestParallelBenchmarkTransferServiceTransfer(t *testing.T) {
347+
_, _, cases, err := benchmark2.GenerateCasesWithDefaults()
348+
require.NoError(t, err)
349+
350+
test := benchmark2.NewTest[*benchmarkTransferEnv](cases)
351+
test.RunBenchmark(t,
352+
func(c *benchmark2.Case) (*benchmarkTransferEnv, error) {
353+
return newBenchmarkTransferEnv(1, c)
354+
},
355+
func(ctx context.Context, env *benchmarkTransferEnv) error {
356+
action, _, err := env.Envs[0].ts.Transfer(
357+
ctx,
358+
"an_anchor",
359+
nil,
360+
env.Envs[0].ids,
361+
env.Envs[0].outputs,
362+
nil,
363+
)
364+
if err != nil {
365+
return err
366+
}
367+
_, err = action.Serialize()
368+
369+
return err
370+
},
371+
)
372+
}
373+
374+
type transferEnv struct {
375+
ts *v1.TransferService
376+
outputs []*token.Token
377+
ids []*token.ID
378+
}
379+
380+
func newTransferEnv(benchmarkCase *benchmark2.Case) (*transferEnv, error) {
381+
logger := logging.MustGetLogger("test")
382+
ppm := &mockPublicParamsManager{PublicParamsManager: &mock.PublicParamsManager{}}
383+
pp, err := setup.Setup(64)
384+
if err != nil {
385+
return nil, err
386+
}
387+
ppm.PublicParametersReturns(pp)
388+
389+
ws := &mock.WalletService{}
390+
tl := &MockTokenLoader{}
391+
des := &mock.Deserializer{}
392+
ts := v1.NewTransferService(logger, ppm, ws, tl, des)
393+
394+
outputs := make([]*token.Token, benchmarkCase.NumOutputs)
395+
for i := range outputs {
396+
outputs[i] = &token.Token{
397+
Owner: []byte("owner2"),
398+
Type: "ABC",
399+
Quantity: token.NewQuantityFromUInt64(uint64(i)*10 + 10).Hex(),
400+
}
401+
}
402+
403+
ids := make([]*token.ID, benchmarkCase.NumInputs)
404+
inputTokens := make([]*token.Token, benchmarkCase.NumInputs)
405+
for i := range ids {
406+
ids[i] = &token.ID{TxId: strconv.Itoa(i), Index: 0}
407+
inputTokens[i] = &token.Token{
408+
Owner: []byte("owner1"),
409+
Type: "ABC",
410+
Quantity: token.NewQuantityFromUInt64(uint64(i)*10 + 10).Hex(),
411+
}
412+
}
413+
414+
tl.GetTokensStub = func(ctx context.Context, ids []*token.ID) ([]*token.Token, error) {
415+
return inputTokens, nil
416+
}
417+
des.GetAuditInfoReturns([]byte("audit"), nil)
418+
des.RecipientsReturns([]driver.Identity{[]byte("owner2")}, nil)
419+
420+
return &transferEnv{
421+
ts: ts,
422+
outputs: outputs,
423+
ids: ids,
424+
}, nil
425+
}
426+
427+
type benchmarkTransferEnv struct {
428+
Envs []*transferEnv
429+
}
430+
431+
func newBenchmarkTransferEnv(n int, benchmarkCase *benchmark2.Case) (*benchmarkTransferEnv, error) {
432+
envs := make([]*transferEnv, n)
433+
for i := range n {
434+
env, err := newTransferEnv(benchmarkCase)
435+
if err != nil {
436+
return nil, err
437+
}
438+
envs[i] = env
439+
}
440+
441+
return &benchmarkTransferEnv{Envs: envs}, nil
442+
}

0 commit comments

Comments
 (0)