@@ -8,6 +8,7 @@ package v1_test
88
99import (
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