github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/sdf/sdf.go (about) 1 /* 2 Copyright (C) BABEC. All rights reserved. 3 Copyright (C) THL A29 Limited, a Tencent company. All rights reserved. 4 5 SPDX-License-Identifier: Apache-2.0 6 */ 7 8 package sdf 9 10 import ( 11 "fmt" 12 "log" 13 "os" 14 "strconv" 15 "time" 16 17 "chainmaker.org/chainmaker/common/v2/crypto/sdf/base" 18 "github.com/pkg/errors" 19 ) 20 21 const ( 22 defaultSessionSize = 10 23 ) 24 25 type SDFHandle struct { 26 ctx *base.Ctx 27 deviceHandle base.SessionHandle 28 sessions chan base.SessionHandle 29 sessionCacheSize int 30 } 31 32 // New returns a HSM SDFHandle to provide go-sdf functionalities. 33 func New(lib string, sessionCacheSize int) (*SDFHandle, error) { 34 ctx := base.New(lib) 35 if ctx == nil { 36 libEnv := os.Getenv("HSM_LIB") 37 log.Printf("lib[%s] invalid, use HSM_LIB[%s] from env\n", lib, libEnv) 38 ctx = base.New(libEnv) 39 if ctx == nil { 40 return nil, fmt.Errorf("[SDF] error: fail to initialize [%s]", libEnv) 41 } 42 } 43 44 if sessionCacheSize <= 0 { 45 sessionSizeStr := os.Getenv("HSM_SESSION_CACHE_SIZE") 46 sessionSize, err := strconv.Atoi(sessionSizeStr) 47 if err == nil && sessionSize > 0 { 48 log.Printf("sessionCacheSize[%d] invalid, use HSM_SESSION_CACHE_SIZE[%s] from env\n", 49 sessionCacheSize, sessionSizeStr) 50 sessionCacheSize = sessionSize 51 } else { 52 log.Printf("sessionCacheSize[%d] and HSM_SESSION_CACHE_SIZE[%s] invalid, use default size[%d]\n", 53 sessionCacheSize, sessionSizeStr, defaultSessionSize) 54 sessionCacheSize = defaultSessionSize 55 } 56 } 57 58 var err error 59 var deviceHandle base.SessionHandle 60 for i := 0; i < 3; i++ { 61 deviceHandle, err = ctx.SDFOpenDevice() 62 if err != nil { 63 continue 64 } 65 break 66 } 67 if err != nil { 68 return nil, fmt.Errorf("[SDF] error: fail to open device after 3 times [%v]", err) 69 } 70 71 sessions := make(chan base.SessionHandle, sessionCacheSize) 72 handle := &SDFHandle{ 73 ctx: ctx, 74 deviceHandle: deviceHandle, 75 sessions: sessions, 76 sessionCacheSize: sessionCacheSize, 77 } 78 return handle, nil 79 } 80 81 func (h *SDFHandle) getSession() (base.SessionHandle, error) { 82 var session base.SessionHandle 83 select { 84 case session = <-h.sessions: 85 return session, nil 86 default: 87 var err error 88 for i := 0; i < 3; i++ { 89 session, err = h.ctx.SDFOpenSession(h.deviceHandle) 90 if err == nil { 91 return session, nil 92 } 93 time.Sleep(time.Millisecond * 100) 94 } 95 return nil, errors.WithMessage(err, "failed to create new session after 3 times attempt") 96 } 97 } 98 99 func (h *SDFHandle) returnSession(err error, session base.SessionHandle) { 100 if err != nil { 101 _ = h.ctx.SDFCloseSession(session) 102 } 103 select { 104 case h.sessions <- session: 105 return 106 default: 107 _ = h.ctx.SDFCloseSession(session) 108 return 109 } 110 } 111 112 func (h *SDFHandle) Close() error { 113 //close channel to avoid creating new session 114 close(h.sessions) 115 116 //close all sessions 117 for session := range h.sessions { 118 err := h.ctx.SDFCloseSession(session) 119 if err != nil { 120 return err 121 } 122 } 123 124 //close device 125 return h.ctx.SDFCloseDevice(h.deviceHandle) 126 }